ruby-dnn 0.14.3 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/Rakefile +4 -2
- data/examples/api-examples/save_example.rb +7 -5
- data/examples/dcgan/imgen.rb +2 -7
- data/examples/dcgan/train.rb +0 -1
- data/lib/dnn.rb +10 -10
- data/lib/dnn/core/callbacks.rb +6 -2
- data/lib/dnn/core/iterator.rb +10 -2
- data/lib/dnn/core/{activations.rb → layers/activations.rb} +0 -0
- data/lib/dnn/core/{layers.rb → layers/basic_layers.rb} +31 -8
- data/lib/dnn/core/{cnn_layers.rb → layers/cnn_layers.rb} +0 -0
- data/lib/dnn/core/{embedding.rb → layers/embedding.rb} +5 -4
- data/lib/dnn/core/{merge_layers.rb → layers/merge_layers.rb} +1 -1
- data/lib/dnn/core/{normalizations.rb → layers/normalizations.rb} +9 -5
- data/lib/dnn/core/{rnn_layers.rb → layers/rnn_layers.rb} +25 -16
- data/lib/dnn/core/losses.rb +8 -0
- data/lib/dnn/core/models.rb +164 -68
- data/lib/dnn/core/optimizers.rb +49 -72
- data/lib/dnn/core/param.rb +0 -2
- data/lib/dnn/core/savers.rb +40 -49
- data/lib/dnn/datasets/stl-10.rb +65 -0
- data/lib/dnn/version.rb +1 -1
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6be46c1c89fbb1f1f2091c95f15ccab21473d52571ee47953a4c07446ea8544c
|
4
|
+
data.tar.gz: e01eb929c13b2a33a350ee42b8bb8584446722ac3ba3dc7e163f7f3429ec068a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc5bd6608d17a90cb97f6f5530877e5441a2dc73fc18e7b821c33d606469d6a15c22d519570b8c8821282915de84b677b3527221b1eb076a145a85997a58d2d9
|
7
|
+
data.tar.gz: 721c578f41a7648dfc5c462a1b9a81f6b9604b50540e8fa4a58bb801adc8059ee7cff9f27d3c1b1a710ce0857e426ca2087f4902bf46d9c621870e3ae7cb664a
|
data/README.md
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
[](https://badge.fury.io/rb/ruby-dnn)
|
3
3
|
[](https://travis-ci.org/unagiootoro/ruby-dnn)
|
4
4
|
|
5
|
-
ruby-dnn is a ruby deep learning library. This library supports full connected neural network and convolution neural network
|
6
|
-
|
5
|
+
ruby-dnn is a ruby deep learning library. This library supports full connected neural network and convolution neural network
|
6
|
+
and recurrent neural network.
|
7
|
+
Currently, you can get 99% accuracy with MNIST and 78% with CIFAR 10.
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
|
@@ -79,8 +80,9 @@ If you want to know more detailed information, please refer to the source code.
|
|
79
80
|
|| Implemented classes |
|
80
81
|
|:-----------|------------:|
|
81
82
|
| Connections | Dense, Conv2D, Conv2DTranspose, Embedding, SimpleRNN, LSTM, GRU |
|
82
|
-
| Layers | Flatten, Reshape, Dropout, BatchNormalization, MaxPool2D, AvgPool2D, UnPool2D |
|
83
83
|
| Activations | Sigmoid, Tanh, Softsign, Softplus, Swish, ReLU, LeakyReLU, ELU |
|
84
|
+
| Basic | Flatten, Reshape, Dropout, BatchNormalization |
|
85
|
+
| Pooling | MaxPool2D, AvgPool2D, GlobalAvgPool2D, UnPool2D |
|
84
86
|
| Optimizers | SGD, Nesterov, AdaGrad, RMSProp, AdaDelta, RMSPropGraves, Adam, AdaBound |
|
85
87
|
| Losses | MeanSquaredError, MeanAbsoluteError, Hinge, HuberLoss, SoftmaxCrossEntropy, SigmoidCrossEntropy |
|
86
88
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ Rake::TestTask.new(:test) do |t|
|
|
5
5
|
t.libs << "test"
|
6
6
|
t.libs << "ext"
|
7
7
|
t.libs << "lib"
|
8
|
-
t.test_files = FileList["test/*_test.rb"]
|
8
|
+
t.test_files = FileList["test/*_test.rb", "test/layers_test/*_test.rb"]
|
9
9
|
end
|
10
10
|
|
11
11
|
task :build_cifar_loader do
|
@@ -27,7 +27,9 @@ end
|
|
27
27
|
task :default => [:test, :build_cifar_loader, :build_rb_stb_image]
|
28
28
|
|
29
29
|
task :doc do
|
30
|
-
src_list = Dir["lib/dnn
|
30
|
+
src_list = Dir["lib/dnn.rb"]
|
31
|
+
src_list += Dir["lib/dnn/core/*.rb"]
|
32
|
+
src_list += Dir["lib/dnn/core/layers/*.rb"]
|
31
33
|
src_list += Dir["lib/dnn/*.rb"]
|
32
34
|
sh "yardoc #{src_list.join(' ')}"
|
33
35
|
end
|
@@ -20,9 +20,9 @@ BATCH_SIZE = 128
|
|
20
20
|
# Select save style from USE_MARSHAL or USE_JSON.
|
21
21
|
SAVE_STYLE = USE_MARSHAL
|
22
22
|
|
23
|
-
# When set a true, save data included
|
23
|
+
# When set a true, save data included model structure.
|
24
24
|
# This setting is enabled when SAVE_STYLE is USE_MARSHAL.
|
25
|
-
|
25
|
+
INCLUDE_MODEL = true
|
26
26
|
|
27
27
|
x_train, y_train = MNIST.load_train
|
28
28
|
x_test, y_test = MNIST.load_test
|
@@ -47,7 +47,7 @@ class MLP < Model
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def call(x)
|
50
|
-
x = InputLayer.(x)
|
50
|
+
x = InputLayer.new(784).(x)
|
51
51
|
x = @l1.(x)
|
52
52
|
x = @bn1.(x)
|
53
53
|
x = ReLU.(x)
|
@@ -64,7 +64,7 @@ model.setup(Adam.new, SoftmaxCrossEntropy.new)
|
|
64
64
|
model.train(x_train, y_train, EPOCHS, batch_size: BATCH_SIZE, test: [x_test, y_test])
|
65
65
|
|
66
66
|
if SAVE_STYLE == USE_MARSHAL
|
67
|
-
saver = MarshalSaver.new(model,
|
67
|
+
saver = MarshalSaver.new(model, include_model: INCLUDE_MODEL)
|
68
68
|
saver.save("trained_mnist.marshal")
|
69
69
|
# model.save("trained_mnist.marshal") # This code is equivalent to the code above.
|
70
70
|
elsif SAVE_STYLE == USE_JSON
|
@@ -73,6 +73,8 @@ elsif SAVE_STYLE == USE_JSON
|
|
73
73
|
end
|
74
74
|
|
75
75
|
model2 = MLP.new
|
76
|
+
model2.setup(Adam.new, SoftmaxCrossEntropy.new)
|
77
|
+
model2.predict1(Numo::SFloat.zeros(784))
|
76
78
|
if SAVE_STYLE == USE_MARSHAL
|
77
79
|
loader = MarshalLoader.new(model2)
|
78
80
|
loader.load("trained_mnist.marshal")
|
@@ -82,4 +84,4 @@ elsif SAVE_STYLE == USE_JSON
|
|
82
84
|
loader.load("trained_mnist.json")
|
83
85
|
end
|
84
86
|
|
85
|
-
puts model2.
|
87
|
+
puts model2.evaluate(x_test, y_test)
|
data/examples/dcgan/imgen.rb
CHANGED
@@ -8,13 +8,8 @@ Image = DNN::Image
|
|
8
8
|
|
9
9
|
batch_size = 100
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
dcgan = DCGAN.new(gen, dis)
|
14
|
-
dcgan.predict1(Numo::SFloat.zeros(20))
|
15
|
-
|
16
|
-
loader = MarshalLoader.new(dcgan)
|
17
|
-
loader.load("trained/dcgan_model_epoch20.marshal")
|
11
|
+
dcgan = DCGAN.load("trained/dcgan_model_epoch20.marshal")
|
12
|
+
gen = dcgan.gen
|
18
13
|
|
19
14
|
Numo::SFloat.srand(rand(1 << 31))
|
20
15
|
noise = Numo::SFloat.new(batch_size, 20).rand(-1, 1)
|
data/examples/dcgan/train.rb
CHANGED
@@ -20,7 +20,6 @@ dcgan = DCGAN.new(gen, dis)
|
|
20
20
|
dis.setup(Adam.new(alpha: 0.00001, beta1: 0.1), SigmoidCrossEntropy.new)
|
21
21
|
dcgan.setup(Adam.new(alpha: 0.0002, beta1: 0.5), SigmoidCrossEntropy.new)
|
22
22
|
dcgan.add_callback(CheckPoint.new("trained/dcgan_model"))
|
23
|
-
dcgan.predict1(Numo::SFloat.zeros(20))
|
24
23
|
|
25
24
|
x_train, * = MNIST.load_train
|
26
25
|
x_train = Numo::SFloat.cast(x_train)
|
data/lib/dnn.rb
CHANGED
@@ -11,21 +11,21 @@ require_relative "dnn/version"
|
|
11
11
|
require_relative "dnn/core/error"
|
12
12
|
require_relative "dnn/core/global"
|
13
13
|
require_relative "dnn/core/tensor"
|
14
|
-
require_relative "dnn/core/models"
|
15
14
|
require_relative "dnn/core/param"
|
16
15
|
require_relative "dnn/core/link"
|
17
16
|
require_relative "dnn/core/iterator"
|
18
|
-
require_relative "dnn/core/
|
19
|
-
require_relative "dnn/core/layers"
|
20
|
-
require_relative "dnn/core/normalizations"
|
21
|
-
require_relative "dnn/core/activations"
|
22
|
-
require_relative "dnn/core/merge_layers"
|
17
|
+
require_relative "dnn/core/models"
|
18
|
+
require_relative "dnn/core/layers/basic_layers"
|
19
|
+
require_relative "dnn/core/layers/normalizations"
|
20
|
+
require_relative "dnn/core/layers/activations"
|
21
|
+
require_relative "dnn/core/layers/merge_layers"
|
22
|
+
require_relative "dnn/core/layers/cnn_layers"
|
23
|
+
require_relative "dnn/core/layers/embedding"
|
24
|
+
require_relative "dnn/core/layers/rnn_layers"
|
25
|
+
require_relative "dnn/core/optimizers"
|
23
26
|
require_relative "dnn/core/losses"
|
27
|
+
require_relative "dnn/core/initializers"
|
24
28
|
require_relative "dnn/core/regularizers"
|
25
|
-
require_relative "dnn/core/cnn_layers"
|
26
|
-
require_relative "dnn/core/embedding"
|
27
|
-
require_relative "dnn/core/rnn_layers"
|
28
|
-
require_relative "dnn/core/optimizers"
|
29
29
|
require_relative "dnn/core/callbacks"
|
30
30
|
require_relative "dnn/core/savers"
|
31
31
|
require_relative "dnn/core/utils"
|
data/lib/dnn/core/callbacks.rb
CHANGED
@@ -35,13 +35,17 @@ module DNN
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# A callback that save the model at the after of the epoch.
|
38
|
+
# @param [String] base_file_name Base file name for saving.
|
39
|
+
# @param [Boolean] include_model When set a true, save data included model structure.
|
38
40
|
class CheckPoint < Callback
|
39
|
-
def initialize(base_file_name)
|
41
|
+
def initialize(base_file_name, include_model: true)
|
40
42
|
@base_file_name = base_file_name
|
43
|
+
@include_model = include_model
|
41
44
|
end
|
42
45
|
|
43
46
|
def after_epoch
|
44
|
-
|
47
|
+
saver = Savers::MarshalSaver.new(@model, include_model: @include_model)
|
48
|
+
saver.save(@base_file_name + "_epoch#{model.last_log[:epoch]}.marshal")
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
data/lib/dnn/core/iterator.rb
CHANGED
@@ -4,8 +4,8 @@ module DNN
|
|
4
4
|
attr_reader :num_datas
|
5
5
|
attr_reader :last_round_down
|
6
6
|
|
7
|
-
# @param [Numo::SFloat] x_datas input datas.
|
8
|
-
# @param [Numo::SFloat] y_datas output datas.
|
7
|
+
# @param [Numo::SFloat | Array] x_datas input datas.
|
8
|
+
# @param [Numo::SFloat | Array] y_datas output datas.
|
9
9
|
# @param [Boolean] random Set true to return batches randomly. Setting false returns batches in order of index.
|
10
10
|
# @param [Boolean] last_round_down Set true to round down for last batch data when call foreach.
|
11
11
|
def initialize(x_datas, y_datas, random: true, last_round_down: false)
|
@@ -19,6 +19,7 @@ module DNN
|
|
19
19
|
|
20
20
|
# Return the next batch.
|
21
21
|
# @param [Integer] batch_size Required batch size.
|
22
|
+
# @return [Array] Returns the mini batch in the form [x_batch, y_batch].
|
22
23
|
def next_batch(batch_size)
|
23
24
|
raise DNN_Error, "This iterator has not next batch. Please call reset." unless has_next?
|
24
25
|
if @indexes.length <= batch_size
|
@@ -27,6 +28,13 @@ module DNN
|
|
27
28
|
else
|
28
29
|
batch_indexes = @indexes.shift(batch_size)
|
29
30
|
end
|
31
|
+
get_batch(batch_indexes)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Implement a process to get mini batch.
|
35
|
+
# @param [Array] batch_indexes Index of batch to get.
|
36
|
+
# @return [Array] Returns the mini batch in the form [x_batch, y_batch].
|
37
|
+
private def get_batch(batch_indexes)
|
30
38
|
x_batch = if @x_datas.is_a?(Array)
|
31
39
|
@x_datas.map { |datas| datas[batch_indexes, false] }
|
32
40
|
else
|
File without changes
|
@@ -3,7 +3,6 @@ module DNN
|
|
3
3
|
|
4
4
|
# Super class of all layer classes.
|
5
5
|
class Layer
|
6
|
-
attr_accessor :name
|
7
6
|
attr_reader :input_shape
|
8
7
|
|
9
8
|
def self.call(x, *args)
|
@@ -16,13 +15,11 @@ module DNN
|
|
16
15
|
layer = layer_class.allocate
|
17
16
|
raise DNN_Error, "#{layer.class} is not an instance of #{self} class." unless layer.is_a?(self)
|
18
17
|
layer.load_hash(hash)
|
19
|
-
layer.name = hash[:name]&.to_sym
|
20
18
|
layer
|
21
19
|
end
|
22
20
|
|
23
21
|
def initialize
|
24
22
|
@built = false
|
25
|
-
@name = nil
|
26
23
|
end
|
27
24
|
|
28
25
|
# Forward propagation and create a link.
|
@@ -70,7 +67,7 @@ module DNN
|
|
70
67
|
|
71
68
|
# Layer to a hash.
|
72
69
|
def to_hash(merge_hash = nil)
|
73
|
-
hash = { class: self.class.name
|
70
|
+
hash = { class: self.class.name }
|
74
71
|
hash.merge!(merge_hash) if merge_hash
|
75
72
|
hash
|
76
73
|
end
|
@@ -78,10 +75,20 @@ module DNN
|
|
78
75
|
def load_hash(hash)
|
79
76
|
initialize
|
80
77
|
end
|
78
|
+
|
79
|
+
def clean
|
80
|
+
input_shape = @input_shape
|
81
|
+
hash = to_hash
|
82
|
+
instance_variables.each do |ivar|
|
83
|
+
instance_variable_set(ivar, nil)
|
84
|
+
end
|
85
|
+
load_hash(hash)
|
86
|
+
build(input_shape)
|
87
|
+
end
|
81
88
|
end
|
82
89
|
|
83
90
|
# This class is a superclass of all classes with learning parameters.
|
84
|
-
class
|
91
|
+
class TrainableLayer < Layer
|
85
92
|
# @return [Boolean] Setting false prevents learning of parameters.
|
86
93
|
attr_accessor :trainable
|
87
94
|
|
@@ -94,6 +101,22 @@ module DNN
|
|
94
101
|
def get_params
|
95
102
|
raise NotImplementedError, "Class '#{self.class.name}' has implement method 'get_params'"
|
96
103
|
end
|
104
|
+
|
105
|
+
def clean
|
106
|
+
input_shape = @input_shape
|
107
|
+
hash = to_hash
|
108
|
+
params = get_params
|
109
|
+
instance_variables.each do |ivar|
|
110
|
+
instance_variable_set(ivar, nil)
|
111
|
+
end
|
112
|
+
load_hash(hash)
|
113
|
+
build(input_shape)
|
114
|
+
params.each do |(key, param)|
|
115
|
+
param.data = nil
|
116
|
+
param.grad = Xumo::SFloat[0] if param.grad
|
117
|
+
instance_variable_set("@#{key}", param)
|
118
|
+
end
|
119
|
+
end
|
97
120
|
end
|
98
121
|
|
99
122
|
class InputLayer < Layer
|
@@ -109,7 +132,7 @@ module DNN
|
|
109
132
|
end
|
110
133
|
|
111
134
|
def call(input)
|
112
|
-
build unless built?
|
135
|
+
build(@input_shape) unless built?
|
113
136
|
if input.is_a?(Tensor)
|
114
137
|
x = input.data
|
115
138
|
prev_link = input&.link
|
@@ -120,7 +143,7 @@ module DNN
|
|
120
143
|
Tensor.new(forward(x), Link.new(prev_link, self))
|
121
144
|
end
|
122
145
|
|
123
|
-
def build
|
146
|
+
def build(input_shape)
|
124
147
|
@built = true
|
125
148
|
end
|
126
149
|
|
@@ -163,7 +186,7 @@ module DNN
|
|
163
186
|
end
|
164
187
|
|
165
188
|
# It is a superclass of all connection layers.
|
166
|
-
class Connection <
|
189
|
+
class Connection < TrainableLayer
|
167
190
|
attr_reader :weight
|
168
191
|
attr_reader :bias
|
169
192
|
attr_reader :weight_initializer
|
File without changes
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DNN
|
2
2
|
module Layers
|
3
3
|
|
4
|
-
class Embedding <
|
4
|
+
class Embedding < TrainableLayer
|
5
5
|
attr_reader :input_length
|
6
6
|
attr_reader :weight
|
7
7
|
attr_reader :weight_initializer
|
@@ -19,16 +19,17 @@ module DNN
|
|
19
19
|
@input_length = input_length
|
20
20
|
@weight_initializer = weight_initializer
|
21
21
|
@weight_regularizer = weight_regularizer
|
22
|
+
@weight = Param.new(nil, Xumo::SFloat[0])
|
22
23
|
end
|
23
24
|
|
24
25
|
def call(input_tensor)
|
25
|
-
build unless built?
|
26
|
+
build(@input_shape) unless built?
|
26
27
|
Tensor.new(forward(input_tensor.data), Link.new(nil, self))
|
27
28
|
end
|
28
29
|
|
29
|
-
def build
|
30
|
+
def build(input_shape)
|
30
31
|
@built = true
|
31
|
-
@weight =
|
32
|
+
@weight.data = Xumo::SFloat.new(@input_length)
|
32
33
|
@weight_initializer.init_param(self, @weight)
|
33
34
|
@weight_regularizer.param = @weight if @weight_regularizer
|
34
35
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DNN
|
2
2
|
module Layers
|
3
3
|
|
4
|
-
class BatchNormalization <
|
4
|
+
class BatchNormalization < TrainableLayer
|
5
5
|
attr_reader :gamma
|
6
6
|
attr_reader :beta
|
7
7
|
attr_reader :running_mean
|
@@ -18,14 +18,18 @@ module DNN
|
|
18
18
|
@axis = axis
|
19
19
|
@momentum = momentum
|
20
20
|
@eps = eps
|
21
|
+
@gamma = Param.new(nil, Xumo::SFloat[0])
|
22
|
+
@beta = Param.new(nil, Xumo::SFloat[0])
|
23
|
+
@running_mean = Param.new
|
24
|
+
@running_var = Param.new
|
21
25
|
end
|
22
26
|
|
23
27
|
def build(input_shape)
|
24
28
|
super
|
25
|
-
@gamma =
|
26
|
-
@beta =
|
27
|
-
@running_mean =
|
28
|
-
@running_var =
|
29
|
+
@gamma.data = Xumo::SFloat.ones(*output_shape)
|
30
|
+
@beta.data = Xumo::SFloat.zeros(*output_shape)
|
31
|
+
@running_mean.data = Xumo::SFloat.zeros(*output_shape)
|
32
|
+
@running_var.data = Xumo::SFloat.zeros(*output_shape)
|
29
33
|
end
|
30
34
|
|
31
35
|
def forward(x)
|
@@ -31,7 +31,7 @@ module DNN
|
|
31
31
|
@num_nodes = num_nodes
|
32
32
|
@stateful = stateful
|
33
33
|
@return_sequences = return_sequences
|
34
|
-
@
|
34
|
+
@hidden_layers = []
|
35
35
|
@hidden = Param.new
|
36
36
|
@recurrent_weight = Param.new(nil, Xumo::SFloat[0])
|
37
37
|
@recurrent_weight_initializer = recurrent_weight_initializer
|
@@ -46,14 +46,19 @@ module DNN
|
|
46
46
|
@time_length = @input_shape[0]
|
47
47
|
end
|
48
48
|
|
49
|
+
private def create_hidden_layer
|
50
|
+
raise NotImplementedError, "Class '#{self.class.name}' has implement method 'create_hidden_layer'"
|
51
|
+
end
|
52
|
+
|
49
53
|
def forward(xs)
|
54
|
+
create_hidden_layer
|
50
55
|
@xs_shape = xs.shape
|
51
56
|
hs = Xumo::SFloat.zeros(xs.shape[0], @time_length, @num_nodes)
|
52
57
|
h = @stateful && @hidden.data ? @hidden.data : Xumo::SFloat.zeros(xs.shape[0], @num_nodes)
|
53
58
|
xs.shape[1].times do |t|
|
54
59
|
x = xs[true, t, false]
|
55
|
-
@
|
56
|
-
h = @
|
60
|
+
@hidden_layers[t].trainable = @trainable
|
61
|
+
h = @hidden_layers[t].forward(x, h)
|
57
62
|
hs[true, t, false] = h
|
58
63
|
end
|
59
64
|
@hidden.data = h
|
@@ -70,7 +75,7 @@ module DNN
|
|
70
75
|
dh = 0
|
71
76
|
(dh2s.shape[1] - 1).downto(0) do |t|
|
72
77
|
dh2 = dh2s[true, t, false]
|
73
|
-
dx, dh = @
|
78
|
+
dx, dh = @hidden_layers[t].backward(dh2 + dh)
|
74
79
|
dxs[true, t, false] = dx
|
75
80
|
end
|
76
81
|
dxs
|
@@ -196,9 +201,10 @@ module DNN
|
|
196
201
|
@recurrent_weight.data = Xumo::SFloat.new(@num_nodes, @num_nodes)
|
197
202
|
@bias.data = Xumo::SFloat.new(@num_nodes) if @bias
|
198
203
|
init_weight_and_bias
|
199
|
-
|
200
|
-
|
201
|
-
|
204
|
+
end
|
205
|
+
|
206
|
+
def create_hidden_layer
|
207
|
+
@hidden_layers = Array.new(@time_length) { SimpleRNNDense.new(@weight, @recurrent_weight, @bias, @activation) }
|
202
208
|
end
|
203
209
|
|
204
210
|
def to_hash
|
@@ -301,12 +307,14 @@ module DNN
|
|
301
307
|
@recurrent_weight.data = Xumo::SFloat.new(@num_nodes, @num_nodes * 4)
|
302
308
|
@bias.data = Xumo::SFloat.new(@num_nodes * 4) if @bias
|
303
309
|
init_weight_and_bias
|
304
|
-
|
305
|
-
|
306
|
-
|
310
|
+
end
|
311
|
+
|
312
|
+
def create_hidden_layer
|
313
|
+
@hidden_layers = Array.new(@time_length) { LSTMDense.new(@weight, @recurrent_weight, @bias) }
|
307
314
|
end
|
308
315
|
|
309
316
|
def forward(xs)
|
317
|
+
create_hidden_layer
|
310
318
|
@xs_shape = xs.shape
|
311
319
|
hs = Xumo::SFloat.zeros(xs.shape[0], @time_length, @num_nodes)
|
312
320
|
h = nil
|
@@ -319,8 +327,8 @@ module DNN
|
|
319
327
|
c ||= Xumo::SFloat.zeros(xs.shape[0], @num_nodes)
|
320
328
|
xs.shape[1].times do |t|
|
321
329
|
x = xs[true, t, false]
|
322
|
-
@
|
323
|
-
h, c = @
|
330
|
+
@hidden_layers[t].trainable = @trainable
|
331
|
+
h, c = @hidden_layers[t].forward(x, h, c)
|
324
332
|
hs[true, t, false] = h
|
325
333
|
end
|
326
334
|
@hidden.data = h
|
@@ -339,7 +347,7 @@ module DNN
|
|
339
347
|
dc = 0
|
340
348
|
(dh2s.shape[1] - 1).downto(0) do |t|
|
341
349
|
dh2 = dh2s[true, t, false]
|
342
|
-
dx, dh, dc = @
|
350
|
+
dx, dh, dc = @hidden_layers[t].backward(dh2 + dh, dc)
|
343
351
|
dxs[true, t, false] = dx
|
344
352
|
end
|
345
353
|
dxs
|
@@ -444,9 +452,10 @@ module DNN
|
|
444
452
|
@recurrent_weight.data = Xumo::SFloat.new(@num_nodes, @num_nodes * 3)
|
445
453
|
@bias.data = Xumo::SFloat.new(@num_nodes * 3) if @bias
|
446
454
|
init_weight_and_bias
|
447
|
-
|
448
|
-
|
449
|
-
|
455
|
+
end
|
456
|
+
|
457
|
+
def create_hidden_layer
|
458
|
+
@hidden_layers = Array.new(@time_length) { GRUDense.new(@weight, @recurrent_weight, @bias) }
|
450
459
|
end
|
451
460
|
end
|
452
461
|
|