【问题标题】:ValueError: Inputs have incompatible shapesValueError:输入具有不兼容的形状
【发布时间】:2023-02-01 01:16:45
【问题描述】:

我有以下代码:

def fcn8_decoder(convs, n_classes):
  # features from the encoder stage
  f3, f4, f5 = convs

  # number of filters
  n = 512

  # add convolutional layers on top of the CNN extractor.
  o = tf.keras.layers.Conv2D(n , (7 , 7) , activation='relu' , padding='same', name="conv6", data_format=IMAGE_ORDERING)(f5)
  o = tf.keras.layers.Dropout(0.5)(o)

  o = tf.keras.layers.Conv2D(n , (1 , 1) , activation='relu' , padding='same', name="conv7", data_format=IMAGE_ORDERING)(o)
  o = tf.keras.layers.Dropout(0.5)(o)

  o = tf.keras.layers.Conv2D(n_classes,  (1, 1), activation='relu' , padding='same', data_format=IMAGE_ORDERING)(o)

    
  ### START CODE HERE ###

  # Upsample `o` above and crop any extra pixels introduced
  o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False)(o)
  o = tf.keras.layers.Cropping2D(cropping=(1,1))(o)

  # load the pool 4 prediction and do a 1x1 convolution to reshape it to the same shape of `o` above
  o2 = f4
  o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding='same', data_format=IMAGE_ORDERING))(o2)

  # add the results of the upsampling and pool 4 prediction
  o = tf.keras.layers.Add()([o, o2])

  # upsample the resulting tensor of the operation you just did
  o = (tf.keras.layers.Conv2DTranspose( n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False))(o)
  o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)

  # load the pool 3 prediction and do a 1x1 convolution to reshape it to the same shape of `o` above
  o2 = f3
  o2 = tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding='same', data_format=IMAGE_ORDERING)(o2)

  # add the results of the upsampling and pool 3 prediction
  o = tf.keras.layers.Add()([o, o2])

  # upsample up to the size of the original image
  o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(8,8) ,  strides=(8,8) , use_bias=False )(o)
  o = tf.keras.layers.Cropping2D(((0, 0), (0, 96-84)))(o)

  # append a sigmoid activation
  o = (tf.keras.layers.Activation('sigmoid'))(o)
  ### END CODE HERE ###

  return o

# TEST CODE

test_convs, test_img_input = FCN8()
test_fcn8_decoder = fcn8_decoder(test_convs, 11)

print(test_fcn8_decoder.shape)

del test_convs, test_img_input, test_fcn8_decoder

可以查看完整代码here

我收到以下错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-cff468b82c6a> in <module>
      2 
      3 test_convs, test_img_input = FCN8()
----> 4 test_fcn8_decoder = fcn8_decoder(test_convs, 11)
      5 
      6 print(test_fcn8_decoder.shape)

2 frames
/usr/local/lib/python3.8/dist-packages/keras/layers/merging/base_merge.py in _compute_elemwise_op_output_shape(self, shape1, shape2)
     71       else:
     72         if i != j:
---> 73           raise ValueError(
     74               'Inputs have incompatible shapes. '
     75               f'Received shapes {shape1} and {shape2}')

ValueError: Inputs have incompatible shapes. Received shapes (4, 4, 11) and (4, 5, 11)

我在这里做错了什么?

【问题讨论】:

  • 我无法访问 colab,因为它是私有的!
  • 我修复了超链接。

标签: python tensorflow deep-learning image-segmentation


【解决方案1】:

您的模型实现看起来是正确的。问题在于输入形状。输入形状必须能被 32 整除,例如 (224, 224, 3) 或 (64, 64, 3)。

在出错的代码中,您使用的是形状(64, 84, 3),但 84 不能被 32 整除。

解释:

FCN8 的下采样路径使用 5 个卷积块对输入进行下采样。因为模型使用 5 个这样的块,所以输入必须能被 2**5 = 32 整除。 (相关https://stackoverflow.com/a/74847194/5666087.

工作示例:

test_convs, test_img_input = FCN8(input_height=64, input_width=64)
test_fcn8_decoder = fcn8_decoder(convs=test_convs, n_classes=11)
test_convs, test_img_input = FCN8(input_height=224, input_width=224)
test_fcn8_decoder = fcn8_decoder(convs=test_convs, n_classes=11)
test_convs, test_img_input = FCN8(input_height=128, input_width=128)
test_fcn8_decoder = fcn8_decoder(convs=test_convs, n_classes=11)

【讨论】:

    【解决方案2】:

    可能导致问题的原因是您的输入不是正方形格式(相同的高度和宽度),并且在总和层中,您试图对经过一些卷积后具有不同形状的张量求和,然后成为更多的张量之一长方形。

    我设法找到了一些随意的导致具有兼容形状的张量的内核大小。还删除了填充。

    这是我改变的:

    这个:

    o2 = f4
    o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding= 'same', data_format=IMAGE_ORDERING))(o2)
    

    转向这个:

    o2 = f4
    o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 2 ) ,activation='relu', data_format=IMAGE_ORDERING))(o2)
    

    和这个:

    o2 = f3
    o2 = tf.keras.layers.Conv2D(n_classes , ( 1 , 1 ) , activation='relu' , padding ='same', data_format=IMAGE_ORDERING)(o2)
    

    转向这个:

    o2 = f3
    o2 = tf.keras.layers.Conv2D(n_classes , ( 1 , 3 ) , activation='relu' , data_format=IMAGE_ORDERING)(o2)
    

    这是完整的代码:

    def fcn8_decoder(convs, n_classes):
        #features from the encoder stage
        f3, f4, f5 = convs
    
        # number of filters
        n = 512
    
        # add convolutional layers on top of the CNN extractor.
        o = tf.keras.layers.Conv2D(n , (7 , 7) , activation='relu' , padding='same', name="conv6", data_format=IMAGE_ORDERING)(f5)
        o = tf.keras.layers.Dropout(0.5)(o)
    
        o = tf.keras.layers.Conv2D(n , (1 , 1) , activation='relu' , padding='same', name="conv7", data_format=IMAGE_ORDERING)(o)
        o = tf.keras.layers.Dropout(0.5)(o)
    
        o = tf.keras.layers.Conv2D(n_classes,  (1, 1), activation='relu' , padding='same', data_format=IMAGE_ORDERING)(o)
    
    
        ### START CODE HERE ###
    
        # Upsample `o` above and crop any extra pixels introduced
        o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False)(o)
        o = tf.keras.layers.Cropping2D(cropping=(1,1))(o)
    
        # load the pool 4 prediction and do a 1x1 convolution to reshape it to the same shape of `o` above
        o2 = f4
        o2 = ( tf.keras.layers.Conv2D(n_classes , ( 1 , 2 ) , activation='relu' , data_format=IMAGE_ORDERING))(o2)
    
    
    
        # add the results of the upsampling and pool 4 prediction
        o = tf.keras.layers.Add()([o, o2])
    
        # upsample the resulting tensor of the operation you just did
        o = (tf.keras.layers.Conv2DTranspose( n_classes , kernel_size=(4,4) ,  strides=(2,2) , use_bias=False))(o)
        o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)
    
        # load the pool 3 prediction and do a 1x1 convolution to reshape it to the same shape of `o` above
        o2 = f3
        o2 = tf.keras.layers.Conv2D(n_classes , ( 1 , 3 ) , activation='relu' , data_format=IMAGE_ORDERING)(o2)
    
        print("###################################################")
        print(o2.shape,o.shape)
    
        # add the results of the upsampling and pool 3 prediction
        o = tf.keras.layers.Add()([o, o2])
    
        # upsample up to the size of the original image
        o = tf.keras.layers.Conv2DTranspose(n_classes , kernel_size=(8,8) ,  strides=(8,8) , use_bias=False )(o)
        o = tf.keras.layers.Cropping2D(((0, 0), (0, 96-84)))(o)
    
        # append a sigmoid activation
        o = (tf.keras.layers.Activation('sigmoid'))(o)
        ### END CODE HERE ###
    
        return o
    

    【讨论】:

      猜你喜欢
      • 2021-05-12
      • 2021-05-29
      • 2022-01-01
      • 2016-10-23
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      相关资源
      最近更新 更多