运行 优化器在张量流图像分割中执行步骤时出现形状不兼容问题
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].
我正在 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].