lib/dnn/core/layers.rb in ruby-dnn-0.1.5 vs lib/dnn/core/layers.rb in ruby-dnn-0.1.6
- old
+ new
@@ -18,10 +18,15 @@
#Get the shape of the layer.
def shape
prev_layer.shape
end
+
+ #Layer to a hash.
+ def to_hash
+ {name: self.class.name}
+ end
#Get the previous layer.
def prev_layer
@model.layers[@model.layers.index(self) - 1]
end
@@ -54,11 +59,15 @@
end
class InputLayer < Layer
attr_reader :shape
-
+
+ def self.load_hash(hash)
+ self.new(hash[:shape])
+ end
+
def initialize(dim_or_shape)
@shape = dim_or_shape.is_a?(Array) ? dim_or_shape : [dim_or_shape]
end
def forward(x)
@@ -66,10 +75,14 @@
end
def backward(dout)
dout
end
+
+ def to_hash
+ {name: self.class.name, shape: @shape}
+ end
end
class Dense < HasParamLayer
include Initializers
@@ -85,10 +98,17 @@
@num_nodes = num_nodes
@weight_initializer = (weight_initializer || RandomNormal.new)
@bias_initializer = (bias_initializer || Zeros.new)
@weight_decay = weight_decay
end
+
+ def self.load_hash(hash)
+ self.new(hash[:num_nodes],
+ weight_initializer: Util.load_hash(hash[:weight_initializer]),
+ bias_initializer: Util.load_hash(hash[:bias_initializer]),
+ weight_decay: hash[:weight_decay])
+ end
def forward(x)
@x = x
@x.dot(@params[:weight]) + @params[:bias]
end
@@ -104,10 +124,20 @@
end
def shape
[@num_nodes]
end
+
+ def to_hash
+ {
+ name: self.class.name,
+ num_nodes: @num_nodes,
+ weight_initializer: @weight_initializer.to_hash,
+ bias_initializer: @bias_initializer.to_hash,
+ weight_decay: @weight_decay,
+ }
+ end
private
def init_params
num_prev_nodes = prev_layer.shape[0]
@@ -176,13 +206,22 @@
@filter_height = filter_height
@filter_width = filter_width
@weight_initializer = (weight_initializer || RandomNormal.new)
@bias_initializer = (bias_initializer || Zeros.new)
@strides = strides
- @weight_decay = weight_decay
@padding = padding
+ @weight_decay = weight_decay
end
+
+ def self.load_hash(hash)
+ Conv2D.new(hash[:num_filters], hash[:filter_height], hash[:filter_width],
+ weight_initializer: Util.load_hash(hash[:weight_initializer]),
+ bias_initializer: Util.load_hash(hash[:bias_initializer]),
+ strides: hash[:strides],
+ padding: hash[:padding],
+ weight_decay: hash[:weight_decay])
+ end
def init(model)
super
prev_height, prev_width = prev_layer.shape[1], prev_layer.shape[2]
@out_height = (prev_height + @padding * 2 - @filter_height) / @strides[0] + 1
@@ -211,10 +250,24 @@
end
def shape
[@num_filters, @out_height, @out_width]
end
+
+ def to_hash
+ {
+ name: self.class.name,
+ num_filters: @num_filters,
+ filter_height: @filter_height,
+ filter_width: @filter_width,
+ weight_initializer: @weight_initializer.to_hash,
+ bias_initializer: @bias_initializer.to_hash,
+ strides: @strides,
+ padding: @padding,
+ weight_decay: @weight_decay,
+ }
+ end
private
def init_params
num_prev_filter = prev_layer.shape[0]
@@ -262,10 +315,20 @@
end
def shape
[@num_channel, @out_height, @out_width]
end
+
+ def to_hash
+ {
+ name: self.class.name,
+ pool_height: @pool_height,
+ pool_width: @pool_width,
+ strides: @strides,
+ padding: @padding,
+ }
+ end
end
class Flatten < Layer
def forward(x)
@@ -289,18 +352,26 @@
def initialize(shape)
@shape = shape
@x_shape = nil
end
+ def self.load_hash(hash)
+ self.new(hash[:shape])
+ end
+
def forward(x)
@x_shape = x.shape
x.reshape(*@shape)
end
def backward(dout)
dout.reshape(@x_shape)
end
+
+ def to_hash
+ {name: self.class.name, shape: @shape}
+ end
end
class OutputLayer < Layer
private
@@ -315,10 +386,14 @@
class Dropout < Layer
def initialize(dropout_ratio)
@dropout_ratio = dropout_ratio
@mask = nil
end
+
+ def self.load(hash)
+ self.new(hash[:dropout_ratio])
+ end
def forward(x)
if @model.training
@mask = SFloat.ones(*x.shape).rand < @dropout_ratio
x[@mask] = 0
@@ -344,25 +419,26 @@
@xn = @xc / @std
@params[:gamma] * @xn + @params[:beta]
end
def backward(dout)
+ batch_size = dout.shape[0]
@grads[:beta] = dout.sum(0)
@grads[:gamma] = (@xn * dout).sum(0)
dxn = @params[:gamma] * dout
dxc = dxn / @std
dstd = -((dxn * @xc) / (@std**2)).sum(0)
dvar = 0.5 * dstd / @std
- dxc += (2.0 / @model.batch_size) * @xc * dvar
+ dxc += (2.0 / batch_size) * @xc * dvar
dmean = dxc.sum(0)
- dxc - dmean / @model.batch_size
+ dxc - dmean / batch_size
end
private
def init_params
- @params[:gamma] = 1
- @params[:beta] = 0
+ @params[:gamma] = SFloat.ones(*shape)
+ @params[:beta] = SFloat.zeros(*shape)
end
end
end
end