Min*_*ark 35 conv-neural-network tensorflow
该conv2d_transpose()操作的文档没有清楚地解释它的作用:
conv2d的转置.
在Deconvolutional Networks之后,此操作有时称为"反卷积" ,但实际上是conv2d的转置(渐变)而不是实际的反卷积.
我查看了文档指出的文件,但没有帮助.
这个操作有什么作用以及为什么要使用它的例子?
Yix*_*ing 23
这是从"渐变"角度来看的另一个观点,即为什么TensorFlow文档说conv2d_transpose()"实际上是转换(渐变)的转化而不是实际的反卷积".有关实际计算的详细信息conv2d_transpose,我强烈推荐这篇文章,从第19页开始.
在tf.nn有二维卷积4个密切相关,而混乱的功能:
tf.nn.conv2dtf.nn.conv2d_backprop_filtertf.nn.conv2d_backprop_inputtf.nn.conv2d_transpose一句话摘要:它们都只是2d卷积.它们的区别在于它们的输入参数排序,输入旋转或转置,步幅(包括小数步幅大小),填充等等.tf.nn.conv2d在手中,可以通过转换输入和更改conv2d参数来实现所有其他3个操作.
# forward
out = conv2d(x, w)
# backward, given d_out
=> find d_x?
=> find d_w?
Run Code Online (Sandbox Code Playgroud)
在前向计算中,我们计算输入图像x与滤波器的卷积,w结果是out.在反向计算中,假设我们给出了d_out,这是梯度wrt out.我们的目标是找到d_x和d_w,分别是梯度x和w.
为便于讨论,我们假设:
1in_channels和out_channels是1VALID填充从概念上讲,根据上述假设,我们有以下关系:
out = conv2d(x, w, padding='VALID')
d_x = conv2d(d_out, rot180(w), padding='FULL')
d_w = conv2d(x, d_out, padding='VALID')
Run Code Online (Sandbox Code Playgroud)
其中rot180是2D矩阵旋转180度(左右翻转和自顶向下的翻转),FULL是指"应用过滤器无论它部分地与输入重叠"(见theano文档).注意,这仅适用于上述假设,但是,可以更改conv2d参数以概括它.
关键要点:
d_x是输出梯度d_out和重量的卷积,并进行了w一些修改.d_w是输入x和输出梯度的卷积,并进行了d_out一些修改.现在,让我们给出一个实际工作代码示例,说明如何使用上面的4个函数来计算d_x和d_w给出d_out.这显示了
conv2d,
conv2d_backprop_filter和
conv2d_backprop_input,以及
conv2d_transpose彼此之间的关系.
请在此处找到完整的脚本.
d_x以4种不同方式进行计算:
# Method 1: TF's autodiff
d_x = tf.gradients(f, x)[0]
# Method 2: manually using conv2d
d_x_manual = tf.nn.conv2d(input=tf_pad_to_full_conv2d(d_out, w_size),
filter=tf_rot180(w),
strides=strides,
padding='VALID')
# Method 3: conv2d_backprop_input
d_x_backprop_input = tf.nn.conv2d_backprop_input(input_sizes=x_shape,
filter=w,
out_backprop=d_out,
strides=strides,
padding='VALID')
# Method 4: conv2d_transpose
d_x_transpose = tf.nn.conv2d_transpose(value=d_out,
filter=w,
output_shape=x_shape,
strides=strides,
padding='VALID')
Run Code Online (Sandbox Code Playgroud)
d_w以3种不同方式进行计算:
# Method 1: TF's autodiff
d_w = tf.gradients(f, w)[0]
# Method 2: manually using conv2d
d_w_manual = tf_NHWC_to_HWIO(tf.nn.conv2d(input=x,
filter=tf_NHWC_to_HWIO(d_out),
strides=strides,
padding='VALID'))
# Method 3: conv2d_backprop_filter
d_w_backprop_filter = tf.nn.conv2d_backprop_filter(input=x,
filter_sizes=w_shape,
out_backprop=d_out,
strides=strides,
padding='VALID')
Run Code Online (Sandbox Code Playgroud)
请参阅完整的脚本的执行tf_rot180,tf_pad_to_full_conv2d,tf_NHWC_to_HWIO.在脚本中,我们检查不同方法的最终输出值是否相同; 也可以使用numpy实现.
sim*_*o23 12
conv2d_transpose()只需转置权重并将它们翻转180度.然后它应用标准的conv2d()."Transposes"实际上意味着它改变了权重张量中"列"的顺序.请查看以下示例.
这里有一个使用带有stride = 1和padding ='SAME'的卷积的示例.这是一个简单的案例,但同样的推理可以应用于其他案例.
说我们有:
如果我们对输入进行卷积,那么意志的激活就会形成:[1,28,28,32].
activations = sess.run(h_conv1,feed_dict={x:np.reshape(image,[1,784])})
Run Code Online (Sandbox Code Playgroud)
哪里:
W_conv1 = weight_variable([7, 7, 1, 32])
b_conv1 = bias_variable([32])
h_conv1 = conv2d(x, W_conv1, strides=[1, 1, 1, 1], padding='SAME') + b_conv1
Run Code Online (Sandbox Code Playgroud)
要获得"反卷积"或"转置卷积",我们可以通过这种方式对卷积激活使用conv2d_transpose():
deconv = conv2d_transpose(activations,W_conv1, output_shape=[1,28,28,1],padding='SAME')
Run Code Online (Sandbox Code Playgroud)
或者使用conv2d()我们需要转置和翻转权重:
transposed_weights = tf.transpose(W_conv1, perm=[0, 1, 3, 2])
Run Code Online (Sandbox Code Playgroud)
这里我们将"colums"的顺序从[0,1,2,3]改为[0,1,3,2].所以从[7,7,1,32]我们将得到一个形状=的张量= [7,7,32,1].然后我们翻转重量:
for i in range(n_filters):
# Flip the weights by 180 degrees
transposed_and_flipped_weights[:,:,i,0] = sess.run(tf.reverse(transposed_weights[:,:,i,0], axis=[0, 1]))
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用conv2d()计算卷积:
strides = [1,1,1,1]
deconv = conv2d(activations,transposed_and_flipped_weights,strides=strides,padding='SAME')
Run Code Online (Sandbox Code Playgroud)
我们将获得与以前相同的结果.使用conv2d_backprop_input()也可以获得完全相同的结果:
deconv = conv2d_backprop_input([1,28,28,1],W_conv1,activations, strides=strides, padding='SAME')
Run Code Online (Sandbox Code Playgroud)
结果显示在这里:
测试conv2d(),conv2d_tranposed()和conv2d_backprop_input()
我们可以看到结果是一样的.要以更好的方式查看它,请查看我的代码:
https://github.com/simo23/conv2d_transpose
这里我使用标准的conv2d()复制conv2d_transpose()函数的输出.
conv2d_transpose 的一个应用是放大,下面是一个解释其工作原理的示例:
a = np.array([[0, 0, 1.5],
[0, 1, 0],
[0, 0, 0]]).reshape(1,3,3,1)
filt = np.array([[1, 2],
[3, 4.0]]).reshape(2,2,1,1)
b = tf.nn.conv2d_transpose(a,
filt,
output_shape=[1,6,6,1],
strides=[1,2,2,1],
padding='SAME')
print(tf.squeeze(b))
tf.Tensor(
[[0. 0. 0. 0. 1.5 3. ]
[0. 0. 0. 0. 4.5 6. ]
[0. 0. 1. 2. 0. 0. ]
[0. 0. 3. 4. 0. 0. ]
[0. 0. 0. 0. 0. 0. ]
[0. 0. 0. 0. 0. 0. ]], shape=(6, 6), dtype=float64)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23293 次 |
| 最近记录: |