Skip to content

Add log_audio, TBAudio, tests, examples #27

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 46 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1a5e250
Merge pull request #1 from PhilipVinc/master
Mar 26, 2019
d3f50c6
Merge pull request #2 from PhilipVinc/master
Apr 17, 2019
d5fefa1
Merge pull request #5 from PhilipVinc/master
May 8, 2019
f9992b6
add matrix and list support to log_text
May 14, 2019
cf7c911
reverting test_TBLogger.jl
May 14, 2019
9ef5ff4
Merge pull request #7 from PhilipVinc/master
May 15, 2019
c3c8a6f
add support for 1-D images in `log_image`
May 15, 2019
8e276e1
add ImageFormat explanation
May 15, 2019
0e6f2b3
add seperate function for image objects
May 16, 2019
b53a4a9
add more formats
May 16, 2019
447c484
add preprocess function for image objects for automatic dispatch
May 16, 2019
8282a13
add TBImage, TBImages wrapper
May 16, 2019
c24dd63
add tests. more required. more will come
May 16, 2019
2884423
Merge pull request #8 from shashikdm/updateimage
May 16, 2019
c3773cc
minor bug fix
May 16, 2019
92c7d08
Merge pull request #9 from shashikdm/updateimage
May 16, 2019
8b6170d
refactoring
May 16, 2019
a3c90a5
add support for 3-d images such as mri
May 16, 2019
598aec6
bug fixes
May 17, 2019
dffb97f
add more tests
May 17, 2019
e048ddb
minor bug fix
May 17, 2019
544415b
add examples folder
May 17, 2019
71d79ee
Merge pull request #10 from shashikdm/examples
May 17, 2019
15a6250
syntax revision
May 17, 2019
92a1c10
Merge branch 'master' of github.com:shashikdm/TensorBoardLogger.jl
May 17, 2019
e4af898
change if else to function dispatch `image_summary`
May 18, 2019
7a4bef4
major revision `log_image` smart use of ImageFormats
May 18, 2019
ab7dda3
change throw message
May 18, 2019
8243d18
change dict to ternary. minor revision
May 18, 2019
773ff7a
add LogAudio.jl with dep WAV.jl
May 19, 2019
4c14f46
add test for `log_audio`
May 20, 2019
9f17ec2
add `TBAudios` and `TBAudio` and test
May 20, 2019
821b804
bugfix `log_text`
May 20, 2019
0e80fa5
add examples `Audios.jl` and `Texts.jl`
May 20, 2019
103d1dc
Merge branch 'master' into master
PhilipVinc May 20, 2019
13180d1
Merge pull request #12 from shashikdm/master
May 21, 2019
60eb6f5
change SummaryCollection construction `log_audio`
May 21, 2019
ea81489
Merge pull request #11 from shashikdm/logaudio
May 21, 2019
ba3c284
Merge branch 'master' into master
May 21, 2019
d6d3285
update
May 21, 2019
b4a92dd
Merge branch 'master' of github.com:shashikdm/TensorBoardLogger.jl
May 21, 2019
5e315b9
change docstring
May 21, 2019
3c0993f
rm test data
May 21, 2019
700be47
chane SummaryCollection
May 21, 2019
f86a646
Merge branch 'master' into master
May 22, 2019
16d20e3
rm WAV dependency
May 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"
WAV = "8149f6b0-98f6-5db9-b78f-408fbbb8ef88"

[targets]
test = ["Test", "Flux", "TestImages", "ImageMagick"]
test = ["Test", "Flux", "TestImages", "ImageMagick", "WAV"]
27 changes: 27 additions & 0 deletions examples/Audios.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using TensorBoardLogger #import the TensorBoardLogger package
using Logging #import Logging package

logger = TBLogger("audiologs", tb_append) #create tensorboard logger

################log audio example: cos wave ################
samplerate = 44100
x = collect(1:samplerate*2)
x = cos.(440*pi*x/samplerate)
#using logger interface
with_logger(logger) do
@info "cos/loggerinterface" x = TBAudio(x, samplerate)
end
#using explicit function interface
log_audio(logger, "cos/explicitinterface", x, samplerate, step = 0)


################log scalar example: sin+cos wave################
y = collect(1:samplerate*2)
y = sin.(440*pi*y/samplerate)
z = x+y
#using logger interface
with_logger(logger) do
@info "sin+cos/loggerinterface" z = TBAudio(z, samplerate)
end
#using explicit function interface
log_audio(logger, "sin+cos/explicitinterface", z, samplerate, step = 0)
29 changes: 29 additions & 0 deletions examples/Texts.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using TensorBoardLogger #import the TensorBoardLogger package
using Logging #import Logging package

logger = TBLogger("textlogs", tb_append) #create tensorboard logger

################log scalars example: String################
#using logger interface
with_logger(logger) do
@info "string/loggerinterface" str = "A computer once beat me at chess, but it was no match for me at kick boxing. *— Emo Philips*"
end
#using explicit function interface
str =
"
All parts should go together without forcing.
You must remember that the parts you are reassembling were disassembled by you.
Therefore, if you can’t get them together again, there must be a reason.
By all means, do not use a hammer.”
*— IBM Manual, 1925*
"
log_text(logger, "string/explicitinterface", str, step = 0)


################log scalar example: y = matrix################
squares =
[["Number" "Square"];
[1 1]; [2 4]; [3 9]; [4 16]; [5 25]; [6 36]; [7 49]; [8 64]; [9 81]; [10 100]]

#using explicit function interface
log_text(logger, "table", squares, step = 0)
35 changes: 35 additions & 0 deletions src/Loggers/LogAudio.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
log_audios(logger::TBLogger, name::AbstractString, samples::AbstractArray, samplerate::Real, step)

Logs multiple audio clips at step `step`
- samples:
Array of audio clips which are Arrays of samples N*C where N = number of samples and C = number of channel
- samplerate: Sampling rate or Sampling frequency: a Real value same for all clips
"""
function log_audios(logger::TBLogger, name::AbstractString, samplesArray::AbstractArray, samplerate::Real; step=nothing)
for (n, sample) in enumerate(samplesArray)
log_audio(logger, name*"/$n", sample, samplerate, step = step)
end
end
"""
log_audio(logger::TBLogger, name::AbstractString, samples::AbstractArray, samplerate::Real, step)

Logs an audio clip with name `name` at step `step`
- samples: Array of samples N*C where N = number of samples and C = number of channels
- samplerate: Sampling rate or Sampling frequency: a Real value
"""
function log_audio(logger::TBLogger, name::AbstractString, samples::AbstractArray, samplerate::Real; step=nothing)
summ = SummaryCollection(audio_summary(name, samples, samplerate))
write_event(logger.file, make_event(logger, summ, step=step))
end

function audio_summary(name::AbstractString, samples::AbstractArray, samplerate::Real)
@assert ndims(samples) <= 2
samples = samples./max(maximum(samples), 1)
samples = Int16.(floor.(samples.*32767))
io = IOBuffer()
save(Stream(format"WAV", io), samples)
eas = io.data
audio = Summary_Audio(sample_rate = samplerate, num_channels = ndims(samples), length_frames = size(samples, 1), encoded_audio_string = eas, content_type = "audio/wav")
Summary_Value(tag=name, audio=audio)
end
3 changes: 1 addition & 2 deletions src/Loggers/LogImage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ function log_image(logger::TBLogger, name::AbstractString, imgArray::AbstractArr
@assert dims == expected_ndims(format)
obsdim = obs_dim(format)
if iszero(obsdim)
summ = SummaryCollection()
push!(summ.value, image_summary(name, imgArray, format))
summ = SummaryCollection(image_summary(name, imgArray, format))
write_event(logger.file, make_event(logger, summ, step=step))
else
format = strip_obs[format]
Expand Down
3 changes: 3 additions & 0 deletions src/Loggers/LogText.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ function text_summary(name::String, text::Any)
#content of the tensor
textstringval = Vector{Array{UInt8, 1}}()
if isa(text, AbstractArray)
if ndims(text) == 2
text = permutedims(text, (2, 1))
end
for string in text
string = markdown_repr(string)
push!(textstringval, Array{UInt8, 1}(string))
Expand Down
5 changes: 3 additions & 2 deletions src/TensorBoardLogger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import Base.CoreLogging:
AbstractLogger, handle_message, shouldlog, min_enabled_level,
catch_exceptions

export log_histogram, log_value, log_vector, log_text, log_image, log_images
export log_histogram, log_value, log_vector, log_text, log_image, log_images, log_audio, log_audios
export scalar_summary, histogram_summary, text_summary, make_event
export TBLogger
export reset!, set_step!, increment_step!
export ImageFormat, L, CL, LC, LN, NL, NCL, NLC, CLN, LCN, HW, WH, HWC, WHC, CHW, CWH,HWN, WHN, NHW, NWH, HWCN, WHCN, CHWN, CWHN, NHWC, NWHC, NCHW, NCWH
# Wrapper types
export TBText, TBVector, TBHistogram, TBImage, TBImages
export TBText, TBVector, TBHistogram, TBImage, TBImages, TBAudio, TBAudios

# Protobuffer definitions for tensorboard
include("protojl/tensorflow.jl")
Expand All @@ -42,6 +42,7 @@ include("Loggers/LogValue.jl")
include("Loggers/LogText.jl")
include("Loggers/LogHistograms.jl")
include("Loggers/LogImage.jl")
include("Loggers/LogAudio.jl")

include("logger_dispatch.jl")
include("logger_dispatch_overrides.jl")
Expand Down
41 changes: 38 additions & 3 deletions src/logger_dispatch_overrides.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,41 @@ preprocess(name, val::WrapperLogType, data) = push!(data, name=>val)
Base.show(io::IO, mime::AbstractString, x::WrapperLogType) =
Base.show(io, mime, content(x))

########## For things going to LogAudio ##############################
"""
TBAudios(data, samplerate)

Forces elements of Array `data` to be serialized as Audio to TensorBoard.
"""
struct TBAudios <:WrapperLogType
data::AbstractArray
samplerate::Real
end
content(x::TBAudios) = x.data
function preprocess(name, val::TBAudios, data)
for (n, audio) in enumerate(val.data)
preprocess(name*"/$n", TBAudio(audio, val.samplerate), data)
end
end

"""
TBAudio(data, samplerate)

Forces `data` to be serialized as Audio to TensorBoard.
"""
struct TBAudio <: WrapperLogType
data::AbstractArray
samplerate::Real
end
content(x::TBAudio) = x.data
preprocess(name, val::TBAudio, data) = push!(data, name=>val)
summary_impl(name, val::TBAudio) = audio_summary(name, val.data, val.samplerate)

########## For things going to LogImage ########################
"""
TBImage(data, format)
TBImages(data, format)

Forces `data` to be serialized as an Image to TensorBoard.
Forces elements of Array `data` to be serialized as an Image to TensorBoard.
"""
struct TBImages <:WrapperLogType
data::AbstractArray
Expand All @@ -41,6 +71,11 @@ function preprocess(name, val::TBImages, data)
end
end

"""
TBImage(data, format)

Forces `data` to be serialized as an Image to TensorBoard.
"""
struct TBImage <: WrapperLogType
data::AbstractArray
format::ImageFormat
Expand All @@ -54,7 +89,7 @@ function preprocess(name, val::TBImage, data)
@assert dims == expected_ndims(format)
obsdim = obs_dim(format)
if iszero(obsdim)
push!(data, name=>TBImage(imgArray, format))
push!(data, name=>val)
else
format = strip_obs[format]
index = collect("[:"* ",:"^(dims-1) *"]")
Expand Down
16 changes: 16 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using Flux.Data.MNIST
using TestImages
using ImageCore
using ColorTypes
using FileIO


@testset "TBLogger" begin
Expand Down Expand Up @@ -201,6 +202,21 @@ end
@test TensorBoardLogger.step(logger) == 200
end

@testset "Audio Logger" begin
logger = TBLogger("test_logs/t", tb_overwrite)
step = 1

ss = TensorBoardLogger.audio_summary("test", rand(800), 800)
@test isa(ss, TensorBoardLogger.Summary_Value)
@test ss.tag == "test"

clip = (cos.(440*pi*collect(1:100)/44100), 44100)
fs = clip[2]
sample = clip[1]
samples = [sample, sample, sample]
log_audios(logger, "audiosample", samples, fs, step = step)
end

@testset "Logger dispatch overrides" begin
include("test_logger_dispatch_overrides.jl")
end
13 changes: 12 additions & 1 deletion test/test_logger_dispatch_overrides.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,19 @@ end
(rand(5, 4, 3, 2), WHCN), (rand(4, 5, 3, 2), HWCN), (rand(2, 3, 4, 5), NCHW), (rand(2, 3, 5, 4), NCWH),
(rand(3, 5, 4, 2), CWHN), (rand(3, 4, 5, 2), CHWN), (rand(2, 4, 5, 3), NHWC), (rand(2, 5, 4, 3), NWHC),
]
preprocess("randTBImages", TBImages([rand(3, 3), rand(3,3)], HW), data)
for testtuple in testdata
preprocess("randTBImage/$(last(testtuple))", TBImage(first(testtuple), last(testtuple)), data)
end
@test size(data, 1) == 45
@test size(data, 1) == 47
end

@testset "TBAudio" begin
data = Vector{Pair{String,Any}}()
sample_rate = 44100
x = collect(1:sample_rate*2)
y = cos.(440*pi*x/sample_rate)
preprocess("test", TBAudios([y, y], sample_rate), data)
@test first(data) == ("test/1"=>TBAudio(y, sample_rate))
@test last(data) == ("test/2"=>TBAudio(y, sample_rate))
end