2016-02-18 3 views
19

Dostaję komunikat o błędzie podczas korzystania conv2d_transpose:Confused o conv2d_transpose

W tensorflow/core/common_runtime/executor.cc:1102] 0x7fc81f0d6250 Compute status: Invalid argument: Conv2DBackpropInput: Number of rows of out_backprop doesn't match computed: actual = 32, computed = 4 
[[Node: generator/g_h1/conv2d_transpose = Conv2DBackpropInput[T=DT_FLOAT, padding="SAME", strides=[1, 2, 2, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/cpu:0"](generator/g_h1/conv2d_transpose/output_shape, generator/g_h1/w/read, _recv_l_0)]] 

jednak występuje po wykres jest zbudowany podczas kompilacji funkcji straty (Adam). Jakieś pomysły na to, co by to spowodowało? Podejrzewam, że jest to związane z wymiarami wejściowymi, ale nie jestem do końca pewien, dlaczego.

Pełna błąd: https://gist.github.com/jimfleming/75d88e888044615dd6e3

odpowiedni kod:

# l shape: [batch_size, 32, 32, 4] 

output_shape = [self.batch_size, 8, 8, 128] 
filter_shape = [7, 7, 128, l.get_shape()[-1]] 
strides = [1, 2, 2, 1] 
with tf.variable_scope("g_h1"): 
    w = tf.get_variable('w', filter_shape, initializer=tf.random_normal_initializer(stddev=0.02)) 
    h1 = tf.nn.conv2d_transpose(l, w, output_shape=output_shape, strides=strides, padding='SAME') 
    h1 = tf.nn.relu(h1) 

output_shape = [self.batch_size, 16, 16, 128] 
filter_shape = [7, 7, 128, h1.get_shape()[-1]] 
strides = [1, 2, 2, 1] 
with tf.variable_scope("g_h2"): 
    w = tf.get_variable('w', filter_shape, initializer=tf.random_normal_initializer(stddev=0.02)) 
    h2 = tf.nn.conv2d_transpose(h1, w,output_shape=output_shape, strides=strides, padding='SAME') 
    h2 = tf.nn.relu(h2) 

output_shape = [self.batch_size, 32, 32, 3] 
filter_shape = [5, 5, 3, h2.get_shape()[-1]] 
strides = [1, 2, 2, 1] 
with tf.variable_scope("g_h3"): 
    w = tf.get_variable('w', filter_shape, initializer=tf.random_normal_initializer(stddev=0.02)) 
    h3 = tf.nn.conv2d_transpose(h2, w,output_shape=output_shape, strides=strides, padding='SAME') 
    h3 = tf.nn.tanh(h3) 
+0

Podobny problem został rozwiązany tutaj: http://stackoverflow.com/questions/36967872/tensorflow-conv2d-transpose-size-error-number-of-rows- out-backprop-doesnt-m –

Odpowiedz

29

Dzięki za pytanie! Masz dokładnie rację - problem polega na tym, że wymiary wejściowe i wyjściowe przekazywane do tf.nn.conv2d_transpose nie są zgodne. (Błąd może zostać wykryty przy obliczaniu gradienty, ale obliczanie gradientu nie jest problemem.) Wygląd

Przejdźmy już przy pierwszej części kodu i uprościć trochę:

sess = tf.Session() 
batch_size = 3 
output_shape = [batch_size, 8, 8, 128] 
strides = [1, 2, 2, 1] 

l = tf.constant(0.1, shape=[batch_size, 32, 32, 4]) 
w = tf.constant(0.1, shape=[7, 7, 128, 4]) 

h1 = tf.nn.conv2d_transpose(l, w, output_shape=output_shape, strides=strides, padding='SAME') 
print sess.run(h1) 

Wymieniłem zmienne na stałe - łatwiej zobaczyć, co się dzieje.

Jeśli próbujesz uruchomić ten kod, można uzyskać podobny błąd:

InvalidArgumentError: Conv2DCustomBackpropInput: Size of out_backprop doesn't match computed: actual = 32, computed = 4 
    [[Node: conv2d_transpose_6 = 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/cpu:0"](conv2d_transpose_6/output_shape, Const_25, Const_24)]] 

Teraz, błąd jest trochę mylące --- to mówi o „out_backprop” argument „Conv2DCustomBackpropInput”. Kluczem jest to, że tf.nn.conv2d_transpose jest w rzeczywistości tylko gradientem tf.nn.conv2d, więc Tensorflow używa tego samego kodu wewnętrznie (Conv2DCustomBackpropInput) do obliczenia gradientu tf.nn.conv2d i do obliczenia tf.nn.conv2d_transpose.

Błąd oznacza, że ​​żądany "output_shape" nie jest możliwy, biorąc pod uwagę kształty "l" i "w".

Od tf.nn.conv2d_transpose jest wstecznie (gradient) odpowiednikiem tf.nn.conv2d jeden sposób, aby zobaczyć, jakie są poprawne kształty powinny być jest użycie odpowiedniego naprzód operacji:

output = tf.constant(0.1, shape=output_shape) 
expected_l = tf.nn.conv2d(output, w, strides=strides, padding='SAME') 
print expected_l.get_shape() 
# Prints (3, 4, 4, 4) 

Że jest w kierunku do przodu, jeśli podałeś tensor kształtu "output_shape", wydostaniesz tensor kształtu (3, 4, 4, 4). Jednym ze sposobów rozwiązania problemu jest zmiana kształtu "l" na (3, 4, 4, 4); jeśli zmienisz powyższy kod na:

l = tf.constant(0.1, shape=[batch_size, 4, 4, 4]) 

wszystko działa poprawnie.

Generalnie spróbuj użyć tf.nn.conv2d, aby poznać relację między kształtami tensorów. Ponieważ tf.nn.conv2d_transpose jest jego wstecznym odpowiednikiem, ma on taką samą relację między kształtem wejściowym, wyjściowym i filtrującym (ale z odwróconymi rolami wejścia i wyjścia).

Nadzieję, że pomaga!

1

Korzystanie padding='SAME' w tf.nn.conv2d_transpose() funkcja może działa zbyt