ruby-dnn 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d462153bdd72ecf6df60f2d6bc6922ee76f3fd1318f03d33e644c91fe0b1881e
4
- data.tar.gz: 3ba2d911fbb994f18aa1bf9bb389e1c50fd31c10c5e1dcded5c9f4567b7e35ef
3
+ metadata.gz: 634ecbbfbad30f1660a3f04adc9e3a3835d54b93dc84eb765962406111243f46
4
+ data.tar.gz: 7b00ad63ddf17e95df2e852b29005fdb35671b2bed12e951d8c54fcc3415abe7
5
5
  SHA512:
6
- metadata.gz: f06a8bc128241b4e50c72ccc9e7a72944b705991d6f52b65a1276042f78bfd50d19cd8f971a717fdb3699b7bb93bc136fc44f24b4202f2aff9f98f295e20198f
7
- data.tar.gz: 2e115414aab91238cc1ad46255c5ca407bbcb786a41d12626671d4e8cb9a93d34a455a23d41ab2bf90d52e9c5a4a10e51a6686a240cc5fd642028e5111167c8c
6
+ metadata.gz: fba18cc2365d798e27fc3fa8be1f296664d23ef2b04d0e6d8db635189b4cf591675e29c8314437b00e8dc122d143ec956486915ed84a37e8b19b0952687a6467
7
+ data.tar.gz: f2d7f67c6331db0d58a01b3dbbc3f9b136fc692900811e88251e0a6865a0b0790e4291621296155f3f7778051ac0323a727ae6d1e812baebf76096a25b9ee0d9
@@ -1,8 +1,16 @@
1
- ## ruby-dnnのAPIリファレンスです。
1
+ # APIリファレンス
2
+ ruby-dnnのAPIリファレンスです。このリファレンスでは、APIを利用するうえで必要となるクラスとメソッドしか記載していません。
3
+ そのため、プログラムの詳細が必要な場合は、ソースコードを参照してください。
4
+
5
+ 対応バージョン:0.1.6
2
6
 
3
7
  # module DNN
4
8
  ruby-dnnの名前空間をなすモジュールです。
5
9
 
10
+ ## 【Constants】
11
+ ## VERSION
12
+ ruby-dnnのバージョン。
13
+
6
14
 
7
15
  # class Model
8
16
  ニューラルネットワークのモデルを作成するクラスです。
@@ -15,23 +23,56 @@ marshalファイルを読み込み、モデルを作成します。
15
23
  * String file_name
16
24
  読み込むmarshalファイル名。
17
25
  ### return
18
- なし。
26
+ Model
27
+ 生成したモデル。
28
+
29
+ ## def self.load_json(json_str)
30
+ json文字列からモデルを作成します。
31
+ ### arguments
32
+ * String json_str
33
+ json文字列。
34
+ ### return
35
+ Model
36
+ 生成したモデル。
19
37
 
20
38
  ## 【Instance methods】
21
39
 
22
- ## def initialize
23
- コンストラクタ。
40
+ ## def load_json_params(json_str)
41
+ 学習パラメータをjson文字列から取得し、モデルにセットします。
24
42
  ### arguments
43
+ * String json_str
44
+ 学習パラメータを変換して生成したjson文字列。
45
+ ### return
25
46
  なし。
26
47
 
27
48
  ## def save(file_name)
28
49
  モデルをmarshalファイルに保存します。
50
+ このmarshalファイルには、学習パラメータ及びOptimizerの状態が保存されるため、
51
+ 読み込んだ後、正確に学習を継続することができます。
29
52
  ### arguments
30
53
  * String file_name
31
54
  書き込むファイル名。
32
55
  ### return
33
56
  なし。
34
57
 
58
+ ## def to_json
59
+ モデルをjson文字列に変換します。
60
+ 変換したjson文字列には学習パラメータの情報は含まれません。
61
+ 学習パラメータの情報を取得したい場合は、params_to_jsonを使用してください。
62
+ ### arguments
63
+ なし。
64
+ ### return
65
+ String
66
+ モデルを変換して生成したjson文字列。
67
+
68
+ ## def params_to_json
69
+ 学習パラメータをjson文字列に変換します。
70
+ ### arguments
71
+ なし。
72
+ ### return
73
+ String
74
+ 学習パラメータを変換して生成したjson文字列。
75
+
35
76
  ## def <<(layer)
36
77
  モデルにレイヤーを追加します。
37
78
  ### arguments
@@ -168,34 +209,19 @@ SFloat
168
209
  Array
169
210
  レイヤーの形状。Layerクラスのshapeメソッドでは、前レイヤーの形状を返却します。
170
211
 
171
- ## def prev_layer
172
- 前のレイヤーを取得します。
212
+ ## abstruct def to_hash
213
+ レイヤーをハッシュに変換します。このメソッドは、モデルをjsonに変換するために使用されます。このメソッドが返すハッシュの要素には、{name: self.class.name}が含まれていなければなりません。
173
214
  ### arguments
174
215
  なし。
175
216
  ### return
176
- Layer
177
- 前のレイヤー。
217
+ Hash
218
+ レイヤーを変換したハッシュ。
178
219
 
179
220
 
180
221
  # class HasParamLayer < Layer
181
222
  学習可能なパラメータを持つ全てのレイヤーのスーパークラスです。
182
223
 
183
224
  ## 【Instance methods】
184
- ## def initialize
185
- コンストラクタ
186
- ### arguments
187
- なし。
188
-
189
- ## override def init(model)
190
- Layerクラスからオーバーライドされたメソッドです。
191
- init_paramの呼び出しを行います。
192
-
193
- ## def update
194
- オプティマイザーを用いてパラメータの更新を行います。
195
- ### arguments
196
- なし。
197
- ### return
198
- なし。
199
225
 
200
226
  ## private abstruct def init_params
201
227
  更新可能なパラメータを初期化します。HasParamLayerクラスを継承するクラスは、このメソッドを実装する必要があります。
@@ -208,11 +234,6 @@ init_paramの呼び出しを行います。
208
234
  # class InputLayer < Layer
209
235
  入力層に該当するレイヤーです。モデルの先頭レイヤーは、必ずこのクラスのインスタンスでなければなりません。
210
236
 
211
- ## 【Properties】
212
- ## attr_reaedr :shape
213
- SFloat shape
214
- コンストラクタで設定されたshapeを取得します。
215
-
216
237
  ## 【Instance methods】
217
238
  ## def initialize(dim_or_shape)
218
239
  コンストラクタ
@@ -220,12 +241,6 @@ SFloat shape
220
241
  * Integer|Array dim_or_shape
221
242
  入力層のdimentionまたはshapeを指定します。引数がIntegerだとdimentionとみなし、Arrayだとshapeとみなします。
222
243
 
223
- ## override def forward(x)
224
- 入力値をそのまま順方向に伝搬します。
225
-
226
- ## override def backward(dout)
227
- 逆方向から伝搬してきた微分値をそのまま逆方向に伝搬します。
228
-
229
244
 
230
245
  # class Dense
231
246
  全結合レイヤーを扱うクラスです。
@@ -254,15 +269,6 @@ nilを指定すると、Zerosイニシャライザーが使用されます。
254
269
  * Float weight_decay: 0
255
270
  重み減衰の係数を設定します。
256
271
 
257
- ## override def forward(x)
258
- ノードを順方向に伝搬します。
259
-
260
- ## override def backward(dout)
261
- ノードを逆方向に伝搬します。
262
-
263
- ## override def shape
264
- [ノード数]をshapeとして返却します。
265
-
266
272
 
267
273
  # class Conv2D < HasParamLayer
268
274
  畳み込みレイヤーを扱うクラスです。
@@ -289,18 +295,6 @@ nilを指定すると、RandomNormalイニシャライザーが使用されま
289
295
  * Float weight_decay: 0
290
296
  重み減衰を行うL2正則化項の強さを設定します。
291
297
 
292
- ## override def init(model)
293
- モデルのコンパイル時に、レイヤーを初期化するために使用されます。
294
-
295
- ## override def forward(x)
296
- イメージにフィルターを適用して順方向に伝搬します。
297
-
298
- ## override def backward(dout)
299
- フィルターが適用されたイメージを変換して、逆方向に伝搬します。
300
-
301
- ## override def shape
302
- 畳み込み後のイメージの次元を返します。
303
-
304
298
 
305
299
  # class MaxPool2D < Layer
306
300
  maxプーリングを行うレイヤーです。
@@ -318,32 +312,10 @@ maxプーリングを行うレイヤーです。
318
312
  * Integer padding: 0
319
313
  イメージに対してゼロパディングを行う単位を指定します。
320
314
 
321
- ## override def init(model)
322
- モデルのコンパイル時に、レイヤーを初期化するために使用されます。
323
-
324
- ## override def forward(x)
325
- イメージにプーリングを行い、順方向に伝搬します。
326
-
327
- ## override def backward(dout)
328
- プーリングされたイメージを変換し、逆方向に伝搬します。
329
-
330
- ## override def shape
331
- プーリング後のイメージのshapeを返します。
332
-
333
315
 
334
316
  # class Flatten
335
317
  N次元のデータを平坦化します。
336
318
 
337
- ## 【Instance methods】
338
- ## override def forward(x)
339
- データを平坦化して、順方向に伝搬します。
340
-
341
- ## override def backward(dout)
342
- データを元の形状に戻し、逆方向に伝搬します。
343
-
344
- ## override def shape
345
- 前レイヤーの形状を平坦化して返します。
346
-
347
319
 
348
320
  # class Reshape < Layer
349
321
  データの形状を変更します。
@@ -355,11 +327,6 @@ N次元のデータを平坦化します。
355
327
  * Array<Integer> shape
356
328
  データの形状を変更するshapeです。
357
329
 
358
- ## override def forward(x)
359
- データをコンストラクタで指定したshapeにreshapeして、順方向に伝搬します。
360
-
361
- ## override def backward(dout)
362
- データを元のshapeにreshapeして、逆方向に伝搬します。
363
330
 
364
331
  # class OutputLayer < Layer
365
332
  出力層に該当するレイヤーです。出力層の活性化関数は、全てこのクラスを継承する必要があります。
@@ -380,14 +347,6 @@ SFloat y
380
347
  ### return
381
348
  損失関数の値。
382
349
 
383
- ## def ridge
384
- L2正則化係数を用いて、L2正則化項の値を計算して取得します。
385
- ### arguments
386
- なし。
387
- ### return
388
- SFloat
389
- L2正則化項の値を取得します。
390
-
391
350
 
392
351
  # class Dropout
393
352
  学習の際に、一部のノードを非活性化させるクラスです。
@@ -398,135 +357,49 @@ L2正則化項の値を取得します。
398
357
  * Float dropout_ration
399
358
  ノードを非活性にする割合。
400
359
 
401
- ## abstruct def forward(x)
402
- 一部のノードを非活性にした上で、順方向に伝搬します。
403
-
404
- ## abstruct def backward(dout)
405
- 一部の非活性のノード以外の全てのノードを逆方向に伝搬します。
406
360
 
407
361
  # class BatchNormalization < HasParamLayer
408
362
  ミニバッチ単位でのデータの正規化を行います。
409
363
 
410
- ## override def forward(x)
411
- 正規化したデータを順方向に伝搬します。
412
-
413
- ## override def backward(dout)
414
- 正規化したデータを微分して、逆方向に伝搬します。
415
364
 
416
365
  # module Activations
417
366
  活性化関数のレイヤーの名前空間をなすモジュールです。
418
367
 
419
- # module SigmoidFunction
420
- シグモイド関数を提供するモジュールです。
421
-
422
- ## def forward(x)
423
- シグモイド関数の値を順方向に伝搬します。
424
- ### arguments
425
- SFloat x
426
- シグモイド関数の引数。
427
- ### return
428
- SFloat
429
- シグモイド関数の戻り値
430
-
431
368
 
432
369
  # class Sigmoid < Layer
433
- ## include SigmoidFunction
434
370
  シグモイド関数のレイヤーです。
435
371
 
436
- ## override def forward(x)
437
- シグモイド関数の値を順方向に伝搬します。
438
-
439
- ## def backward(dout)
440
- ### arguments
441
- SFloat dout
442
- シグモイド関数の導関数を適用した値を逆伝搬する。
443
- ### return
444
- SFloat
445
- シグモイド関数の導関数を適用した逆伝搬の値。
446
-
447
372
 
448
373
  # class Tanh < Layer
449
374
  tanh関数のレイヤーです。
450
- ## def forward(x)
451
- tanh関数の値を順方向に伝搬します。
452
- ### arguments
453
- SFloat x
454
- tanh関数の引数。
455
- ### return
456
- SFloat
457
- tanh関数の戻り値
458
-
459
- ## def backward(dout)
460
- ### arguments
461
- SFloat dout
462
- tanh関数の導関数を適用した値を逆伝搬する。
463
- ### return
464
- SFloat
465
- tanh関数の導関数を適用した逆伝搬の値。
466
375
 
467
376
 
468
377
  # class ReLU < Layer
469
378
  ランプ関数のレイヤーです。
470
- ## def forward(x)
471
- ランプ関数の値を順方向に伝搬します。
472
- ### arguments
473
- SFloat x
474
- ランプ関数の引数。
475
- ### return
476
- SFloat
477
- ランプ関数の戻り値
478
-
479
- ## def backward(dout)
480
- ### arguments
481
- SFloat dout
482
- ランプ関数の導関数を適用した値を逆伝搬する。
483
- ### return
484
- SFloat
485
- ランプ関数の導関数を適用した逆伝搬の値。
486
379
 
487
380
 
488
381
  # class LeakyReLU < Layer
489
382
  LeakyReLU関数のレイヤーです。
490
- ## def forward(x)
491
- LeakyReLU関数の値を順方向に伝搬します。
492
- ### arguments
493
- SFloat x
494
- LeakyReLU関数の引数。
495
- ### return
496
- SFloat
497
- LeakyReLU関数の戻り値
498
383
 
499
- ## def backward(dout)
384
+ ## 【Instance methods】
385
+
386
+ ## def initialize(alpha)
387
+ コンストラクタ。
500
388
  ### arguments
501
- SFloat dout
502
- LeakyReLU関数の導関数を適用した値を逆伝搬する。
503
- ### return
504
- SFloat
505
- LeakyReLU関数の導関数を適用した逆伝搬の値。
389
+ * Float alpha
390
+ 出力値が負のときの傾き。
506
391
 
507
392
 
508
393
  # class IdentityWithLoss < OutputLayer
509
394
  恒等関数と二乗誤差関数を合わせた出力層のレイヤーです。
510
- ## override def forward(x)
511
- データをそのまま順方向に伝搬します。
512
- ## override def backward(y)
513
- 恒等関数と二乗誤差関数を合わせたものを微分した導関数を用いて、教師データの出力データを逆方向に伝搬します。
514
395
 
515
396
 
516
397
  # class SoftmaxWithLoss < OutputLayer
517
398
  ソフトマックス関数とクロスエントロピー誤差関数を合わせた出力層のレイヤーです。
518
- ## override def forward(x)
519
- ソフトマックス関数の値を順方向に伝搬します。
520
- ## override def backward(y)
521
- ソフトマックス関数とクロスエントロピー誤差関数を合わせたものを微分した導関数を用いて、教師データの出力データを逆方向に伝搬します。
522
399
 
523
400
 
524
401
  # class SigmoidWithLoss < OutputLayer
525
402
  シグモイド関数とバイナリクロスエントロピー誤差関数を合わせた出力層のレイヤーです。
526
- ## override def forward(x)
527
- シグモイド関数の値を順方向に伝搬します。
528
- ## override def backward(y)
529
- シグモイド関数とバイナリクロスエントロピー誤差関数を合わせたものを微分した導関数を用いて、教師データの出力データを逆方向に伝搬します。
530
403
 
531
404
 
532
405
  # module Initializers
@@ -550,36 +423,25 @@ LeakyReLU関数の導関数を適用した逆伝搬の値。
550
423
  # class Zeros < Initializer
551
424
  パラメータを0で初期化します。
552
425
 
553
- ## override def init_param(layer, param_key)
554
- レイヤーの持つパラメータを0で初期化します。
555
426
 
556
427
  # class RandomNormal < Initializer
557
428
  パラメータを正規分布による乱数で初期化します。
558
429
 
559
430
  ## def initialize(mean = 0, std = 0.05)
560
431
  ### arguments
561
- Float mean = 0
562
- 正規分布の平均。
563
- Float std = 0.05
564
- 正規分布の分散。
565
-
566
- ## override def init_param(layer, param_key)
567
- レイヤーの持つパラメータを正規分布による乱数で初期化します。
432
+ * Float mean = 0
433
+ 正規分布の平均。
434
+ * Float std = 0.05
435
+ 正規分布の分散。
568
436
 
569
437
 
570
438
  # class Xavier < Initializer
571
439
  パラメータをXavierの初期値で初期化します。
572
440
 
573
- ## override def init_param(layer, param_key)
574
- レイヤーの持つパラメータをXavierの初期値で初期化します。
575
-
576
441
 
577
442
  # class He < Initializer
578
443
  パラメータをHeの初期値で初期化します。
579
444
 
580
- ## override def init_param(layer, param_key)
581
- レイヤーの持つパラメータをHeの初期値で初期化します。
582
-
583
445
 
584
446
  # module Optimizers
585
447
  全てのOptimizerの名前空間をなすモジュールです。
@@ -599,14 +461,14 @@ Float learning_rate
599
461
  ## def initialize(learning_rate)
600
462
  コンストラクタ。
601
463
  ### arguments
602
- Float learning_rate
603
- Optimizerの学習率。
464
+ * Float learning_rate
465
+ Optimizerの学習率。
604
466
 
605
467
  ## abstruct def update(layer)
606
- layerのgradsを元に、layerのparamsを更新します。
468
+ layerのgradsを元に、layerのparamsを更新します。全てのOptimizerを継承するクラスは、このメソッドを実装する必要があります。
607
469
  ### arguments
608
- Layer layer
609
- paramsを更新するレイヤー。
470
+ * Layer layer
471
+ paramsを更新するレイヤー。
610
472
  ### return
611
473
  なし。
612
474
 
@@ -622,13 +484,13 @@ Float momentum
622
484
 
623
485
  ## 【Instance methods】
624
486
 
625
- ## override def initialize(learning_rate = 0.01, momentum: 0)
487
+ ## def initialize(learning_rate = 0.01, momentum: 0)
626
488
  コンストラクタ。
627
489
  ### arguments
628
- Float learning_rate
629
- 学習率。
630
- Float momentum
631
- モーメンタム係数。
490
+ * Float learning_rate
491
+ 学習率。
492
+ * Float momentum
493
+ モーメンタム係数。
632
494
 
633
495
 
634
496
  # class AdaGrad < Optimizer
@@ -644,6 +506,16 @@ RMSPropによるオプティマイザです。
644
506
  Float muse
645
507
  指数平均移動のための係数。
646
508
 
509
+ ## 【Instance methods】
510
+
511
+ ## def initialize(learning_rate = 0.001, muse = 0.9)
512
+ コンストラクタ。
513
+ ### arguments
514
+ * Float learning_rate
515
+ 学習率。
516
+ * Float muse
517
+ 指数平均移動のための係数。
518
+
647
519
 
648
520
  # class Adam < Optimizer
649
521
  Adamによるオプティマイザです。
@@ -658,6 +530,16 @@ Float beta1
658
530
  Float beta2
659
531
  指数平均移動のための係数2。
660
532
 
533
+ ## 【Instance methods】
534
+
535
+ ## def initialize(learning_rate = 0.001, beta1 = 0.9, beta2 = 0.999)
536
+ コンストラクタ。
537
+ ### arguments
538
+ * Float beta1
539
+ 指数平均移動のための係数1。
540
+ * Float beta2
541
+ 指数平均移動のための係数2。
542
+
661
543
 
662
544
  # module Util
663
545
  ユーティリティ関数を提供します。
@@ -667,12 +549,12 @@ Float beta2
667
549
  ## def self.get_minibatch(x, y, batch_size)
668
550
  batch_size分のミニバッチを取得します。
669
551
  ### arguments
670
- SFloat x
671
- 教師データの入力データ。
672
- SFloat y
673
- 教師データの出力データ。
674
- Integer batch_size
675
- ミニバッチのサイズ。
552
+ * SFloat x
553
+ 教師データの入力データ。
554
+ * SFloat y
555
+ 教師データの出力データ。
556
+ * Integer batch_size
557
+ ミニバッチのサイズ。
676
558
  ### return
677
559
  Array
678
560
  [xのミニバッチ, yのミニバッチ]の形式の配列を返します。
@@ -680,23 +562,12 @@ Array
680
562
  ## def self.to_categorical(y, num_classes, type = nil)
681
563
  ラベルをnum_classesのベクトルにカテゴライズします。
682
564
  ### arguments
683
- SFloat y
684
- 教師データの出力データ。
685
- Integer num_classes
686
- カテゴライズするクラス数。
687
- NArray narray_type = nil
688
- カテゴライズしたNArrayデータの型。nilを指定すると、yの型を使用します。
565
+ * SFloat y
566
+ 教師データの出力データ。
567
+ * Integer num_classes
568
+ カテゴライズするクラス数。
569
+ * NArray narray_type = nil
570
+ カテゴライズしたNArrayデータの型。nilを指定すると、yの型を使用します。
689
571
  ### return
690
572
  NArray
691
573
  カテゴライズされたNArrayのインスタンス。
692
-
693
- ## def self.numerical_grad(x, func)
694
- 引数で渡された関数を数値微分します。
695
- ### arguments
696
- SFloat x
697
- funcの引数。
698
- Proc|Method func
699
- 数値微分を行う対象の関数。
700
- ### return
701
- SFloat
702
- 数値微分した結果の値。
@@ -50,13 +50,19 @@ module DNN
50
50
 
51
51
 
52
52
  class LeakyReLU < Layer
53
+ include Numo
54
+
53
55
  def initialize(alpha = 0.3)
54
56
  @alpha = alpha
55
57
  end
56
58
 
59
+ def self.load_hash(hash)
60
+ self.new(hash[:alpha])
61
+ end
62
+
57
63
  def forward(x)
58
64
  @x = x.clone
59
- a = Numo::SFloat.ones(x.shape)
65
+ a = SFloat.ones(x.shape)
60
66
  a[x <= 0] = @alpha
61
67
  x * a
62
68
  end
@@ -66,6 +72,10 @@ module DNN
66
72
  @x[@x <= 0] = @alpha
67
73
  dout * @x
68
74
  end
75
+
76
+ def to_hash
77
+ {name: self.class.name, alpha: alpha}
78
+ end
69
79
  end
70
80
 
71
81
 
@@ -79,7 +89,8 @@ module DNN
79
89
  end
80
90
 
81
91
  def loss(y)
82
- 0.5 * ((@out - y) ** 2).sum / @model.batch_size + ridge
92
+ batch_size = y.shape[0]
93
+ 0.5 * ((@out - y) ** 2).sum / batch_size + ridge
83
94
  end
84
95
  end
85
96
 
@@ -94,7 +105,8 @@ module DNN
94
105
  end
95
106
 
96
107
  def loss(y)
97
- -(y * NMath.log(@out + 1e-7)).sum / @model.batch_size + ridge
108
+ batch_size = y.shape[0]
109
+ -(y * NMath.log(@out + 1e-7)).sum / batch_size + ridge
98
110
  end
99
111
  end
100
112
 
@@ -108,7 +120,8 @@ module DNN
108
120
  end
109
121
 
110
122
  def loss(y)
111
- -(y * NMath.log(@out + 1e-7) + (1 - y) * NMath.log(1 - @out + 1e-7)).sum / @model.batch_size + ridge
123
+ batch_size = y.shape[0]
124
+ -(y * NMath.log(@out + 1e-7) + (1 - y) * NMath.log(1 - @out + 1e-7)).sum / batch_size + ridge
112
125
  end
113
126
  end
114
127
 
@@ -5,6 +5,10 @@ module DNN
5
5
  def init_param(layer, param_key, param)
6
6
  layer.params[param_key] = param
7
7
  end
8
+
9
+ def to_hash
10
+ {name: self.class.name}
11
+ end
8
12
  end
9
13
 
10
14
 
@@ -16,14 +20,22 @@ module DNN
16
20
 
17
21
 
18
22
  class RandomNormal < Initializer
23
+ def self.load_hash(hash)
24
+ self.new(hash[:mean], hash[:std])
25
+ end
26
+
19
27
  def initialize(mean = 0, std = 0.05)
20
28
  @mean = mean
21
29
  @std = std
22
30
  end
23
-
31
+
24
32
  def init_param(layer, param_key)
25
33
  super(layer, param_key, layer.params[param_key].rand_norm(@mean, @std))
26
34
  end
35
+
36
+ def to_hash
37
+ {name: self.class.name, mean: @mean, std: @std}
38
+ end
27
39
  end
28
40
 
29
41
 
@@ -20,6 +20,11 @@ module DNN
20
20
  def shape
21
21
  prev_layer.shape
22
22
  end
23
+
24
+ #Layer to a hash.
25
+ def to_hash
26
+ {name: self.class.name}
27
+ end
23
28
 
24
29
  #Get the previous layer.
25
30
  def prev_layer
@@ -56,7 +61,11 @@ module DNN
56
61
 
57
62
  class InputLayer < Layer
58
63
  attr_reader :shape
59
-
64
+
65
+ def self.load_hash(hash)
66
+ self.new(hash[:shape])
67
+ end
68
+
60
69
  def initialize(dim_or_shape)
61
70
  @shape = dim_or_shape.is_a?(Array) ? dim_or_shape : [dim_or_shape]
62
71
  end
@@ -68,6 +77,10 @@ module DNN
68
77
  def backward(dout)
69
78
  dout
70
79
  end
80
+
81
+ def to_hash
82
+ {name: self.class.name, shape: @shape}
83
+ end
71
84
  end
72
85
 
73
86
 
@@ -87,6 +100,13 @@ module DNN
87
100
  @bias_initializer = (bias_initializer || Zeros.new)
88
101
  @weight_decay = weight_decay
89
102
  end
103
+
104
+ def self.load_hash(hash)
105
+ self.new(hash[:num_nodes],
106
+ weight_initializer: Util.load_hash(hash[:weight_initializer]),
107
+ bias_initializer: Util.load_hash(hash[:bias_initializer]),
108
+ weight_decay: hash[:weight_decay])
109
+ end
90
110
 
91
111
  def forward(x)
92
112
  @x = x
@@ -106,6 +126,16 @@ module DNN
106
126
  def shape
107
127
  [@num_nodes]
108
128
  end
129
+
130
+ def to_hash
131
+ {
132
+ name: self.class.name,
133
+ num_nodes: @num_nodes,
134
+ weight_initializer: @weight_initializer.to_hash,
135
+ bias_initializer: @bias_initializer.to_hash,
136
+ weight_decay: @weight_decay,
137
+ }
138
+ end
109
139
 
110
140
  private
111
141
 
@@ -178,8 +208,17 @@ module DNN
178
208
  @weight_initializer = (weight_initializer || RandomNormal.new)
179
209
  @bias_initializer = (bias_initializer || Zeros.new)
180
210
  @strides = strides
181
- @weight_decay = weight_decay
182
211
  @padding = padding
212
+ @weight_decay = weight_decay
213
+ end
214
+
215
+ def self.load_hash(hash)
216
+ Conv2D.new(hash[:num_filters], hash[:filter_height], hash[:filter_width],
217
+ weight_initializer: Util.load_hash(hash[:weight_initializer]),
218
+ bias_initializer: Util.load_hash(hash[:bias_initializer]),
219
+ strides: hash[:strides],
220
+ padding: hash[:padding],
221
+ weight_decay: hash[:weight_decay])
183
222
  end
184
223
 
185
224
  def init(model)
@@ -213,6 +252,20 @@ module DNN
213
252
  def shape
214
253
  [@num_filters, @out_height, @out_width]
215
254
  end
255
+
256
+ def to_hash
257
+ {
258
+ name: self.class.name,
259
+ num_filters: @num_filters,
260
+ filter_height: @filter_height,
261
+ filter_width: @filter_width,
262
+ weight_initializer: @weight_initializer.to_hash,
263
+ bias_initializer: @bias_initializer.to_hash,
264
+ strides: @strides,
265
+ padding: @padding,
266
+ weight_decay: @weight_decay,
267
+ }
268
+ end
216
269
 
217
270
  private
218
271
 
@@ -264,6 +317,16 @@ module DNN
264
317
  def shape
265
318
  [@num_channel, @out_height, @out_width]
266
319
  end
320
+
321
+ def to_hash
322
+ {
323
+ name: self.class.name,
324
+ pool_height: @pool_height,
325
+ pool_width: @pool_width,
326
+ strides: @strides,
327
+ padding: @padding,
328
+ }
329
+ end
267
330
  end
268
331
 
269
332
 
@@ -291,6 +354,10 @@ module DNN
291
354
  @x_shape = nil
292
355
  end
293
356
 
357
+ def self.load_hash(hash)
358
+ self.new(hash[:shape])
359
+ end
360
+
294
361
  def forward(x)
295
362
  @x_shape = x.shape
296
363
  x.reshape(*@shape)
@@ -299,6 +366,10 @@ module DNN
299
366
  def backward(dout)
300
367
  dout.reshape(@x_shape)
301
368
  end
369
+
370
+ def to_hash
371
+ {name: self.class.name, shape: @shape}
372
+ end
302
373
  end
303
374
 
304
375
 
@@ -317,6 +388,10 @@ module DNN
317
388
  @dropout_ratio = dropout_ratio
318
389
  @mask = nil
319
390
  end
391
+
392
+ def self.load(hash)
393
+ self.new(hash[:dropout_ratio])
394
+ end
320
395
 
321
396
  def forward(x)
322
397
  if @model.training
@@ -346,22 +421,23 @@ module DNN
346
421
  end
347
422
 
348
423
  def backward(dout)
424
+ batch_size = dout.shape[0]
349
425
  @grads[:beta] = dout.sum(0)
350
426
  @grads[:gamma] = (@xn * dout).sum(0)
351
427
  dxn = @params[:gamma] * dout
352
428
  dxc = dxn / @std
353
429
  dstd = -((dxn * @xc) / (@std**2)).sum(0)
354
430
  dvar = 0.5 * dstd / @std
355
- dxc += (2.0 / @model.batch_size) * @xc * dvar
431
+ dxc += (2.0 / batch_size) * @xc * dvar
356
432
  dmean = dxc.sum(0)
357
- dxc - dmean / @model.batch_size
433
+ dxc - dmean / batch_size
358
434
  end
359
435
 
360
436
  private
361
437
 
362
438
  def init_params
363
- @params[:gamma] = 1
364
- @params[:beta] = 0
439
+ @params[:gamma] = SFloat.ones(*shape)
440
+ @params[:beta] = SFloat.zeros(*shape)
365
441
  end
366
442
  end
367
443
  end
@@ -1,25 +1,65 @@
1
+ require "json"
2
+ require "base64"
3
+
1
4
  module DNN
2
5
  class Model
3
- attr_reader :layers
6
+ include Numo
7
+
8
+ attr_accessor :layers
4
9
  attr_reader :optimizer
5
10
  attr_reader :batch_size
6
11
  attr_reader :training
7
12
 
8
- def self.load(file_name)
9
- Marshal.load(File.binread(file_name))
10
- end
11
-
12
13
  def initialize
13
14
  @layers = []
14
15
  @optimizer = nil
15
16
  @batch_size = nil
16
17
  end
18
+
19
+ def self.load(file_name)
20
+ Marshal.load(File.binread(file_name))
21
+ end
22
+
23
+ def self.load_json(json_str)
24
+ hash = JSON.parse(json_str, symbolize_names: true)
25
+ model = self.new
26
+ model.layers = hash[:layers].map { |hash_layer| Util.load_hash(hash_layer) }
27
+ model.compile(Util.load_hash(hash[:optimizer]))
28
+ model
29
+ end
30
+
31
+ def load_json_params(json_str)
32
+ has_param_layers_params = JSON.parse(json_str, symbolize_names: true)
33
+ has_param_layers_index = 0
34
+ @layers.each do |layer|
35
+ next unless layer.is_a?(HasParamLayer)
36
+ hash_params = has_param_layers_params[has_param_layers_index]
37
+ hash_params.each do |key, param|
38
+ layer.params[key] = SFloat.cast(param)
39
+ end
40
+ has_param_layers_index += 1
41
+ end
42
+ end
17
43
 
18
44
  def save(file_name)
19
45
  dir_name = file_name.match(%r`(.*)/.+$`)[1]
20
46
  Dir.mkdir(dir_name) unless Dir.exist?(dir_name)
21
47
  File.binwrite(file_name, Marshal.dump(self))
22
48
  end
49
+
50
+ def to_json
51
+ hash_layers = @layers.map { |layer| layer.to_hash }
52
+ hash = {version: VERSION, layers: hash_layers, optimizer: @optimizer.to_hash}
53
+ JSON.dump(hash)
54
+ end
55
+
56
+ def params_to_json
57
+ has_param_layers = @layers.select { |layer| layer.is_a?(HasParamLayer) }
58
+ has_param_layers_params = has_param_layers.map do |layer|
59
+ layer.params.map { |key, param| [key, param.to_a] }.to_h
60
+ end
61
+ JSON.dump(has_param_layers_params)
62
+ end
23
63
 
24
64
  def <<(layer)
25
65
  unless layer.is_a?(Layers::Layer)
@@ -11,6 +11,10 @@ module DNN
11
11
 
12
12
  #Update layer has params.
13
13
  def update(layer) end
14
+
15
+ def to_hash
16
+ {name: self.class.name, learning_rate: @learning_rate}
17
+ end
14
18
  end
15
19
 
16
20
 
@@ -22,6 +26,10 @@ module DNN
22
26
  @momentum = momentum
23
27
  @amounts = {}
24
28
  end
29
+
30
+ def self.load_hash(hash)
31
+ self.new(hash[:learning_rate], hash[:momentum])
32
+ end
25
33
 
26
34
  def update(layer)
27
35
  amount = if @amounts[layer]
@@ -39,6 +47,14 @@ module DNN
39
47
  layer.params[key] -= amount[key]
40
48
  end
41
49
  end
50
+
51
+ def to_hash
52
+ {
53
+ name: self.class.name,
54
+ learning_rate: @learning_rate,
55
+ momentum: @momentum,
56
+ }
57
+ end
42
58
  end
43
59
 
44
60
 
@@ -47,6 +63,10 @@ module DNN
47
63
  super(learning_rate)
48
64
  @g = {}
49
65
  end
66
+
67
+ def self.load_hash(hash)
68
+ @learning_rate = hash[:learning_rate]
69
+ end
50
70
 
51
71
  def update(layer)
52
72
  @g[layer] ||= {}
@@ -67,6 +87,10 @@ module DNN
67
87
  @muse = muse
68
88
  @g = {}
69
89
  end
90
+
91
+ def self.load_hash(hash)
92
+ self.new(hash[:learning_rate], hash[:muse])
93
+ end
70
94
 
71
95
  def update(layer)
72
96
  @g[layer] ||= {}
@@ -76,6 +100,14 @@ module DNN
76
100
  layer.params[key] -= (@learning_rate / NMath.sqrt(@g[layer][key] + 1e-7)) * layer.grads[key]
77
101
  end
78
102
  end
103
+
104
+ def to_hash
105
+ {
106
+ name: self.class.name,
107
+ learning_rate: @learning_rate,
108
+ muse: @muse,
109
+ }
110
+ end
79
111
  end
80
112
 
81
113
 
@@ -94,6 +126,10 @@ module DNN
94
126
  @v = {}
95
127
  end
96
128
 
129
+ def self.load_hash(hash)
130
+ self.new(hash[:learning_rate], hash[:beta1], hash[:beta2])
131
+ end
132
+
97
133
  def update(layer)
98
134
  @iter += 1
99
135
  @m[layer] ||= {}
@@ -107,6 +143,15 @@ module DNN
107
143
  layer.params[key] -= lr * @m[layer][key] / NMath.sqrt(@v[layer][key] + 1e-7)
108
144
  end
109
145
  end
146
+
147
+ def to_hash
148
+ {
149
+ name: self.class.name,
150
+ learning_rate: @learning_rate,
151
+ beta1: @beta1,
152
+ beta2: @beta2,
153
+ }
154
+ end
110
155
  end
111
156
 
112
157
  end
@@ -20,5 +20,14 @@ module DNN
20
20
  def self.numerical_grad(x, func)
21
21
  (func.(x + 1e-7) - func.(x)) / 1e-7
22
22
  end
23
+
24
+ #Convert hash to an object.
25
+ def self.load_hash(hash)
26
+ dnn_class = DNN.const_get(hash[:name])
27
+ if dnn_class.respond_to?(:load_hash)
28
+ return dnn_class.load_hash(hash)
29
+ end
30
+ dnn_class.new
31
+ end
23
32
  end
24
33
  end
@@ -1,3 +1,3 @@
1
1
  module DNN
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{ruby deep learning library.}
13
13
  spec.description = %q{ruby-dnn is a ruby deep learning library.}
14
- spec.homepage = "https://github.com/unagiootoro/dnn.git"
14
+ spec.homepage = "https://github.com/unagiootoro/ruby-dnn.git"
15
15
  spec.license = "MIT"
16
16
  spec.extensions = ["lib/dnn/ext/mnist/extconf.rb", "lib/dnn/ext/cifar10/extconf.rb", "lib/dnn/ext/image_io/extconf.rb"]
17
17
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-dnn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - unagiootoro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-04 00:00:00.000000000 Z
11
+ date: 2018-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -212,7 +212,7 @@ files:
212
212
  - lib/dnn/lib/image_io.rb
213
213
  - lib/dnn/lib/mnist.rb
214
214
  - ruby-dnn.gemspec
215
- homepage: https://github.com/unagiootoro/dnn.git
215
+ homepage: https://github.com/unagiootoro/ruby-dnn.git
216
216
  licenses:
217
217
  - MIT
218
218
  metadata: {}