質問編集履歴

1

質問の内容をよりピンポイントにしました.

2021/04/25 14:50

投稿

hirashun
hirashun

スコア6

test CHANGED
@@ -1 +1 @@
1
- Tensorflowで, 定義したCellにいて前時刻の隠れ層の入力を取得する方法
1
+ Tensorflowのlayerのcall関数いて
test CHANGED
@@ -1,457 +1,9 @@
1
1
  ### 概要
2
2
 
3
-  現在, Tensorflowを用いて時系列データの予測を行うCTRNN(Continuous-time RNN)の実装を行なっております.
3
+  現在, Tensorflowを用いて時系列データの予測を行うRNNの実装を行なっております.
4
-
5
-  CTRNNでの入力層から隠れ層における順伝播計算は以下のようになっており, 隠れ層の前時刻の入力u_t-1を必要とします.
6
4
 
7
5
 
8
6
 
9
- u_{t,i} = (1 - 1/τ)u_{t-1,i} + 1/τ{(Σw*x_t) + (Σw*c_{t-1}) +b}
7
+ [Webサイト](https://qiita.com/everylittle/items/c088564d53cdfcde92cc)と, [Tensorflowのライブラリ](https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/layers/recurrent.py)の主にAbstractRNNCell, SimpleRNNCELL, LSTMCellの部分を参考にしているのですが, LSTMCellのcall関数において, h, [h,c]を返しているのはどういう意味なのでしょうか?
10
8
 
11
- c_{t,i} = activation(u_{t,i}) (wは重み, bはバイアス, τは時定数)
12
-
13
-
14
-
15
- [Webサイト](https://qiita.com/everylittle/items/c088564d53cdfcde92cc)と, [Tensorflowのライブラリ](https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/layers/recurrent.py)の主にAbstractRNNCell, SimpleRNNCELL, LSTMCellの部分を参考に, 自分でCTRNNCellを定義したのですが, コード中にあるstatesにu_{t-1}を含め, それを取得する方法がわかりません.
16
-
17
- 申し訳ありませんが, アドバイスやご回答いただければ幸いです.
18
-
19
- また, 質問で不足している事項がありましたら, ご指摘ください. よろしくお願いします.
20
-
21
-
22
-
23
- ```Python3
24
-
25
- import tensorflow as tf
26
-
27
- import numpy as np
28
-
29
- import math###
30
-
31
- from tensorflow.keras import Sequential
32
-
33
- from tensorflow.keras.layers import RNN, AbstractRNNCell
34
-
35
- from tensorflow.keras.optimizers import SGD
36
-
37
- from tensorflow.keras import layers
38
-
39
- from tensorflow.python.keras import activations, constraints, initializers, regularizers
40
-
41
- from tensorflow.python.keras import backend as K
42
-
43
- from tensorflow.python.keras.utils import tf_utils
44
-
45
- from tensorflow.python.ops import array_ops
46
-
47
- import matplotlib.pyplot as plt
48
-
49
-
50
-
51
-
52
-
53
- class CTRNNCell(AbstractRNNCell):
54
-
55
- def __init__(self,
56
-
57
- units,
58
-
59
- activation='tanh',
60
-
61
- use_bias=True,
62
-
63
- kernel_initializer='glorot_uniform',
64
-
65
- recurrent_initializer='orthogonal',
66
-
67
- bias_initializer='zeros',
68
-
69
- kernel_regularizer=None,
70
-
71
- recurrent_regularizer=None,
72
-
73
- bias_regularizer=None,
74
-
75
- kernel_constraint=None,
76
-
77
- recurrent_constraint=None,
78
-
79
- bias_constraint=None,
80
-
81
- tau=3,
82
-
83
- **kwargs):
84
-
85
-
86
-
87
- super(CTRNNCell, self).__init__(**kwargs)
88
-
89
- self.units = units
90
-
91
- self.activation = activations.get(activation)
92
-
93
- self.use_bias = use_bias
94
-
95
-
96
-
97
- self.kernel_initializer = initializers.get(kernel_initializer)
98
-
99
- self.recurrent_initializer = initializers.get(recurrent_initializer)
100
-
101
- self.bias_initializer = initializers.get(bias_initializer)
102
-
103
-
104
-
105
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
106
-
107
- self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
108
-
109
- self.bias_regularizer = regularizers.get(bias_regularizer)
110
-
111
-
112
-
113
- self.kernel_constraint = constraints.get(kernel_constraint)
114
-
115
- self.recurrent_constraint = constraints.get(recurrent_constraint)
116
-
117
- self.bias_constraint = constraints.get(bias_constraint)
118
-
119
- self.tau = tau
120
-
121
-
122
-
123
- @property
124
-
125
- def state_size(self):
126
-
127
- return self.units
128
-
129
-
130
-
131
- def build(self, input_shape):
132
-
133
- input_dim = input_shape[-1]
134
-
135
- self.kernel = self.add_weight(
136
-
137
- shape=(input_dim, self.units),
138
-
139
- name='kernel',
140
-
141
- initializer=self.kernel_initializer,
142
-
143
- regularizer=self.kernel_regularizer,
144
-
145
- constraint=self.kernel_constraint)
146
-
147
- self.recurrent_kernel = self.add_weight(
148
-
149
- shape=(self.units,self.units),
150
-
151
- name='recurrent_kernel',
152
-
153
- initializer=self.recurrent_initializer,
154
-
155
- regularizer=self.recurrent_regularizer,
156
-
157
- constraint=self.recurrent_constraint)
158
-
159
-
160
-
161
- if self.use_bias:
162
-
163
- self.bias = self.add_weight(
164
-
165
- shape=(self.units,),
166
-
167
- name='bias',
168
-
169
- initializer=self.bias_initializer,
170
-
171
- regularizer=self.bias_regularizer,
172
-
173
- constraint=self.bias_constraint)
174
-
175
- else:
176
-
177
- self.bias = None
178
-
179
- self.built = True
180
-
181
-
182
-
183
- def call(self, inputs, states, training=None):
184
-
185
- #前時刻のuを取得する方法がわからない
186
-
187
- prev_c = states[0] # previous memory state
188
-
189
- #prev_u = states[0]
190
-
191
- prev_u = states[1]
192
-
193
- u = K.dot(inputs, self.kernel)
194
-
195
- if self.use_bias:
196
-
197
- u = K.bias_add(u, self.bias)
198
-
199
-
200
-
201
- u = (1-1/self.tau)*prev_u + 1/self.tau*u +1/self.tau*K.dot(prev_c, self.recurrent_kernel)
202
-
203
- #print(u)
204
-
205
-
206
-
207
- c = self.activation(u)
208
-
209
- return c, c
210
-
211
-
212
-
213
- #シードを固定
214
-
215
- def set_seed(seed=12345):
216
-
217
- np.random.seed(seed)
218
-
219
- tf.random.set_seed(seed)
220
-
221
-
222
-
223
- #データ取得
224
-
225
- def get_training_data():
226
-
227
- period = 50
228
-
229
- time_steps = np.arange(5*period)
230
-
231
- data = [np.cos((2*np.pi*time_steps/period)),
232
-
233
- np.sin((2*2*np.pi*time_steps/period))]
234
-
235
- data = np.array(data).T
236
-
237
- noise = np.random.normal(0, 0.01, data.shape)
238
-
239
- data = data + noise
240
-
241
- #(1, datalen, dim)に配列をreshape
242
-
243
- data = data[np.newaxis, :, :]
244
-
245
-
246
-
247
- return data
248
-
249
-
250
-
251
-
252
-
253
- def get_input_target(data):
254
-
255
- input_data = data[:, :-1, :]
256
-
257
- target_data = data[:, 1:, :]
258
-
259
-
260
-
261
- return input_data, target_data
262
-
263
-
264
-
265
-
266
-
267
- def build_model(data_length, in_state_size, hidden_state_size, out_state_size,
268
-
269
- train=False):
270
-
271
- inputs = tf.keras.Input(shape=(data_length, in_state_size))
272
-
273
- initial_hidden_input = tf.keras.Input(shape=(hidden_state_size,))
274
-
275
- hidden_states, hidden_state = RNN(CTRNNCell(hidden_state_size),
276
-
277
- return_sequences=True, return_state=True)(
278
-
279
- inputs, initial_state=[initial_hidden_input])
280
-
281
- outputs = layers.Dense(out_state_size, activation="tanh")(hidden_states)
282
-
283
-
284
-
285
- if train:#訓練用
286
-
287
- model = tf.keras.Model(inputs=[inputs, initial_hidden_input],
288
-
289
- outputs=outputs)
290
-
291
- else:#予測用
292
-
293
- model = tf.keras.Model(inputs=[inputs, initial_hidden_input],
294
-
295
- outputs=[outputs, hidden_state])
296
-
297
-
298
-
299
- return model
300
-
301
-
302
-
303
-
304
-
305
- def plot(target_data, open_outputs, closed_outputs):
306
-
307
- fig = plt.figure(figsize=(12, 4))
308
-
309
- ax = plt.subplot2grid((1, 3), (0, 0))
310
-
311
- ax.set_title("Target")
312
-
313
- ax.set_aspect("equal")
314
-
315
- ax.grid(True)
316
-
317
- ax.set_xlim([-1.2, 1.2])
318
-
319
- ax.set_ylim([-1.2, 1.2])
320
-
321
- ax.plot(target_data[0, :, 0], target_data[0, :, 1])
322
-
323
-
324
-
325
- ax = plt.subplot2grid((1, 3), (0, 1))
326
-
327
- ax.set_title("Open-loop generation")
328
-
329
- ax.set_aspect("equal")
330
-
331
- ax.grid(True)
332
-
333
- ax.set_xlim([-1.2, 1.2])
334
-
335
- ax.set_ylim([-1.2, 1.2])
336
-
337
- ax.plot(open_outputs[0, :, 0], open_outputs[0, :, 1])
338
-
339
-
340
-
341
- ax = plt.subplot2grid((1, 3), (0, 2))
342
-
343
- ax.set_title("Closed-loop generation")
344
-
345
- ax.set_aspect("equal")
346
-
347
- ax.grid(True)
348
-
349
- ax.set_xlim([-1.2, 1.2])
350
-
351
- ax.set_ylim([-1.2, 1.2])
352
-
353
- ax.plot(closed_outputs[0, :, 0], closed_outputs[0, :, 1])
354
-
355
-
356
-
357
- plt.tight_layout()
358
-
359
- plt.show()
360
-
361
-
362
-
363
-
364
-
365
- def main():
366
-
367
- set_seed()
368
-
369
-
370
-
371
- data = get_training_data()
372
-
373
- input_data, target_data = get_input_target(data)
374
-
375
-
376
-
377
- data_length = input_data.shape[1]
378
-
379
- in_state_size = input_data.shape[2]
380
-
381
- hidden_state_size = 20
382
-
383
- out_state_size = target_data.shape[2]
384
-
385
-
386
-
387
- model = build_model(data_length, in_state_size, hidden_state_size,
388
-
389
- out_state_size, train=True)
390
-
391
-
392
-
393
- model.summary()
394
-
395
-
396
-
397
- optimizer = tf.keras.optimizers.Adam(learning_rate=0.01)
398
-
399
- model.compile(optimizer, loss="mse")
400
-
401
-
402
-
403
- hidden_state = np.zeros([1, hidden_state_size])
404
-
405
- model.fit([input_data, hidden_state], target_data, epochs=1000, verbose=0)
406
-
407
-
408
-
409
- open_outputs = model.predict([input_data, hidden_state])
410
-
411
-
412
-
413
- model_test = build_model(1, in_state_size, hidden_state_size,
414
-
415
- out_state_size, train=False)
416
-
417
- model_test.set_weights(model.get_weights())
418
-
419
- model_test.summary()
420
-
421
-
422
-
423
- predicted_input = input_data[:, :1, :] # used as an initial input
424
-
425
- hidden_state = np.zeros([1, hidden_state_size]) # used as an initial hidden state
426
-
427
-
428
-
429
- generation_length=data_length
430
-
431
- closed_outputs=np.zeros([1, generation_length, out_state_size])
432
-
433
- for time_step in range(generation_length):
434
-
435
- predicted_input, hidden_state = model_test.predict(
436
-
437
- [predicted_input, hidden_state])
438
-
439
- closed_outputs[0, time_step, :] = predicted_input[0, 0, :]
440
-
441
-
442
-
443
- plot(target_data, open_outputs, closed_outputs)
444
-
445
-
446
-
447
-
448
-
449
- if __name__ == "__main__":
450
-
451
- main()
452
-
453
-
454
-
455
-
456
-
457
- ```
9
+ [h, c]であれば納得感があるのですが...