★tensorflow中“卷积”的深度解析

2019-07-07  本文已影响0人  马尔代夫Maldives

两点结论:

(1)单个独立卷积核的通道数=输入图像的通道数(输入图像决定);
(2)独立卷积核的个数=输出图像的通道数(用户决定)。

注意:

在描述卷积核时,“卷积核通道数”这个概念必须搞清楚,是指“单个独立卷积核的通道数”,还是指独立卷积核的个数(输出通道数)
例:
假如输入图像的规模为32×32×128,即输入通道数为128;
那么根据前面(1)可知单个卷积核的通道数也是128,即卷积核尺寸应该为:n×n×128(n通常为3、5、7等)。
假如用256个这样的卷积核对输入进行卷积,则最后得到的输出图像尺寸为(根据前面(2)):(32-n+1)×(32-n+1)×256,即输出图像有256个通道(一个卷积核得到一个输出结果,也就是一个通道,相当于把原来只有128层的图像,扩展到了256层)。
可见,本次所有卷积核尺寸(或者说卷积核的总参数个数)是:n×n×128×256
需要注意的是,很多时候在描述卷积核时,通常会忽略单个卷积核的通道数,而保留了卷积核个数,如上面的总卷积核简写为:n×n×256,省略了128,这么写是有道理的,因为这4个参数中128这个参数是由输入图像的通道数决定的,而其他三个参数则是由用户决定的。
因此在解读卷积核尺寸时,必须搞清楚,第三个参数是输入通道数还是卷积核个数。判断标准就是前面的(1)和(2)两点结论。

1. 关于通道(channels)

图片通道channel:通常jpg等彩色图片由R、G、B三个图层构成,每个图层实际上就是一个二维矩阵,也就是所谓的一个通道,因此一个彩色图片通常有3个通道,而一个黑白图片就只有一个通道。
tensorfllow中的“输入通道in_channels”:输入图像的通道数。
tensorfllow中的“输出通道out_channels”:输出图像的通道数。

最初输入的图片样本的 channels ,取决于图片类型,比如RGB;
卷积操作完成后输出的 out_channels ,取决于卷积核的数量。此时的 out_channels 也会作为下一次卷积时的卷积核的 in_channels;
卷积核中的 in_channels ,就是上一次卷积的 out_channels ,如果是第一次做卷积,就是输入本图片的 channels 。

2. 函数解析

tf.nn.conv2d()是TensorFlow里面实现卷积的函数,其调用方式如下:

result = tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

3. tensorflow图像卷积过程

下图展示了对一张3通道jpeg图片进行两次连续卷积操作的过程:


cgx-tensorflow二维卷积过程解析.jpg

4. 一般卷积网络解读示例(根据前面知识)

卷积网络结构解读.png 卷积网络结构解读2.png

5. Conv2D()如何定义一个卷积层?

图片1.jpg

6. tensorflow图像卷积实例

import tensorflow as tf
import matplotlib.pyplot as plt

sess  = tf.InteractiveSession()

# 二维卷积核大小(多个二维卷积核组成一个三维卷积核)
kernel_size = 7
# 卷积步长
stride_size = 3
# 输出通道数(三维卷积核个数,或输出特征图个数)
out_channels = 4 
 
# 读入图像文件
image_value = tf.read_file('./cgx.jpg')
# 图像解码
img = tf.image.decode_jpeg(image_value, channels=3)
# print(img.eval().shape) #原始图片维度
img_hight = img.eval().shape[0] #得到图像的高度维
img_width = img.eval().shape[1] #得到图像的宽度维
img_inchannels = img.eval().shape[2] #对于jpg图片为3

# 显示图片
plt.figure(1)
plt.imshow(img.eval()) #完整图像
# plt.imshow(img.eval()[:,:,0]) #G层
# plt.imshow(img.eval()[:,:,1]) #B层
# plt.imshow(img.eval()[:,:,2]) #R层
plt.show()

# # 格式转换,转化成浮点数便于计算
img = tf.to_float(img, name='ToFloat')

# 将图片转化成适合tensorflow卷积的格式
# 第一个参数1是输入图片张数,最后一个3个RGB3个维度
batch_shape = (1,img_width,img_hight,img_inchannels)
input_img = tf.reshape(img,batch_shape)

# 生成卷积核
filter = tf.Variable(tf.random_normal([kernel_size,kernel_size,img_inchannels,out_channels]))
# 卷积步长定义
strides_shape =[ 1,stride_size,stride_size,1]
# 调用conv2d()函数计算二维卷积
my_conv2d = tf.nn.conv2d(input_img, filter, strides_shape, padding='VALID')

##############################################################################################
#执行会话
# 调用sess初始化变量
sess.run(tf.global_variables_initializer())
#调用sess.run()执行卷积操作
feature_maps = sess.run(my_conv2d) #numpy.ndarray数组,shape=[原始图片张数,卷积后的高,卷积后的宽,特征图张数]

print('原始图像维度:[原始图片张数,图片高,图片宽,图片通道数]={}'.format(input_img.shape))
print('卷积图像维度:[原始图片张数,特征图高,特征图宽,特征图张数]={}'.format(feature_maps.shape))

# 展示每所有特征图
for i in range(feature_maps.shape[3]):
    print("第{}个特征图:".format(i+1))
    plt.imshow(feature_maps[0,:,:,i],cmap='gray') #第一个特征图
    plt.show()

# 关闭会话
sess.close()

输出结果:


卷积结果.png

5. 参考链接

https://www.cnblogs.com/welhzh/p/6607581.html
https://www.jianshu.com/p/abb7d9b82e2a
https://www.imooc.com/article/details/id/29525
https://cloud.tencent.com/developer/article/1341522
https://www.cnblogs.com/billux/p/9072173.html

上一篇下一篇

猜你喜欢

热点阅读