我正在使用Keras,我想制作一个以[a0, a1]
,[b0, b1, b2]
作为输入并以[a0*b0, a0*b1, a0*b2, a1*b0, a1*b1, a1*b2]
作为输出的图层。我尝试使用Lambda
,但无法成功。这是我的代码:
import numpy as np
from keras.models import Input
from keras.layers import Lambda
def mix(A):
reshaped = [np.reshape(A[m], (1,np.size(A[m]))) for m in range(len(A))]
mixed = reshaped[-1]
for i in range(len(A)-1):
mixed = np.matmul(np.transpose(reshaped[-i-2]), mixed)
mixed = np.reshape(mixed, (1,np.size(mixed)))
return np.reshape(mixed, np.size(mixed))
a = Input(shape=(2,))
b = Input(shape=(3,))
c = Lambda(mix)([a, b])
这是我得到的错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-32-07bbf930b48b> in <module>()
1 a = Input(shape=(2,))
2 b = Input(shape=(3,))
----> 3 c = Lambda(mix)([a, b])
~\Anaconda3\envs\mind\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
455 # Actually call the layer,
456 # collecting output(s), mask(s), and shape(s).
--> 457 output = self.call(inputs, **kwargs)
458 output_mask = self.compute_mask(inputs, previous_mask)
459
~\Anaconda3\envs\mind\lib\site-packages\keras\layers\core.py in call(self, inputs, mask)
685 if has_arg(self.function, 'mask'):
686 arguments['mask'] = mask
--> 687 return self.function(inputs, **arguments)
688
689 def compute_mask(self, inputs, mask=None):
<ipython-input-31-bbc21320d8af> in mix(A)
4
5 for i in range(len(A)-1):
----> 6 mixed = np.matmul(np.transpose(reshaped[-i-2]), mixed)
7 mixed = np.reshape(mixed, (1,np.size(mixed)))
8
TypeError: Object arrays are not currently supported
但是,如果我放:
a = np.array([1,2])
b = np.array([3,4,5])
print(mix([a,b]))
然后我得到:
[ 3 4 5 6 8 10]
这正是我的意图。但是我不知道如何正确地将其放入Lambda
。
有人可以告诉我如何处理吗?我是Keras的新手,所以我不知道Lambda
,Input
或其他内容的内部结构。
在Abhijit的评论之后,我更改了代码,如下所示:
import numpy as np
import tensorflow as tf
from keras.models import Input
from keras.layers import Lambda
def mix(A):
reshaped = [tf.reshape(A[m], (1,tf.size(A[m]))) for m in range(len(A))]
mixed = reshaped[-1]
for i in range(len(A)-1):
mixed = tf.matmul(tf.transpose(reshaped[-i-2]), mixed)
mixed = tf.reshape(mixed, (1,tf.size(mixed)))
return tf.reshape(mixed, [tf.size(mixed)])
a = Input(shape=(2,))
b = Input(shape=(3,))
c = Lambda(mix)([a, b])
现在我没有任何错误,但是我认为我没有正确的神经网络。因为执行:
model = Model(inputs=[a,b], outputs=c)
print(model.summary())
我得到:
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_22 (InputLayer) (None, 2) 0
__________________________________________________________________________________________________
input_23 (InputLayer) (None, 3) 0
__________________________________________________________________________________________________
lambda_3 (Lambda) (None,) 0 input_22[0][0]
input_23[0][0]
==================================================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
__________________________________________________________________________________________________
但是请参见图层lambda_3
。输出形状不应该是(None, 6)
吗?
答案 0 :(得分:1)
除了需要使用Keras后端函数(即keras.backend.*
)或直接使用后端函数(即tf.*
或th.*
)外,我认为您正在定义mix
的内容不必要地复杂。可以这样简单得多:
from keras import backend as K
def mix(ts):
t0 = K.expand_dims(ts[0], axis=-1)
t1 = K.expand_dims(ts[1], axis=1)
return K.batch_flatten(t0 * t1)
a = Input(shape=(2,))
b = Input(shape=(3,))
c = Lambda(mix)([a, b])
model = Model(inputs=[a,b], outputs=c)
这是测试:
# the reshapes are necessary to make them a batch
a = np.array([1,2]).reshape(1,2)
b = np.array([3,4,5]).reshape(1,3)
print(model.predict([a, b]))
# output
[[ 3. 4. 5. 6. 8. 10.]]
此外,有时Lambda
层可以自动推断输出形状。但是,如果您愿意,可以显式设置其输出形状:
c = Lambda(mix, output_shape=(6,))([a, b])
模型摘要:
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_9 (InputLayer) (None, 2) 0
__________________________________________________________________________________________________
input_10 (InputLayer) (None, 3) 0
__________________________________________________________________________________________________
lambda_5 (Lambda) (None, 6) 0 input_9[0][0]
input_10[0][0]
==================================================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
__________________________________________________________________________________________________