Class: DNN::Layers::BatchNormalization
Instance Attribute Summary collapse
#params, #trainable
Attributes inherited from Layer
#input_shape, #learning_phase
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Layer
#built?, #output_shape
Constructor Details
#initialize(axis: 0, momentum: 0.9, eps: 1e-7) ⇒ BatchNormalization
Returns a new instance of BatchNormalization.
19
20
21
22
23
24
|
# File 'lib/dnn/core/normalizations.rb', line 19
def initialize(axis: 0, momentum: 0.9, eps: 1e-7)
super()
@axis = axis
@momentum = momentum
@eps = eps
end
|
Instance Attribute Details
#axis ⇒ Integer
Returns The axis to normalization.
6
7
8
|
# File 'lib/dnn/core/normalizations.rb', line 6
def axis
@axis
end
|
#eps ⇒ Float
Returns Value to avoid division by zero.
10
11
12
|
# File 'lib/dnn/core/normalizations.rb', line 10
def eps
@eps
end
|
#momentum ⇒ Float
Returns Exponential moving average of mean and variance.
8
9
10
|
# File 'lib/dnn/core/normalizations.rb', line 8
def momentum
@momentum
end
|
Class Method Details
.from_hash(hash) ⇒ Object
12
13
14
|
# File 'lib/dnn/core/normalizations.rb', line 12
def self.from_hash(hash)
self.new(axis: hash[:axis], momentum: hash[:momentum])
end
|
Instance Method Details
#backward(dy) ⇒ Object
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# File 'lib/dnn/core/normalizations.rb', line 51
def backward(dy)
batch_size = dy.shape[@axis]
if @trainable
@beta.grad = dy.sum(axis: @axis, keepdims: true)
@gamma.grad = (@xn * dy).sum(axis: @axis, keepdims: true)
end
dxn = @gamma.data * dy
dxc = dxn / @std
dstd = -((dxn * @xc) / (@std**2)).sum(axis: @axis, keepdims: true)
dvar = 0.5 * dstd / @std
dxc += (2.0 / batch_size) * @xc * dvar
dmean = dxc.sum(axis: @axis, keepdims: true)
dxc - dmean / batch_size
end
|
#build(input_shape) ⇒ Object
26
27
28
29
30
31
32
|
# File 'lib/dnn/core/normalizations.rb', line 26
def build(input_shape)
super
@params[:gamma] = @gamma = Param.new(Xumo::SFloat.ones(*output_shape), 0)
@params[:beta] = @beta = Param.new(Xumo::SFloat.zeros(*output_shape), 0)
@params[:running_mean] = @running_mean = Param.new(Xumo::SFloat.zeros(*output_shape))
@params[:running_var] = @running_var = Param.new(Xumo::SFloat.zeros(*output_shape))
end
|
#forward(x) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/dnn/core/normalizations.rb', line 34
def forward(x)
if learning_phase
mean = x.mean(axis: @axis, keepdims: true)
@xc = x - mean
var = (@xc**2).mean(axis: @axis, keepdims: true)
@std = NMath.sqrt(var + @eps)
xn = @xc / @std
@xn = xn
@running_mean.data = @momentum * @running_mean.data + (1 - @momentum) * mean
@running_var.data = @momentum * @running_var.data + (1 - @momentum) * var
else
xc = x - @running_mean.data
xn = xc / NMath.sqrt(@running_var.data + @eps)
end
@gamma.data * xn + @beta.data
end
|
#to_hash ⇒ Object
66
67
68
|
# File 'lib/dnn/core/normalizations.rb', line 66
def to_hash
super({axis: @axis, momentum: @momentum, eps: @eps})
end
|