Class: DNN::Layers::RNN

Inherits:
Connection show all
Includes:
Initializers
Defined in:
lib/dnn/core/rnn_layers.rb

Overview

Super class of all RNN classes.

Direct Known Subclasses

GRU, LSTM, SimpleRNN

Instance Attribute Summary collapse

Attributes inherited from Connection

#bias_initializer, #bias_regularizer, #weight_initializer, #weight_regularizer

Attributes inherited from HasParamLayer

#params, #trainable

Attributes inherited from Layer

#input_shape, #learning_phase

Instance Method Summary collapse

Methods inherited from Connection

#use_bias

Methods inherited from Layer

#built?

Constructor Details

#initialize(num_nodes, stateful: false, return_sequences: true, weight_initializer: RandomNormal.new, recurrent_weight_initializer: RandomNormal.new, bias_initializer: Zeros.new, weight_regularizer: nil, recurrent_weight_regularizer: nil, bias_regularizer: nil, use_bias: true) ⇒ RNN

Returns a new instance of RNN.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/dnn/core/rnn_layers.rb', line 19

def initialize(num_nodes,
               stateful: false,
               return_sequences: true,
               weight_initializer: RandomNormal.new,
               recurrent_weight_initializer: RandomNormal.new,
               bias_initializer: Zeros.new,
               weight_regularizer: nil,
               recurrent_weight_regularizer: nil,
               bias_regularizer: nil,
               use_bias: true)
  super(weight_initializer: weight_initializer, bias_initializer: bias_initializer,
        weight_regularizer: weight_regularizer, bias_regularizer: bias_regularizer, use_bias: use_bias)
  @num_nodes = num_nodes
  @stateful = stateful
  @return_sequences = return_sequences
  @layers = []
  @hidden = @params[:hidden] = Param.new
  @params[:recurrent_weight] = @recurrent_weight = Param.new(nil, 0)
  @recurrent_weight_initializer = recurrent_weight_initializer
  @recurrent_weight_regularizer = recurrent_weight_regularizer
end

Instance Attribute Details

#num_nodes ⇒ Integer (readonly)

Returns number of nodes.

Returns:

  • (Integer) —

    number of nodes.



9
10
11
# File 'lib/dnn/core/rnn_layers.rb', line 9

def num_nodes
  @num_nodes
end

#recurrent_weight_initializer ⇒ DNN::Initializers::Initializer (readonly)

Returns Recurrent weight initializer.

Returns:



15
16
17
# File 'lib/dnn/core/rnn_layers.rb', line 15

def recurrent_weight_initializer
  @recurrent_weight_initializer
end

#recurrent_weight_regularizer ⇒ DNN::Regularizers::Regularizer (readonly)

Returns Recurrent weight regularization.

Returns:



17
18
19
# File 'lib/dnn/core/rnn_layers.rb', line 17

def recurrent_weight_regularizer
  @recurrent_weight_regularizer
end

#return_sequences ⇒ Bool (readonly)

Returns Set the false, only the last of each cell of RNN is left.

Returns:

  • (Bool) —

    Set the false, only the last of each cell of RNN is left.



13
14
15
# File 'lib/dnn/core/rnn_layers.rb', line 13

def return_sequences
  @return_sequences
end

#stateful ⇒ Bool (readonly)

Returns Maintain state between batches.

Returns:

  • (Bool) —

    Maintain state between batches.



11
12
13
# File 'lib/dnn/core/rnn_layers.rb', line 11

def stateful
  @stateful
end

Instance Method Details

#backward(dh2s) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/dnn/core/rnn_layers.rb', line 60

def backward(dh2s)
  unless @return_sequences
    dh = dh2s
    dh2s = Xumo::SFloat.zeros(dh.shape[0], @time_length, dh.shape[1])
    dh2s[true, -1, false] = dh
  end
  dxs = Xumo::SFloat.zeros(@xs_shape)
  dh = 0
  (0...dh2s.shape[1]).to_a.reverse.each do |t|
    dh2 = dh2s[true, t, false]
    dx, dh = @layers[t].backward(dh2 + dh)
    dxs[true, t, false] = dx
  end
  dxs
end

#build(input_shape) ⇒ Object



41
42
43
44
# File 'lib/dnn/core/rnn_layers.rb', line 41

def build(input_shape)
  super
  @time_length = @input_shape[0]
end

#forward(xs) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dnn/core/rnn_layers.rb', line 46

def forward(xs)
  @xs_shape = xs.shape
  hs = Xumo::SFloat.zeros(xs.shape[0], @time_length, @num_nodes)
  h = (@stateful && @hidden.data) ? @hidden.data : Xumo::SFloat.zeros(xs.shape[0], @num_nodes)
  xs.shape[1].times do |t|
    x = xs[true, t, false]
    @layers[t].trainable = @trainable
    h = @layers[t].forward(x, h)
    hs[true, t, false] = h
  end
  @hidden.data = h
  @return_sequences ? hs : h
end

#output_shape ⇒ Object



76
77
78
# File 'lib/dnn/core/rnn_layers.rb', line 76

def output_shape
  @return_sequences ? [@time_length, @num_nodes] : [@num_nodes]
end

#regularizers ⇒ Object



97
98
99
100
101
102
103
# File 'lib/dnn/core/rnn_layers.rb', line 97

def regularizers
  regularizers = []
  regularizers << @weight_regularizer if @weight_regularizer
  regularizers << @recurrent_weight_regularizer if @recurrent_weight_regularizer
  regularizers << @bias_regularizer if @bias_regularizer
  regularizers
end

#reset_state ⇒ Object

Reset the state of RNN.



93
94
95
# File 'lib/dnn/core/rnn_layers.rb', line 93

def reset_state
  @hidden.data = @hidden.data.fill(0) if @hidden.data
end

#to_hash(merge_hash = nil) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dnn/core/rnn_layers.rb', line 80

def to_hash(merge_hash = nil)
  hash = {
    num_nodes: @num_nodes,
    stateful: @stateful,
    return_sequences: @return_sequences,
    recurrent_weight_initializer: @recurrent_weight_initializer.to_hash,
    recurrent_weight_regularizer: @recurrent_weight_regularizer&.to_hash,
  }
  hash.merge!(merge_hash) if merge_hash
  super(hash)
end