teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

reshape() がバッチを考慮していなかったので修正

2018/09/10 05:04

投稿

tiitoi
tiitoi

スコア21960

answer CHANGED
@@ -89,10 +89,10 @@
89
89
  Returns:
90
90
  (None, 10, 10, 5, 1) のテンソル
91
91
  """
92
- t1 = K.tile(K.reshape(x[0], (1, 10, 10, 1, 1)), (1, 1, 1, 5, 1))
92
+ t1 = K.tile(K.reshape(x[0], (-1, 10, 10, 1, 1)), (1, 1, 1, 5, 1))
93
93
 
94
94
  t2 = K.reverse(x[1], axes=2)
95
- t2 = K.tile(K.reshape(t2, (1, 10, 1, 5, 1)), (1, 1, 10, 1, 1))
95
+ t2 = K.tile(K.reshape(t2, (-1, 10, 1, 5, 1)), (1, 1, 10, 1, 1))
96
96
 
97
97
  return t1 + t2
98
98
 

1

実現したい処理を Keras で実行する方法を追記

2018/09/10 05:04

投稿

tiitoi
tiitoi

スコア21960

answer CHANGED
@@ -1,7 +1,7 @@
1
1
  Keras の [Lambda](https://keras.io/ja/layers/core/#lambda) 内で Keras backend API の他、tensorflow の API が利用できます。
2
2
 
3
3
 
4
- ```
4
+ ```python
5
5
  import numpy as np
6
6
  import tensorflow as tf
7
7
  from keras.models import Model
@@ -18,4 +18,95 @@
18
18
 
19
19
  print(model.predict(x)) # [55.]
20
20
 
21
- ```
21
+ ```
22
+
23
+ ----
24
+
25
+ 追記
26
+
27
+ ### 処理したい内容
28
+
29
+ ```python
30
+ data = np.empty((10, 10, 5, 1))
31
+ for i in range(10):
32
+ for j in range(10):
33
+ for k in range(5):
34
+ data[i, j, k] = a[i, j] + b[i, 4 - k]
35
+ ```
36
+
37
+ ### numpy の API を利用した書き方
38
+
39
+ ```python
40
+ import numpy as np
41
+
42
+ # 入力を作成する。
43
+ ###########################################
44
+ # Tensorflow では、値の型はデフォルトで float32 で扱われるのでそれに合わせる。
45
+ a = np.random.randn(10, 10, 1).astype(np.float32)
46
+ b = np.random.randn(10, 5, 1).astype(np.float32)
47
+
48
+ # for style
49
+ ###########################################
50
+ A1 = np.empty((10, 10, 5, 1))
51
+ B1 = np.empty((10, 10, 5, 1))
52
+ data1 = np.empty((10, 10, 5, 1))
53
+ for i in range(10):
54
+ for j in range(10):
55
+ for k in range(5):
56
+ A1[i, j, k] = a[i, j]
57
+ B1[i, j, k] = b[i, 4 - k]
58
+ data1[i, j, k] = a[i, j] + b[i, 4 - k]
59
+
60
+ # numpy style
61
+ ###########################################
62
+ A2 = np.tile(a.reshape(10, 10, 1, 1), (1, 1, 5, 1))
63
+ B2 = np.tile(np.flip(b, axis=1).reshape(10, 1, 5, 1), (1, 10, 1, 1))
64
+ data2 = A2 + B2
65
+
66
+ # for style と numpy style が一致するかどうか
67
+ print(np.all(np.isclose(A1, A2))) # True
68
+ print(np.all(np.isclose(B1, B2))) # True
69
+ print(np.all(np.isclose(data1, data2))) # True
70
+ ```
71
+
72
+ `a[i, j]` は `k in range(5)` 中は同じ値になるので、`np.tile()` で axis=3 を 5 回繰り返す。
73
+ `b[i, 4 - k]` は、(10, 5, 1) の numpy 配列を axis=1 で反転させ、`j in range(10)` 中は同じ値になるので、`np.tile()` で axis=2 を 10 回繰り返す。
74
+
75
+ ### Keras Backedn API を利用した書き方
76
+
77
+ ```python
78
+ import tensorflow as tf
79
+ from keras.models import Model
80
+ from keras.layers import Input, Lambda
81
+ from keras import backend as K
82
+
83
+ # numpy の関数を Keras Backend API で置き換えた
84
+ # バッチの次元が1つ増えていることに注意。
85
+ def process(x):
86
+ """Args:
87
+ x: [(None, 10, 10, 1) のテンソル、(None, 10, 5, 1) のテンソル]
88
+
89
+ Returns:
90
+ (None, 10, 10, 5, 1) のテンソル
91
+ """
92
+ t1 = K.tile(K.reshape(x[0], (1, 10, 10, 1, 1)), (1, 1, 1, 5, 1))
93
+
94
+ t2 = K.reverse(x[1], axes=2)
95
+ t2 = K.tile(K.reshape(t2, (1, 10, 1, 5, 1)), (1, 1, 10, 1, 1))
96
+
97
+ return t1 + t2
98
+
99
+ # モデルを作成する。
100
+ input_a = Input(shape=(10, 10, 1))
101
+ input_b = Input(shape=(10, 5, 1))
102
+ outputs = Lambda(process)([input_a, input_b])
103
+ model = Model(inputs=[input_a, input_b], outputs=outputs)
104
+
105
+ # a, b はバッチの次元を追加する。順伝搬して結果を計算する。
106
+ data3 = model.predict([a[np.newaxis, ...], b[np.newaxis, ...]])
107
+
108
+ # numpy で計算した値と一致するかどうか
109
+ print(np.all(np.isclose(data1, data3))) # True
110
+ ```
111
+
112
+ numpy の API でできることは Keras Backend API または Tensorflow の API でできるかと思います。