无法将卷积输出中的值除以 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
__________________________________________________________________________________________________