Tensorflow conv2d_transpose: размер out_backprop не соответствует вычисленному - PullRequest
0 голосов
/ 03 июля 2018

Когда я создаю FCN для сегментации, я хочу, чтобы изображения сохраняли исходный размер входных данных, поэтому я использую полностью сверточные слои. Когда я выбираю фиксированный размер ввода, такой как (224, 224), транспонирование конв работает нормально. Однако, когда я изменил код использования (224, 224) на (h, w), я столкнулся со следующей ошибкой. Я раньше гуглил, но не понял. Может кто-нибудь мне помочь? Спасибо.

Информация об ошибке:

InvalidArgumentError (see above for traceback): Conv2DSlowBackpropInput: Size 
of out_backprop doesn't match computed: actual = 62, computed = 
63spatial_dim: 2 input: 500 filter: 16 output: 62 stride: 8 dilation: 1
     [[Node: deconv_layer/conv2d_transpose_2 = 
Conv2DBackpropInput[T=DT_FLOAT, data_format="NCHW", dilations=[1, 1, 1, 1], 
padding="SAME", strides=[1, 1, 8, 8], use_cudnn_on_gpu=true, 
_device="/job:localhost/replica:0/task:0/device:GPU:0"] 
(deconv_layer/conv2d_transpose_2-0-VecPermuteNHWCToNCHW- 
LayoutOptimizer/_1961, deconv_layer/deconv3/kernel/read, 
deconv_layer/Add_1)]]
     [[Node: losses/_2091 = _Recv[client_terminated=false, 
recv_device="/job:localhost/replica:0/task:0/device:CPU:0", 
send_device="/job:localhost/replica:0/task:0/device:GPU:0", 
send_device_incarnation=1, tensor_name="edge_4480_losses", 
tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"] 
()]]

Код:

with tf.variable_scope("deconv_layer"):
    deconv_shape1 = block2.get_shape()
    W_t1 = deconv_utils.weight_variable([4, 4, deconv_shape1[3].value, 2048], 
                                        name="deconv1/kernel")
    b_t1 = deconv_utils.bias_variable([deconv_shape1[3].value], 
                                      name="deconv1/biases")
    deconv_t1 = deconv_utils.conv2d_transpose_strided(block4, W_t1, b_t1, 
                                       output_shape=tf.shape(block2))
    fuse1 = tf.add(deconv_t1, block2)
    print("deconv_t1: ", deconv_t1.shape)
    print("fuse_1: ", fuse1.shape)
    tf.identity(fuse1, name="fuse1")

    deconv_shape2 = block1.get_shape()
    W_t2 = deconv_utils.weight_variable([4, 4, deconv_shape2[3].value, 
                        deconv_shape1[3].value], name="deconv2/kernel")
    b_t2 = deconv_utils.bias_variable([deconv_shape2[3].value], 
                                      name="deconv2/biases")
    deconv_t2 = deconv_utils.conv2d_transpose_strided(fuse1, W_t2, b_t2, 
                        output_shape=tf.shape(block1))
    fuse2 = tf.add(deconv_t2, block1)
    print("deconv_t2: ", deconv_t2.shape)
    print("fuse2: ", fuse2.shape)
    tf.identity(fuse2, name="fuse2")

    shape = tf.shape(features)
    deconv_shape3 = tf.stack([shape[0], shape[1], shape[2], num_classes])
    W_t3 = deconv_utils.weight_variable([16, 16, num_classes, 
                       deconv_shape2[3].value], name="deconv3/kernel")
    b_t3 = deconv_utils.bias_variable([num_classes], name="deconv3/biases")
    deconv_t3 = deconv_utils.conv2d_transpose_strided(fuse2, W_t3, b_t3, 
                       output_shape=deconv_shape3, stride=8)
    print("deconv_t3: ", deconv_t3.shape)

Версия без пользовательских функций находится здесь:

    with tf.variable_scope("deconv_layer"):
    deconv1_shape = block2.get_shape()
    shape1 = [4, 4, deconv1_shape[3].value, 2048]
    deconv1_kernel = tf.Variable(initial_value=tf.truncated_normal(shape1, 
                                 stddev=0.02),
                                 trainable=True,
                                 name="deconv1/kernel")
    deconv1 = tf.nn.conv2d_transpose(value=block4,
                                     filter=deconv1_kernel,
                                     # output_shape=[BATCH_SIZE, 
                             tf.shape(block2)[1], tf.shape(block2)[2], 512],
                                     output_shape=tf.shape(block2),
                                     strides=[1, 2, 2, 1],
                                     padding='SAME',
                                     data_format='NHWC'
                                     )
    print('deconv1', deconv1.shape)
    fuse1 = tf.add(deconv1, block2)  # fuse1 = pool4 + deconv2(pool5)
    tf.identity(fuse1, name="fuse1")

    deconv2_shape = block1.get_shape()
    shape2 = [4, 4, deconv2_shape[3].value, deconv1_shape[3].value]
    deconv2_kernel = tf.Variable(initial_value=tf.truncated_normal(shape2, 
                                 stddev=0.02),
                                 trainable=True,
                                 name="deconv2/kernel")
    deconv2 = tf.nn.conv2d_transpose(value=fuse1,
                                     filter=deconv2_kernel,
                                     output_shape=tf.shape(block1),
                                     strides=[1, 2, 2, 1],
                                     padding='SAME',
                                     data_format='NHWC'
                                     )
    print('deconv2', deconv2.shape)
    fuse2 = tf.add(deconv2, block1)
    tf.identity(fuse2, name="fuse2")

    deconv3_shape = tf.stack([tf.shape(features)[0], tf.shape(features)[1], 
                              tf.shape(features)[2], num_classes])
    shape3 = [16, 16, num_classes, deconv2_shape[3].value]
    deconv_final_kernel = tf.Variable(initial_value=tf.truncated_normal(shape3, stddev=0.02),
                                      trainable=True,
                                      name="deconv3/kernel")

    seg_logits = tf.nn.conv2d_transpose(value=fuse2,
                                        filter=deconv_final_kernel,
                                        output_shape=deconv3_shape,
                                        strides=[1, 8, 8, 1],
                                        padding='SAME',
                                        data_format='NHWC') 

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Conv Net и Deconv Net в FCN, которые построены разными структурами, возможно, не согласуются друг с другом. В этом случае использование извещающей сети conv с padding='VALID', в то время как при развертывании используется все conv_transpose с padding='SAME. Таким образом, формы не совпадают, что вызывает проблему выше.

0 голосов
/ 23 октября 2018

У меня была похожая проблема при попытке воспроизвести функцию transposeconv2d pytorch в тензорном потоке. Я пытался выполнить заполнение входных данных перед тем, как перейти к функции conv2d_transpose () и снова выполнить заполнение выходных данных, полученных после преобразования. Это было причиной, по которой график был правильно инициализирован, но при расчете градиентов произошла ошибка. Я решил ошибку, удалив все ручные отступы и изменив отступ внутри "SAME" внутри функции. Я думаю, что это происходит внутри функции. Поправь меня, если я ошибаюсь. Я не знаю, насколько это влияет на фактический результат.

0 голосов
/ 03 июля 2018

Это из-за вашего шага> 1. Расчет не может быть верным во все времена. Это GitHub сообщение объясняет это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...