Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add Time Series Block #239

Merged
merged 22 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion FastTimeSeries/src/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Construct a model for time-series classification.
function blockmodel(inblock::TimeSeriesRow,
outblock::OneHotTensor{0},
backbone)
data = [rand(Float32, inblock.nfeatures, 256) for _ ∈ 1:inblock.obslength]
data = [rand(Float32, inblock.nfeatures, 32) for _ ∈ 1:inblock.obslength]
output = backbone(data)
outs = size(output)[1]
return Models.RNNModel(backbone, outsize = length(outblock.classes), recout = outs)
Expand Down
10 changes: 8 additions & 2 deletions FastTimeSeries/src/models/RNN.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
function tabular2rnn(X::AbstractArray{Float32, 3})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "tabular" is a bit of a misnomer here, but naming is not a priority.

X = permutedims(X, (2, 1, 3))
X = [X[t, :, :] for t ∈ 1:size(X, 1)]
codeboy5 marked this conversation as resolved.
Show resolved Hide resolved
return X
end

"""
RNNModel(recbackbonem, outsize, recout[; kwargs...])

Expand All @@ -24,5 +30,5 @@ function RNNModel(recbackbone,
dropout_rate = 0.0)

dropout = dropout_rate == 0 ? identity : Dropout(dropout_rate)
Chain(recbackbone, dropout, finalclassifier)
end
Chain(tabular2rnn, recbackbone, dropout, finalclassifier)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should be doing this dense to slices transform in the model itself. If you just need something RNN friendly, relying on the built-in support for dense inputs should be enough. The permutedims can stay for now, but even that probably shouldn't be in the gradient hot path (it allocates O(n) both ways).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative for now is to make the data pipeline spit out the vector of arrays. We can then revisit if/when you add models like CNNs which expect dense inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the "ideal" place to do this transform would be inside the training loop. I am not sure how to exactly do that for FastAI.jl. Is there a way ?

Since the second phase would involve using some CNNs, using data pipeline to spit out vector of arrays would not work.

end
5 changes: 3 additions & 2 deletions FastTimeSeries/src/models/StackedLSTM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Layers for stacked LSTM (referenced from https://github.com/sdobber/FluxArchitectures.jl)

mutable struct StackedLSTMCell{A}
struct StackedLSTMCell{A}
chain::A
end

Expand Down Expand Up @@ -34,12 +34,13 @@ function StackedLSTM(in::Int, out::Integer, hiddensize::Integer, layers::Integer
end

function (m::StackedLSTMCell)(X)
Flux.reset!(m)
[m.chain(x) for x ∈ X[1:end-1]]
return m.chain(X[end])
end

Flux.@functor StackedLSTMCell
Flux.trainable(m::StackedLSTMCell) = (m.chain)
# Flux.trainable(m::StackedLSTMCell) = (m.chain)

# Initialize forget gate bias with 1
function initialize_bias!(l::StackedLSTMCell)
Expand Down
3 changes: 1 addition & 2 deletions FastTimeSeries/src/tasks/classification.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ _tasks["tsclfsingle"] = (
row = FastAI.mockblock(task.blocks[1])

xtrain = FastAI.encodeinput(task, Training(), row);
@test length(xtrain[1,:]) == task.blocks.input.obslength
@test length(xtrain[:,1]) == task.blocks.input.nfeatures
@test size(xtrain) == (task.blocks.input.nfeatures, task.blocks.input.obslength)

@test eltype(xtrain[1,:]) <: Number
end
Expand Down