lib/nn.rb in nn-2.0.1 vs lib/nn.rb in nn-2.1.0
- old
+ new
@@ -1,10 +1,10 @@
require "numo/narray"
require "json"
class NN
- VERSION = "2.0"
+ VERSION = "2.1"
include Numo
attr_accessor :weights
attr_accessor :biases
@@ -42,10 +42,14 @@
@training = true
init_layers
end
def self.load(file_name)
+ Marshal.load(File.binread(file_name))
+ end
+
+ def self.load_json(file_name)
json = JSON.parse(File.read(file_name))
nn = self.new(json["num_nodes"],
learning_rate: json["learning_rate"],
batch_size: json["batch_size"],
activation: json["activation"].map(&:to_sym),
@@ -148,10 +152,14 @@
forward(x, false)
end
end
def save(file_name)
+ File.binwrite(file_name, Marshal.dump(self))
+ end
+
+ def save_json(file_name)
json = {
"version" => VERSION,
"num_nodes" => @num_nodes,
"learning_rate" => @learning_rate,
"batch_size" => @batch_size,
@@ -238,12 +246,12 @@
end
end
def update_weight_and_bias
@layers.select{|layer| layer.is_a?(Affine)}.each.with_index do |layer, i|
- weight_amount = layer.d_weight.mean(0) * @learning_rate
- bias_amount = layer.d_bias.mean * @learning_rate
+ weight_amount = layer.d_weight * @learning_rate
+ bias_amount = layer.d_bias * @learning_rate
if @momentum > 0
weight_amount += @momentum * @weight_amounts[i]
@weight_amounts[i] = weight_amount
bias_amount += @momentum * @bias_amounts[i]
@bias_amounts[i] = bias_amount
@@ -253,12 +261,12 @@
end
end
def update_gamma_and_beta
@layers.select{|layer| layer.is_a?(BatchNorm)}.each.with_index do |layer, i|
- gamma_amount = layer.d_gamma.mean * @learning_rate
- beta_amount = layer.d_beta.mean * @learning_rate
+ gamma_amount = layer.d_gamma * @learning_rate
+ beta_amount = layer.d_beta * @learning_rate
if @momentum > 0
gamma_amount += @momentum * @gamma_amounts[i]
@gamma_amounts[i] = gamma_amount
beta_amount += @momentum * @beta_amounts[i]
@beta_amounts[i] = beta_amount
@@ -288,24 +296,26 @@
@x.dot(@nn.weights[@index]) + @nn.biases[@index]
end
def backward(dout)
x = @x.reshape(*@x.shape, 1)
- @d_weight = x.dot(dout.reshape(dout.shape[0], 1, dout.shape[1]))
+ @d_weight = x.dot(dout.reshape(dout.shape[0], 1, dout.shape[1])).mean(0)
if @nn.weight_decay > 0
dridge = @nn.weight_decay * @nn.weights[@index]
@d_weight += dridge
end
- @d_bias = dout
+ @d_bias = dout.mean
dout.dot(@nn.weights[@index].transpose)
end
end
class NN::Sigmoid
+ include Numo
+
def forward(x)
- @out = 1.0 / (1 + Numo::NMath.exp(-x))
+ @out = 1.0 / (1 + NMath.exp(-x))
end
def backward(dout)
dout * (1.0 - @out) * @out
end
@@ -326,12 +336,10 @@
end
end
class NN::Identity
- include Numo
-
def initialize(nn)
@nn = nn
end
def forward(x)
@@ -417,11 +425,11 @@
out = @nn.gammas[@index] * @xn + @nn.betas[@index]
out.reshape(*@x.shape)
end
def backward(dout)
- @d_beta = dout.sum(0)
- @d_gamma = (@xn * dout).sum(0)
+ @d_beta = dout.sum(0).mean
+ @d_gamma = (@xn * dout).sum(0).mean
dxn = @nn.gammas[@index] * dout
dxc = dxn / @std
dstd = -((dxn * @xc) / (@std ** 2)).sum(0)
dvar = 0.5 * dstd / @std
dxc += (2.0 / @nn.batch_size) * @xc * dvar