无法将卷积输出中的值除以 Keras 中的批量大小
Cannot divide values in convolution output by batch size in Keras
我需要做一些我认为应该很简单的事情:将卷积层的输出除以批量大小(如果您对原因感兴趣,我可以详细说明)。
这是重现我正在尝试做的事情的最少代码
from keras.models import *
from keras.layers import *
from keras import backend as K
input = Input((24,24,3))
conv = Conv2D(8,4,1,'SAME')(input)
norm = Lambda(lambda x:x[0]/x[1])((conv,input.shape[0]))
model = Model(inputs = input, outputs = norm)
model.summary()
但是,我收到错误消息:
----> norm = Lambda(lambda x:x[0]/x[1])((conv,input.shape[0]))
model = Model(inputs = input, outputs = norm)
ValueError: Exception encountered when calling layer "lambda_9" (type Lambda).
None values not supported.
Call arguments received:
• inputs=('tf.Tensor(shape=(None, 24, 24, 8), dtype=float32)', 'None')
• mask=None
• training=None
我觉得这“应该被允许”。我错过了什么或做错了什么?谢谢!
实际上有两种方法可以获得符号张量的形状:tensor.shape
(您正在使用的)和tf.shape(tensor)
。简而言之,tensor.shape
return 是编译时已知的张量的“静态形状”。在这种情况下这可能会出现问题:您正在尝试使用一个在编译时未知的维度,但在模型实际 运行 时定义。 tensor.shape
在这里失败,因为它只会 return 静态已知的 None
(这实际上是未知批量大小的占位符)。
另一方面,tf.shape(tensor)
return 是张量的 动态 形状,实际上它本身就是一个张量,您可以使用this 来定义基于未知形状的操作。这意味着你只需要替换一行:
norm = Lambda(lambda x:x[0]/x[1])((conv, tf.cast(tf.shape(input)[0], tf.float32)))
请注意,我们必须将形状转换为浮点数以避免 dtype 不匹配。这让单元格 运行 正常:
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_3 (InputLayer) [(None, 24, 24, 3)] 0 []
tf.compat.v1.shape_1 (TFOpLamb (4,) 0 ['input_3[0][0]']
da)
tf.__operators__.getitem_1 (Sl () 0 ['tf.compat.v1.shape_1[0][0]']
icingOpLambda)
conv2d_2 (Conv2D) (None, 24, 24, 8) 392 ['input_3[0][0]']
tf.cast (TFOpLambda) () 0 ['tf.__operators__.getitem_1[0][0
]']
lambda_2 (Lambda) (None, 24, 24, 8) 0 ['conv2d_2[0][0]',
'tf.cast[0][0]']
==================================================================================================
Total params: 392
Trainable params: 392
Non-trainable params: 0
__________________________________________________________________________________________________
我需要做一些我认为应该很简单的事情:将卷积层的输出除以批量大小(如果您对原因感兴趣,我可以详细说明)。
这是重现我正在尝试做的事情的最少代码
from keras.models import *
from keras.layers import *
from keras import backend as K
input = Input((24,24,3))
conv = Conv2D(8,4,1,'SAME')(input)
norm = Lambda(lambda x:x[0]/x[1])((conv,input.shape[0]))
model = Model(inputs = input, outputs = norm)
model.summary()
但是,我收到错误消息:
----> norm = Lambda(lambda x:x[0]/x[1])((conv,input.shape[0]))
model = Model(inputs = input, outputs = norm)
ValueError: Exception encountered when calling layer "lambda_9" (type Lambda).
None values not supported.
Call arguments received:
• inputs=('tf.Tensor(shape=(None, 24, 24, 8), dtype=float32)', 'None')
• mask=None
• training=None
我觉得这“应该被允许”。我错过了什么或做错了什么?谢谢!
实际上有两种方法可以获得符号张量的形状:tensor.shape
(您正在使用的)和tf.shape(tensor)
。简而言之,tensor.shape
return 是编译时已知的张量的“静态形状”。在这种情况下这可能会出现问题:您正在尝试使用一个在编译时未知的维度,但在模型实际 运行 时定义。 tensor.shape
在这里失败,因为它只会 return 静态已知的 None
(这实际上是未知批量大小的占位符)。
另一方面,tf.shape(tensor)
return 是张量的 动态 形状,实际上它本身就是一个张量,您可以使用this 来定义基于未知形状的操作。这意味着你只需要替换一行:
norm = Lambda(lambda x:x[0]/x[1])((conv, tf.cast(tf.shape(input)[0], tf.float32)))
请注意,我们必须将形状转换为浮点数以避免 dtype 不匹配。这让单元格 运行 正常:
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_3 (InputLayer) [(None, 24, 24, 3)] 0 []
tf.compat.v1.shape_1 (TFOpLamb (4,) 0 ['input_3[0][0]']
da)
tf.__operators__.getitem_1 (Sl () 0 ['tf.compat.v1.shape_1[0][0]']
icingOpLambda)
conv2d_2 (Conv2D) (None, 24, 24, 8) 392 ['input_3[0][0]']
tf.cast (TFOpLambda) () 0 ['tf.__operators__.getitem_1[0][0
]']
lambda_2 (Lambda) (None, 24, 24, 8) 0 ['conv2d_2[0][0]',
'tf.cast[0][0]']
==================================================================================================
Total params: 392
Trainable params: 392
Non-trainable params: 0
__________________________________________________________________________________________________