2017-07-07 62 views
1

我試圖用Tensorflow構建一個變分自動編碼器。我從最簡單的模型開始。我有以下方法:修正Tensorflow中的去卷積層

def conv_layer(x, w_shape, b_shape, padding='SAME'): 
    W = weight_variable(w_shape) 
    tf.summary.histogram(W.name, W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram(b.name, b) 

    # Note that I used a stride of 2 on purpose in order not to use max pool layer. 
    activations = tf.nn.relu(tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding=padding) + b) 
    tf.summary.histogram(activations.name, activations) 
    return activations 

def deconv_layer(x, w_shape, b_shape, padding="SAME"): 
    W = weight_variable(w_shape) 
    tf.summary.histogram(W.name, W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram('bias', b) 

    x_shape = tf.shape(x) 

    out_shape = tf.stack([x_shape[0], x_shape[1], x_shape[2], w_shape[2]]) 
    # Note that I have used a stride of 2 since I used a stride of 2 in conv layer. 
    transposed_activations = tf.nn.conv2d_transpose(x, W, out_shape, [1, 1, 1, 1], padding=padding) + b 
    tf.summary.histogram(transposed_activations.name, transposed_activations) 
    return transposed_activations 

而整個網絡的模型如下:

with tf.name_scope('conv1'): 
    conv1 = conv_layer(image, [3, 3, 3, 32], [32]) 
with tf.name_scope('conv2'): 
    conv2 = conv_layer(conv1, [3, 3, 32, 64], [64]) 
with tf.name_scope('conv3'): 
    conv3 = conv_layer(conv2, [3, 3, 64, 128], [128]) 
with tf.name_scope('conv4'): 
    conv4 = conv_layer(conv3, [3, 3, 128, 256], [256]) 

with tf.name_scope('z'): 
    z = conv_layer(conv4, [3, 3, 256, 256], [256]) 

with tf.name_scope('deconv4'): 
    deconv4 = deconv_layer(z, [3, 3, 128, 256], [128]) 
with tf.name_scope('deconv3'): 
    deconv3 = deconv_layer(deconv4, [3, 3, 64, 128], [64]) 
with tf.name_scope('deconv2'): 
    deconv2 = deconv_layer(deconv3, [3, 3, 32, 64], [32]) 
with tf.name_scope('deconv1'): 
    deconv_image = deconv_layer(deconv2, [3, 3, 3, 32], [3]) 

我從FIFOQueue讓我的圖像,並將它們送入這一模式。我的圖像尺寸是112, 112, 3。我的問題是在這兩個CONVdeconv層我有以下錯誤從 [1, 1, 1, 1] to [1, 2, 2, 1]改變步幅時:

InvalidArgumentError (see above for traceback): Conv2DSlowBackpropInput: Size of out_backprop doesn't match computed: actual = 4, computed = 2 
    [[Node: deconv4/conv2d_transpose = Conv2DBackpropInput[T=DT_FLOAT, data_format="NHWC", padding="SAME", strides=[1, 2, 2, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/gpu:0"](deconv4/stack, deconv4/Variable/read, z/Relu)]] 
    [[Node: deconv1/add/_17 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_85_deconv1/add", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]] 

PS:我知道,我的思念在deconv層的激活功能,但我猜這與我得到的錯誤沒有關係。 任何幫助非常感謝!

+0

我有同樣的錯誤。你解決了嗎? – freude

+0

@幸運,希望我的回答對你有意義。請喜歡,如果你確信。 –

+0

@freude,我很好地調整了解決方案。我忘了提及輸出形狀的問題。請檢討最終答案,並接受它,如果你確信!謝謝 –

回答

0

這樣做的原因錯誤是如下:

如果我們假定我們有stride = 2在每個CONV層,然後,在我的情況下,當輸入圖像的大小爲112, 112, 3,每個conv layer大小後framesfeature maps在應用卷積後減半。也就是說,在conv1之後,圖像的大小(高度,寬度)變爲[56, 56]。在conv2之後,尺寸變成[28, 28]conv3之後:[14, 14],之後conv4[7, 7]。因此,應用一個名爲z的額外conv layer已將尺寸減小到[3, 3]。這是問題:7不能被2整除。所以我們得到了不同的維度。從[3, 3][112, 112]從申請deconv layer後是不可能的。此外:

[3, 3] -> [6, 6] -> [12, 12] -> [24, 24] -> [48, 48] 

第二錯誤:在deconv layer輸出形狀應該如下:

# we should multiply x_shape[1] and x_shape[2] by 2. 
out_shape = tf.stack([x_shape[0], x_shape[1] * 2, x_shape[2] * 2, w_shape[2]]) 

因此,最終deconv layer變爲如下:

def deconv_layer(x, w_shape, b_shape, is_training, padding="SAME", activation='selu'): 
    W = weight_variable(w_shape) 
    tf.summary.histogram("weights", W) 

    b = bias_variable(b_shape) 
    tf.summary.histogram('biases', b) 

    x_shape = tf.shape(x) 
    # output shape: [batch_size, h * 2, w * 2, input_shape from w]. 
    out_shape = tf.stack([x_shape[0], x_shape[1] * 2, x_shape[2] * 2, w_shape[2]]) 
    # Note that I have used a stride of 2 since I used a stride of 2 in conv layer. 
    if activation == 'selu': 
     conv_trans = tf.nn.conv2d_transpose(x, W, out_shape, [1, 2, 2, 1], padding=padding) + b 

     transposed_activations = tf.nn.elu(conv_trans) 

    else: 
     conv_trans = tf.nn.conv2d_transpose(x, W, out_shape, [1, 2, 2, 1], padding=padding) + b 
     transposed_activations = tf.nn.sigmoid(conv_trans) 

    tf.summary.histogram("transpose_activation", transposed_activations) 
    return transposed_activations 

因此,大小的輸出與輸入的大小不同,這就是我得到錯誤的原因。而爲了做back propagation我們需要一個成本函數。此成本函數將取決於outputinput。因此,如果他們有不同的大小,那會導致錯誤。

可以解決的方法是讓conv layer, z,擁有stride of 1

0

當上述代碼中的步幅爲[1, 2, 2, 1]時,inputdeconv_image的形狀不匹配。這種情況下的decov_image大小將爲[64x64]。你在代碼中的其他地方照顧這個嗎?

+0

當我修改了deconv層的out_shape到: 'out_shape = tf.stack([x_shape [0],x_shape [1] * 2,x_shape [2] * 2,w_shape [2]])'It解決了。也許這是錯誤的根源。這是有道理的。 –