rumale 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8823e97350be198c39b1896dc88978a47b526f1
4
- data.tar.gz: d65a2d3274d104eae9aa20dd97078159614783e1
3
+ metadata.gz: e97522eaf22db6c80513f8d69513b6aef7dc1a9f
4
+ data.tar.gz: a2c2d51a15465f5bac67bc0b60aef1c70067bba4
5
5
  SHA512:
6
- metadata.gz: 5f06921658636e7765edc7a71aa9df28bf6a5cd4b36706671b2bf3a75c55755d190e8ab4dc9801cf94a4034b04429a6f14d8978c0323a9a2a6bf5d34456aa2e5
7
- data.tar.gz: 74dfe7a75358e9e26da392dae39e71c1441a56c63ad51236db3bedfda4156f8cd86a1b69c40574e34b2db46fb8bdb9f22da60bde0a9423afa6849b11551a9494
6
+ metadata.gz: b04158c2f4247c58593dad54e1d8c79030aff2a3826032610b9d7afee73490843caa3c5636c86fc3fc3196ed45affdb2da17c7d926091f77c784f1970464c2a4
7
+ data.tar.gz: e75814bcbe3aa087f2a45a15790a180016147d9197442d5d329a6484d1baee8b4d2726265d640a3d47ada45189d6dfb3157f2fa5eec7e334824cf96bd8fba493
@@ -1,3 +1,12 @@
1
+ # 0.16.0
2
+ ## Breaking changes
3
+ - The meaning of the `max_iter` parameter of the multi-layer perceptron estimators
4
+ has been changed from the maximum number of iterations to the number of epochs.
5
+ The number of epochs is how many times the whole data is given to the training process.
6
+ As a future plan, similar changes will be applied to other estimators used stochastic gradient descent such as SVC and Lasso.
7
+ - [MLPClassifier](https://yoshoku.github.io/rumale/doc/Rumale/NeuralNetwork/MLPClassifier.html)
8
+ - [MLPRegressor](https://yoshoku.github.io/rumale/doc/Rumale/NeuralNetwork/MLPRegressor.html)
9
+
1
10
  # 0.15.0
2
11
  - Add feature extractor classes:
3
12
  - [HashVectorizer](https://yoshoku.github.io/rumale/doc/Rumale/FeatureExtraction/HashVectorizer.html)
@@ -74,6 +74,7 @@ require 'rumale/decomposition/factor_analysis'
74
74
  require 'rumale/decomposition/fast_ica'
75
75
  require 'rumale/manifold/tsne'
76
76
  require 'rumale/manifold/mds'
77
+ require 'rumale/neural_network/adam'
77
78
  require 'rumale/neural_network/base_mlp'
78
79
  require 'rumale/neural_network/mlp_regressor'
79
80
  require 'rumale/neural_network/mlp_classifier'
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rumale/base/base_estimator'
4
+
5
+ module Rumale
6
+ module NeuralNetwork
7
+ # @!visibility private
8
+ # This module consists of the classes that implement optimizers adaptively tuning learning rate.
9
+ module Optimizer
10
+ # @!visibility private
11
+ # Adam is a class that implements Adam optimizer.
12
+ #
13
+ # *Reference*
14
+ # - D P. Kingma and J. Ba, "Adam: A Method for Stochastic Optimization," Proc. ICLR'15, 2015.
15
+ class Adam
16
+ include Base::BaseEstimator
17
+
18
+ # @!visibility private
19
+ # Create a new optimizer with Adam
20
+ #
21
+ # @param learning_rate [Float] The initial value of learning rate.
22
+ # @param decay1 [Float] The smoothing parameter for the first moment.
23
+ # @param decay2 [Float] The smoothing parameter for the second moment.
24
+ def initialize(learning_rate: 0.001, decay1: 0.9, decay2: 0.999)
25
+ @params = {}
26
+ @params[:learning_rate] = learning_rate
27
+ @params[:decay1] = decay1
28
+ @params[:decay2] = decay2
29
+ @fst_moment = nil
30
+ @sec_moment = nil
31
+ @iter = 0
32
+ end
33
+
34
+ # @!visibility private
35
+ # Calculate the updated weight with Nadam adaptive learning rate.
36
+ #
37
+ # @param weight [Numo::DFloat] (shape: [n_features]) The weight to be updated.
38
+ # @param gradient [Numo::DFloat] (shape: [n_features]) The gradient for updating the weight.
39
+ # @return [Numo::DFloat] (shape: [n_feautres]) The updated weight.
40
+ def call(weight, gradient)
41
+ @fst_moment ||= Numo::DFloat.zeros(weight.shape)
42
+ @sec_moment ||= Numo::DFloat.zeros(weight.shape)
43
+
44
+ @iter += 1
45
+
46
+ @fst_moment = @params[:decay1] * @fst_moment + (1.0 - @params[:decay1]) * gradient
47
+ @sec_moment = @params[:decay2] * @sec_moment + (1.0 - @params[:decay2]) * gradient**2
48
+ nm_fst_moment = @fst_moment / (1.0 - @params[:decay1]**@iter)
49
+ nm_sec_moment = @sec_moment / (1.0 - @params[:decay2]**@iter)
50
+
51
+ weight - @params[:learning_rate] * nm_fst_moment / (nm_sec_moment**0.5 + 1e-8)
52
+ end
53
+
54
+ # Dump marshal data.
55
+ # @return [Hash] The marshal data.
56
+ # def marshal_dump
57
+ # { params: @params,
58
+ # fst_moment: @fst_moment,
59
+ # sec_moment: @sec_moment,
60
+ # iter: @iter }
61
+ # end
62
+
63
+ # Load marshal data.
64
+ # @return [nil]
65
+ # def marshal_load(obj)
66
+ # @params = obj[:params]
67
+ # @fst_moment = obj[:fst_moment]
68
+ # @sec_moment = obj[:sec_moment]
69
+ # @iter = obj[:iter]
70
+ # nil
71
+ # end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -177,13 +177,14 @@ module Rumale
177
177
  # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
178
178
  # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
179
179
  # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
180
- # @param max_iter [Integer] The maximum number of iterations.
180
+ # @param max_iter [Integer] The maximum number of epochs that indicates
181
+ # how many times the whole data is given to the training process.
181
182
  # @param batch_size [Intger] The size of the mini batches.
182
183
  # @param tol [Float] The tolerance of loss for terminating optimization.
183
184
  # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
184
185
  # @param random_seed [Integer] The seed value using to initialize the random generator.
185
186
  def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
186
- max_iter: 10000, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
187
+ max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
187
188
  @params = {}
188
189
  @params[:hidden_units] = hidden_units
189
190
  @params[:dropout_rate] = dropout_rate
@@ -203,7 +204,9 @@ module Rumale
203
204
  private
204
205
 
205
206
  def buld_network(n_inputs, n_outputs, srng = nil)
206
- adam = Rumale::Optimizer::Adam.new(learning_rate: @params[:learning_rate], decay1: @params[:decay1], decay2: @params[:decay2])
207
+ adam = Rumale::NeuralNetwork::Optimizer::Adam.new(
208
+ learning_rate: @params[:learning_rate], decay1: @params[:decay1], decay2: @params[:decay2]
209
+ )
207
210
  model = Model::Sequential.new
208
211
  n_units = [n_inputs, *@params[:hidden_units]]
209
212
  n_units.each_cons(2) do |n_in, n_out|
@@ -216,25 +219,25 @@ module Rumale
216
219
 
217
220
  def train(x, y, network, loss_func, srng = nil)
218
221
  class_name = self.class.to_s.split('::').last
219
-
220
222
  n_samples = x.shape[0]
221
- rand_ids = [*0...n_samples].shuffle(random: srng)
222
223
 
223
224
  @params[:max_iter].times do |t|
224
- # random sampling
225
- subset_ids = rand_ids.shift(@params[:batch_size])
226
- rand_ids.concat(subset_ids)
227
- sub_x = x[subset_ids, true].dup
228
- sub_y = y[subset_ids, true].dup
229
- # forward
230
- out, backward = network.forward(sub_x)
231
- # calc loss function
232
- loss, dout = loss_func.call(out, sub_y)
225
+ sample_ids = [*0...n_samples]
226
+ sample_ids.shuffle!(random: srng)
227
+ until (subset_ids = sample_ids.shift(@params[:batch_size])).empty?
228
+ # random sampling
229
+ sub_x = x[subset_ids, true].dup
230
+ sub_y = y[subset_ids, true].dup
231
+ # forward
232
+ out, backward = network.forward(sub_x)
233
+ # calc loss function
234
+ loss, dout = loss_func.call(out, sub_y)
235
+ break if loss < @params[:tol]
236
+ # backward
237
+ backward.call(dout)
238
+ end
233
239
  @n_iter = t + 1
234
- puts "[#{class_name}] Loss after #{@n_iter} iterations: #{loss}" if @params[:verbose] && (@n_iter % 10).zero?
235
- break if loss < @params[:tol]
236
- # backward
237
- backward.call(dout)
240
+ puts "[#{class_name}] Loss after #{@n_iter} epochs: #{loss}" if @params[:verbose]
238
241
  end
239
242
 
240
243
  network
@@ -40,13 +40,14 @@ module Rumale
40
40
  # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
41
41
  # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
42
42
  # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
43
- # @param max_iter [Integer] The maximum number of iterations.
43
+ # @param max_iter [Integer] The maximum number of epochs that indicates
44
+ # how many times the whole data is given to the training process.
44
45
  # @param batch_size [Intger] The size of the mini batches.
45
46
  # @param tol [Float] The tolerance of loss for terminating optimization.
46
47
  # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
47
48
  # @param random_seed [Integer] The seed value using to initialize the random generator.
48
49
  def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
49
- max_iter: 10000, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
50
+ max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
50
51
  check_params_type(Array, hidden_units: hidden_units)
51
52
  check_params_numeric(dropout_rate: dropout_rate, learning_rate: learning_rate, decay1: decay1, decay2: decay2,
52
53
  max_iter: max_iter, batch_size: batch_size, tol: tol)
@@ -35,13 +35,14 @@ module Rumale
35
35
  # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
36
36
  # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
37
37
  # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
38
- # @param max_iter [Integer] The maximum number of iterations.
38
+ # @param max_iter [Integer] The maximum number of epochs that indicates
39
+ # how many times the whole data is given to the training process.
39
40
  # @param batch_size [Intger] The size of the mini batches.
40
41
  # @param tol [Float] The tolerance of loss for terminating optimization.
41
42
  # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
42
43
  # @param random_seed [Integer] The seed value using to initialize the random generator.
43
44
  def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
44
- max_iter: 10000, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
45
+ max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
45
46
  check_params_type(Array, hidden_units: hidden_units)
46
47
  check_params_numeric(dropout_rate: dropout_rate, learning_rate: learning_rate, decay1: decay1, decay2: decay2,
47
48
  max_iter: max_iter, batch_size: batch_size, tol: tol)
@@ -3,5 +3,5 @@
3
3
  # Rumale is a machine learning library in Ruby.
4
4
  module Rumale
5
5
  # The version of Rumale you are using.
6
- VERSION = '0.15.0'
6
+ VERSION = '0.16.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rumale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-01 00:00:00.000000000 Z
11
+ date: 2020-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -233,6 +233,7 @@ files:
233
233
  - lib/rumale/nearest_neighbors/k_neighbors_classifier.rb
234
234
  - lib/rumale/nearest_neighbors/k_neighbors_regressor.rb
235
235
  - lib/rumale/nearest_neighbors/vp_tree.rb
236
+ - lib/rumale/neural_network/adam.rb
236
237
  - lib/rumale/neural_network/base_mlp.rb
237
238
  - lib/rumale/neural_network/mlp_classifier.rb
238
239
  - lib/rumale/neural_network/mlp_regressor.rb