ruby-dnn 0.12.4 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/examples/cifar100_example.rb +1 -1
- data/examples/cifar10_example.rb +1 -1
- data/examples/dcgan/dcgan.rb +7 -3
- data/examples/dcgan/imgen.rb +1 -1
- data/examples/dcgan/train.rb +5 -2
- data/examples/iris_example.rb +1 -1
- data/examples/mnist_conv2d_example.rb +1 -1
- data/examples/mnist_define_by_run.rb +1 -1
- data/examples/mnist_example.rb +1 -1
- data/examples/mnist_lstm_example.rb +1 -1
- data/lib/dnn.rb +2 -0
- data/lib/dnn/core/embedding.rb +1 -2
- data/lib/dnn/core/error.rb +2 -0
- data/lib/dnn/core/global.rb +9 -0
- data/lib/dnn/core/initializers.rb +1 -1
- data/lib/dnn/core/iterator.rb +11 -3
- data/lib/dnn/core/layers.rb +13 -15
- data/lib/dnn/core/link.rb +11 -0
- data/lib/dnn/core/losses.rb +52 -63
- data/lib/dnn/core/merge_layers.rb +3 -3
- data/lib/dnn/core/models.rb +130 -140
- data/lib/dnn/core/normalizations.rb +2 -10
- data/lib/dnn/core/optimizers.rb +62 -57
- data/lib/dnn/core/param.rb +2 -0
- data/lib/dnn/core/savers.rb +138 -0
- data/lib/dnn/{cifar10.rb → datasets/cifar10.rb} +1 -1
- data/lib/dnn/{cifar100.rb → datasets/cifar100.rb} +1 -1
- data/lib/dnn/{downloader.rb → datasets/downloader.rb} +0 -0
- data/lib/dnn/{fashion-mnist.rb → datasets/fashion-mnist.rb} +1 -1
- data/lib/dnn/{iris.rb → datasets/iris.rb} +0 -0
- data/lib/dnn/{mnist.rb → datasets/mnist.rb} +1 -1
- data/lib/dnn/version.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a0f021b01f03d45c51e52a1147b05703f8da8895380560d4add4fd3f2fc3d90
|
4
|
+
data.tar.gz: 2c5b3b04d23b0285a0acd1fbde3ca4f774948645d016c471264484f45230fa6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33758acb29f83b8523accd213293c84d4b887591926de256e38bd41895f86358c80ee64f2876cd4fb679a9a2c71a64929780149a324dd80020f5b6d397c9a608
|
7
|
+
data.tar.gz: 6a8e95ca8c57a968a846562ad4fa921e382cef83c0839599651ab93ad2d7f6d6cb0c36ada945fb125c0b13e10aa1333030ce019b138146b00e19ed9882237ae7
|
data/examples/cifar10_example.rb
CHANGED
data/examples/dcgan/dcgan.rb
CHANGED
@@ -68,9 +68,13 @@ class Discriminator < Model
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def call(x, trainable = true)
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
@l1.trainable = trainable
|
72
|
+
@l2.trainable = trainable
|
73
|
+
@l3.trainable = trainable
|
74
|
+
@l4.trainable = trainable
|
75
|
+
@l5.trainable = trainable
|
76
|
+
@l6.trainable = trainable
|
77
|
+
|
74
78
|
x = InputLayer.new([28, 28, 1]).(x)
|
75
79
|
x = @l1.(x)
|
76
80
|
x = LeakyReLU.(x, 0.2)
|
data/examples/dcgan/imgen.rb
CHANGED
data/examples/dcgan/train.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "dnn"
|
2
|
-
require "dnn/mnist"
|
2
|
+
require "dnn/datasets/mnist"
|
3
3
|
require "numo/linalg/autoloader"
|
4
4
|
require_relative "dcgan"
|
5
5
|
|
@@ -22,9 +22,11 @@ x_train = Numo::SFloat.cast(x_train)
|
|
22
22
|
x_train = x_train / 127.5 - 1
|
23
23
|
|
24
24
|
iter = DNN::Iterator.new(x_train, y_train)
|
25
|
+
num_batchs = x_train.shape[0] / batch_size
|
25
26
|
(1..epochs).each do |epoch|
|
26
27
|
puts "epoch: #{epoch}"
|
27
|
-
|
28
|
+
num_batchs.times do |index|
|
29
|
+
x_batch, y_batch = iter.next_batch(batch_size)
|
28
30
|
noise = Numo::SFloat.new(batch_size, 20).rand(-1, 1)
|
29
31
|
images = gen.predict(noise)
|
30
32
|
x = x_batch.concatenate(images)
|
@@ -37,5 +39,6 @@ iter = DNN::Iterator.new(x_train, y_train)
|
|
37
39
|
|
38
40
|
puts "index: #{index}, dis_loss: #{dis_loss.mean}, dcgan_loss: #{dcgan_loss.mean}"
|
39
41
|
end
|
42
|
+
iter.reset
|
40
43
|
dcgan.save("trained/dcgan_model_epoch#{epoch}.marshal")
|
41
44
|
end
|
data/examples/iris_example.rb
CHANGED
data/examples/mnist_example.rb
CHANGED
data/lib/dnn.rb
CHANGED
@@ -9,6 +9,7 @@ end
|
|
9
9
|
|
10
10
|
require_relative "dnn/version"
|
11
11
|
require_relative "dnn/core/error"
|
12
|
+
require_relative "dnn/core/global"
|
12
13
|
require_relative "dnn/core/models"
|
13
14
|
require_relative "dnn/core/param"
|
14
15
|
require_relative "dnn/core/link"
|
@@ -24,4 +25,5 @@ require_relative "dnn/core/cnn_layers"
|
|
24
25
|
require_relative "dnn/core/embedding"
|
25
26
|
require_relative "dnn/core/rnn_layers"
|
26
27
|
require_relative "dnn/core/optimizers"
|
28
|
+
require_relative "dnn/core/savers"
|
27
29
|
require_relative "dnn/core/utils"
|
data/lib/dnn/core/embedding.rb
CHANGED
data/lib/dnn/core/error.rb
CHANGED
@@ -2,7 +2,7 @@ module DNN
|
|
2
2
|
module Initializers
|
3
3
|
|
4
4
|
class Initializer
|
5
|
-
# @param [Boolean | Integer] seed Seed of random number used for
|
5
|
+
# @param [Boolean | Integer] seed Seed of random number used for initialize parameter.
|
6
6
|
# Set true to determine seed as random.
|
7
7
|
def initialize(seed: false)
|
8
8
|
@seed = seed == true ? rand(1 << 31) : seed
|
data/lib/dnn/core/iterator.rb
CHANGED
@@ -8,7 +8,7 @@ module DNN
|
|
8
8
|
@x_datas = x_datas
|
9
9
|
@y_datas = y_datas
|
10
10
|
@random = random
|
11
|
-
@num_datas = x_datas.shape[0]
|
11
|
+
@num_datas = x_datas.is_a?(Array) ? x_datas[0].shape[0] : x_datas.shape[0]
|
12
12
|
reset
|
13
13
|
end
|
14
14
|
|
@@ -22,8 +22,16 @@ module DNN
|
|
22
22
|
else
|
23
23
|
batch_indexes = @indexes.shift(batch_size)
|
24
24
|
end
|
25
|
-
x_batch = @x_datas
|
26
|
-
|
25
|
+
x_batch = if @x_datas.is_a?(Array)
|
26
|
+
@x_datas.map { |datas| datas[batch_indexes, false] }
|
27
|
+
else
|
28
|
+
@x_datas[batch_indexes, false]
|
29
|
+
end
|
30
|
+
y_batch = if @y_datas.is_a?(Array)
|
31
|
+
@y_datas.map { |datas| datas[batch_indexes, false] }
|
32
|
+
else
|
33
|
+
@y_datas[batch_indexes, false]
|
34
|
+
end
|
27
35
|
[x_batch, y_batch]
|
28
36
|
end
|
29
37
|
|
data/lib/dnn/core/layers.rb
CHANGED
@@ -3,6 +3,7 @@ module DNN
|
|
3
3
|
|
4
4
|
# Super class of all layer classes.
|
5
5
|
class Layer
|
6
|
+
attr_accessor :name
|
6
7
|
attr_reader :input_shape
|
7
8
|
|
8
9
|
def self.call(x, *args)
|
@@ -14,13 +15,13 @@ module DNN
|
|
14
15
|
end
|
15
16
|
|
16
17
|
# Forward propagation and create a link.
|
17
|
-
# @param [Array] input Array of the form [x_input_data, prev_link
|
18
|
+
# @param [Array] input Array of the form [x_input_data, prev_link].
|
18
19
|
def call(input)
|
19
|
-
x, prev_link
|
20
|
+
x, prev_link = *input
|
20
21
|
build(x.shape[1..-1]) unless built?
|
21
22
|
y = forward(x)
|
22
23
|
link = Link.new(prev_link, self)
|
23
|
-
[y, link
|
24
|
+
[y, link]
|
24
25
|
end
|
25
26
|
|
26
27
|
# Build the layer.
|
@@ -98,9 +99,14 @@ module DNN
|
|
98
99
|
|
99
100
|
def call(input)
|
100
101
|
build unless built?
|
101
|
-
|
102
|
+
if input.is_a?(Array)
|
103
|
+
x, prev_link = *input
|
104
|
+
else
|
105
|
+
x = input
|
106
|
+
prev_link = nil
|
107
|
+
end
|
102
108
|
link = prev_link ? Link.new(prev_link, self) : Link.new(nil, self)
|
103
|
-
[forward(x), link
|
109
|
+
[forward(x), link]
|
104
110
|
end
|
105
111
|
|
106
112
|
def build
|
@@ -310,16 +316,8 @@ module DNN
|
|
310
316
|
@rnd = Random.new(@seed)
|
311
317
|
end
|
312
318
|
|
313
|
-
def
|
314
|
-
|
315
|
-
build(x.shape[1..-1]) unless built?
|
316
|
-
y = forward(x, learning_phase)
|
317
|
-
link = Link.new(prev_link, self)
|
318
|
-
[y, link, learning_phase]
|
319
|
-
end
|
320
|
-
|
321
|
-
def forward(x, learning_phase)
|
322
|
-
if learning_phase
|
319
|
+
def forward(x)
|
320
|
+
if DNN.learning_phase
|
323
321
|
Xumo::SFloat.srand(@rnd.rand(1 << 31))
|
324
322
|
@mask = Xumo::SFloat.ones(*x.shape).rand < @dropout_ratio
|
325
323
|
x[@mask] = 0
|
data/lib/dnn/core/link.rb
CHANGED
@@ -7,6 +7,11 @@ module DNN
|
|
7
7
|
@prev = prev
|
8
8
|
@layer = layer
|
9
9
|
end
|
10
|
+
|
11
|
+
def backward(dy)
|
12
|
+
dy = @layer.backward(dy)
|
13
|
+
@prev&.backward(dy)
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
17
|
|
@@ -20,5 +25,11 @@ module DNN
|
|
20
25
|
@prev2 = prev2
|
21
26
|
@layer = layer
|
22
27
|
end
|
28
|
+
|
29
|
+
def backward(dy)
|
30
|
+
dy1, dy2 =* @layer.backward(dy)
|
31
|
+
@prev1&.backward(dy1)
|
32
|
+
@prev2&.backward(dy2)
|
33
|
+
end
|
23
34
|
end
|
24
35
|
end
|
data/lib/dnn/core/losses.rb
CHANGED
@@ -2,25 +2,37 @@ module DNN
|
|
2
2
|
module Losses
|
3
3
|
|
4
4
|
class Loss
|
5
|
-
def
|
5
|
+
def loss(y, t, layers = nil)
|
6
6
|
unless y.shape == t.shape
|
7
7
|
raise DNN_ShapeError.new("The shape of y does not match the t shape. y shape is #{y.shape}, but t shape is #{t.shape}.")
|
8
8
|
end
|
9
|
-
loss_value =
|
10
|
-
|
11
|
-
|
9
|
+
loss_value = forward(y, t)
|
10
|
+
loss_value += regularizers_forward(layers) if layers
|
11
|
+
loss_value
|
12
|
+
end
|
13
|
+
|
14
|
+
def forward(y, t)
|
15
|
+
raise NotImplementedError.new("Class '#{self.class.name}' has implement method 'forward'")
|
16
|
+
end
|
12
17
|
|
18
|
+
def backward(y, t)
|
19
|
+
raise NotImplementedError.new("Class '#{self.class.name}' has implement method 'backward'")
|
20
|
+
end
|
21
|
+
|
22
|
+
def regularizers_forward(layers)
|
23
|
+
loss_value = 0
|
24
|
+
regularizers = layers.select { |layer| layer.respond_to?(:regularizers) }
|
25
|
+
.map(&:regularizers).flatten
|
13
26
|
regularizers.each do |regularizer|
|
14
27
|
loss_value = regularizer.forward(loss_value)
|
15
28
|
end
|
16
29
|
loss_value
|
17
30
|
end
|
18
31
|
|
19
|
-
def
|
32
|
+
def regularizers_backward(layers)
|
20
33
|
layers.select { |layer| layer.respond_to?(:regularizers) }.each do |layer|
|
21
34
|
layer.regularizers.each(&:backward)
|
22
35
|
end
|
23
|
-
backward_loss(t)
|
24
36
|
end
|
25
37
|
|
26
38
|
def to_hash(merge_hash = nil)
|
@@ -28,44 +40,28 @@ module DNN
|
|
28
40
|
hash.merge!(merge_hash) if merge_hash
|
29
41
|
hash
|
30
42
|
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def forward_loss(y, t)
|
35
|
-
raise NotImplementedError.new("Class '#{self.class.name}' has implement method 'forward_loss'")
|
36
|
-
end
|
37
|
-
|
38
|
-
def backward_loss(t)
|
39
|
-
raise NotImplementedError.new("Class '#{self.class.name}' has implement method 'backward_loss'")
|
40
|
-
end
|
41
43
|
end
|
42
44
|
|
43
45
|
class MeanSquaredError < Loss
|
44
|
-
|
45
|
-
|
46
|
-
def forward_loss(y, t)
|
47
|
-
@y = y
|
46
|
+
def forward(y, t)
|
48
47
|
batch_size = t.shape[0]
|
49
48
|
0.5 * ((y - t) ** 2).sum / batch_size
|
50
49
|
end
|
51
50
|
|
52
|
-
def
|
53
|
-
|
51
|
+
def backward(y, t)
|
52
|
+
y - t
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
56
|
|
58
57
|
class MeanAbsoluteError < Loss
|
59
|
-
|
60
|
-
|
61
|
-
def forward_loss(y, t)
|
62
|
-
@y = y
|
58
|
+
def forward(y, t)
|
63
59
|
batch_size = t.shape[0]
|
64
60
|
(y - t).abs.sum / batch_size
|
65
61
|
end
|
66
62
|
|
67
|
-
def
|
68
|
-
dy =
|
63
|
+
def backward(y, t)
|
64
|
+
dy = y - t
|
69
65
|
dy[dy >= 0] = 1
|
70
66
|
dy[dy < 0] = -1
|
71
67
|
dy
|
@@ -74,14 +70,12 @@ module DNN
|
|
74
70
|
|
75
71
|
|
76
72
|
class Hinge < Loss
|
77
|
-
|
78
|
-
|
79
|
-
def forward_loss(y, t)
|
73
|
+
def forward(y, t)
|
80
74
|
@a = 1 - y * t
|
81
75
|
Xumo::SFloat.maximum(0, @a)
|
82
76
|
end
|
83
77
|
|
84
|
-
def
|
78
|
+
def backward(y, t)
|
85
79
|
a = Xumo::SFloat.ones(*@a.shape)
|
86
80
|
a[@a <= 0] = 0
|
87
81
|
a * -t
|
@@ -90,16 +84,13 @@ module DNN
|
|
90
84
|
|
91
85
|
|
92
86
|
class HuberLoss < Loss
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
@y = y
|
97
|
-
loss_l1_value = loss_l1(t)
|
98
|
-
@loss_value = loss_l1_value > 1 ? loss_l1_value : loss_l2(t)
|
87
|
+
def forward(y, t)
|
88
|
+
loss_l1_value = loss_l1(y, t)
|
89
|
+
@loss_value = loss_l1_value > 1 ? loss_l1_value : loss_l2(y, t)
|
99
90
|
end
|
100
91
|
|
101
|
-
def
|
102
|
-
dy =
|
92
|
+
def backward(y, t)
|
93
|
+
dy = y - t
|
103
94
|
if @loss_value > 1
|
104
95
|
dy[dy >= 0] = 1
|
105
96
|
dy[dy < 0] = -1
|
@@ -107,14 +98,16 @@ module DNN
|
|
107
98
|
dy
|
108
99
|
end
|
109
100
|
|
110
|
-
|
101
|
+
private
|
102
|
+
|
103
|
+
def loss_l1(y, t)
|
111
104
|
batch_size = t.shape[0]
|
112
|
-
(
|
105
|
+
(y - t).abs.sum / batch_size
|
113
106
|
end
|
114
107
|
|
115
|
-
def loss_l2(t)
|
108
|
+
def loss_l2(y, t)
|
116
109
|
batch_size = t.shape[0]
|
117
|
-
0.5 * ((
|
110
|
+
0.5 * ((y - t) ** 2).sum / batch_size
|
118
111
|
end
|
119
112
|
end
|
120
113
|
|
@@ -135,20 +128,18 @@ module DNN
|
|
135
128
|
@eps = eps
|
136
129
|
end
|
137
130
|
|
138
|
-
def
|
139
|
-
|
131
|
+
def forward(y, t)
|
132
|
+
@x = SoftmaxCrossEntropy.softmax(y)
|
133
|
+
batch_size = t.shape[0]
|
134
|
+
-(t * Xumo::NMath.log(@x + @eps)).sum / batch_size
|
140
135
|
end
|
141
136
|
|
142
|
-
|
143
|
-
|
144
|
-
def forward_loss(y, t)
|
145
|
-
@y = SoftmaxCrossEntropy.softmax(y)
|
146
|
-
batch_size = t.shape[0]
|
147
|
-
-(t * Xumo::NMath.log(@y + @eps)).sum / batch_size
|
137
|
+
def backward(y, t)
|
138
|
+
@x - t
|
148
139
|
end
|
149
140
|
|
150
|
-
def
|
151
|
-
@
|
141
|
+
def to_hash
|
142
|
+
super(eps: @eps)
|
152
143
|
end
|
153
144
|
end
|
154
145
|
|
@@ -165,19 +156,17 @@ module DNN
|
|
165
156
|
@eps = eps
|
166
157
|
end
|
167
158
|
|
168
|
-
def
|
169
|
-
|
159
|
+
def forward(y, t)
|
160
|
+
@x = Activations::Sigmoid.new.forward(y)
|
161
|
+
-(t * Xumo::NMath.log(@x) + (1 - t) * Xumo::NMath.log(1 - @x))
|
170
162
|
end
|
171
163
|
|
172
|
-
|
173
|
-
|
174
|
-
def forward_loss(y, t)
|
175
|
-
@y = Activations::Sigmoid.new.forward(y)
|
176
|
-
-(t * Xumo::NMath.log(@y) + (1 - t) * Xumo::NMath.log(1 - @y))
|
164
|
+
def backward(y, t)
|
165
|
+
@x - t
|
177
166
|
end
|
178
167
|
|
179
|
-
def
|
180
|
-
@
|
168
|
+
def to_hash
|
169
|
+
super(eps: @eps)
|
181
170
|
end
|
182
171
|
end
|
183
172
|
|