tensorflow实现卷积和反卷积

卷积:tf.nn.conv2d函数

参考链接 https://www.cnblogs.com/qggg/p/6832342.html

函数原型:
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

input是一个Tensor,[batch, in_height, in_width, in_channels]
filter是一个tensor,[filter_height, filter_width, in_channels, out_channels]
strides是步长,卷积时在图像每一维的步长,这是一个一维的向量,长度4
padding:string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同的卷积方式
use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true

结果返回一个Tensor,这个输出,就是我们常说的feature map,shape仍然是[batch, height, width, channels]这种形式。

测试代码:

import tensorflow as tf
input = tf.Variable(tf.random_normal([4,127,127,3]))
filter = tf.Variable(tf.random_normal([11,11,3,96]))

op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='VALID')

with tf.Session() as sess:
    a = np.reshape(np.arange(193548),(4,127,127,3))
    b = np.reshape(np.arange(34848),(11,11,3,96))

    ops_=sess.run(op,feed_dict={input:a,filter:b})
    print(ops_.shape)
#输出结果为:(4, 59, 59, 96)

反卷积:tf.nn.conv2d_transpose函数

参考链接 https://blog.csdn.net/mieleizhi0522/article/details/80441571

函数原型:
tf.conv2d_transpose(value, filter, output_shape, strides, padding=”SAME”, data_format=”NHWC”, name=None)

第一个参数value:指需要做反卷积的输入图像,它要求是一个Tensor
第二个参数filter:卷积核,它要求是一个Tensor,具有[filter_height, filter_width, out_channels, in_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,卷积核个数,图像通道数]
第三个参数output_shape:反卷积操作输出的shape,细心的同学会发现卷积操作是没有这个参数的.
第四个参数strides:反卷积时在图像每一维的步长,这是一个一维的向量,长度4
第五个参数padding:string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同的卷积方式
第六个参数data_format:string类型的量,’NHWC’和’NCHW’其中之一,这是tensorflow新版本中新加的参数,它说明了value参数的数据格式。’NHWC’指tensorflow标准的数据格式[batch, height, width, in_channels],’NCHW’指Theano的数据格式,[batch, in_channels,height, width],当然默认值是’NHWC’

测试代码

import tensorflow as tf
tf.set_random_seed(1)
x = tf.random_normal(shape=[1,3,3,1])
#正向卷积的kernel的模样
kernel = tf.random_normal(shape=[2,2,3,1])

# strides 和padding也是假想中 正向卷积的模样。当然,x是正向卷积后的模样
y = tf.nn.conv2d_transpose(x,kernel,output_shape=[1,5,5,3],
    strides=[1,2,2,1],padding="SAME")
# 在这里,output_shape=[1,6,6,3]也可以,考虑正向过程,[1,6,6,3]
# 通过kernel_shape:[2,2,3,1],strides:[1,2,2,1]也可以
# 获得x_shape:[1,3,3,1]
# output_shape 也可以是一个 tensor
sess = tf.Session()
tf.global_variables_initializer().run(session=sess)

print(y.eval(session=sess).shape)   #(1, 5, 5, 3)

———————————————————-分割线————————————————————————–
 
将卷积和反卷积融合在一起,卷积的输出作为反卷积的输入,测试代码:

import tensorflow as tf
input = tf.Variable(tf.random_normal([1,127,127,3])) #正向过程的输入
filter = tf.Variable(tf.random_normal([11,11,3,96])) #正向过程的kernel

input2 = tf.Variable(tf.random_normal([1,59,59,96]))  #反向过程的输入
filter2 = tf.Variable(tf.random_normal([11,11,3,96])) #反向过程的核,其实和正向过程的核是一样的

conv = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='VALID')
deconv = tf.nn.conv2d_transpose(input2,filter2,output_shape=[1,127,127,3],
    strides=[1,2,2,1],padding="VALID")

with tf.Session() as sess:
    a = np.reshape(np.arange(48387),(1,127,127,3))
    b = np.reshape(np.arange(34848),(11,11,3,96))

    ops_=sess.run(conv,feed_dict={input:a,filter:b})
    print(ops_.shape)  #卷积层的输出,也是反卷积层的输入  (1, 59, 59, 96)

    ops2_ = sess.run(deconv,feed_dict={input2:ops_,filter2:b})
    print(ops2_.shape)   #(1, 127, 127, 3)

猜你喜欢

转载自blog.csdn.net/aaon22357/article/details/82711692