运行 优化器在张量流图像分割中执行步骤时出现形状不兼容问题

shapes not compatible issue when running optimizer step in tensorflow image segmentation

我正在 tensorflow 中执行图像分割任务。

代码:

height = 1024
width = 1024
channels = 1

# input place holders
X = tf.placeholder(tf.float32, [None, height, width, channels], name = 'image')

Y = tf.placeholder(tf.float32, [None, height, width, channels], name = 'annotation')

# variable learning rate
lr = tf.placeholder(tf.float32, name = 'lr')




W1 = tf.Variable(tf.truncated_normal([3, 3, 1, 2], stddev=0.1)) 
B1 = tf.Variable(tf.ones([2])/(2*2))

W2 = tf.Variable(tf.truncated_normal([3, 3, 2, 1], stddev=0.1)) 
B2 = tf.Variable(tf.ones([1])/(1*1))

W3 = tf.Variable(tf.truncated_normal([2, 2, 1, 1], stddev=0.1)) 
B3 = tf.Variable(tf.ones([1])/(1*1))




stride = 1  
Y1 = tf.nn.relu(tf.nn.conv2d(X, W1, strides=[1, stride, stride, 1], padding= 'VALID') + B1)

stride = 1  
Y2 = tf.nn.relu(tf.nn.conv2d(Y1, W2, strides=[1, stride, stride, 1], padding='VALID') + B2)

Ylogits = tf.nn.conv2d_transpose(Y2, W3, output_shape = [1, 1024, 1024, 1], strides = [1, 2, 2, 1])

一切都很好,除了我 运行 这一行:

train_step = tf.train.GradientDescentOptimizer(learning_rate=lr).最小化(cross_entropy_sum)

回溯:

train_step = tf.train.GradientDescentOptimizer(learning_rate=lr).最小化(cross_entropy_sum)

File "/home/anaconda/lib/python2.7/site-packages/tensorflow/python/training/optimizer.py", line 315, in minimize
    grad_loss=grad_loss)
  File "/home/anaconda/lib/python2.7/site-packages/tensorflow/python/training/optimizer.py", line 386, in compute_gradients
    colocate_gradients_with_ops=colocate_gradients_with_ops)
  File "/home/anaconda/lib/python2.7/site-packages/tensorflow/python/ops/gradients_impl.py", line 580, in gradients
    in_grad.set_shape(t_in.get_shape())
  File "/home/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 413, in set_shape
    self._shape = self._shape.merge_with(shape)
  File "/home/anaconda/lib/python2.7/site-packages/tensorflow/python/framework/tensor_shape.py", line 564, in merge_with
    (self, other))
ValueError: Shapes (1, 512, 512, 1) and (?, 1020, 1020, 1) are not compatible

因为您的 conv2d_transpose 操作的步幅是 [1, 2, 2, 1],它会导致输出的高度和宽度是输入的两倍。请参阅 this Data Science answer and the page it links here 了解发生这种情况的原因。

你设置你的output_shape = [1, 1024, 1024, 1],反卷积层期望一半的高度和宽度作为输入,以及相同的批量大小和通道数,这意味着它期望形状为 [1, 512, 512 , 1].

你给它的输入 Y2 的形状是 [None, 1020, 1020, 1],因为两个 conv2d 层每个 trim数据的边缘,但因为步幅是一个,所以它们不会显着减少宽度或高度。批量大小为 None,因为它在这些层中保持不变。

为了解决这个问题,一个选择是在你的一个卷积层上使用 [1, 2, 2, 1] 的步幅,这将使宽度和高度大致减半(要精确减半,请使用 padding='SAME'。这将防止边缘稍微 trimmed)。您还必须将反卷积层的 output_shape 更改为 [None, 1024, 1024, 1].