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