TensorFlow 实现
在 Tensorflow 中,每个输入图像的通常被表示为三维张量 。 一个小批次被表示为四维张量 。 卷积层的权重被表示为四维张量 。 卷积层的偏差项简单地表示为一维形状的张量 。我们来看一个简单的例子。 下面的代码使用 Scikit-Learn 的load_sample_images()
(加载两个彩色图像,一个中国庙宇,另一个是一朵花)加载两个样本图像。 然后创建两个7×7
的卷积核(一个中间是垂直的白线,另一个是水平的白线),并将他们应用到两张图形中,使用 TensorFlow 的conv2d()
函数构建的卷积图层(使用零填充且步幅为 2)。 最后,绘制其中一个结果特征映射(类似于图 13-5 中的右上图)。
from sklearn.datasets import load_sample_image
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
if __name__ == '__main__':
# Load sample images
china = load_sample_image("china.jpg")
flower = load_sample_image("flower.jpg")
dataset = np.array([china, flower], dtype=np.float32)
batch_size, height, width, channels = dataset.shape
# Create 2 filters
filters = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32)
filters[:, 3, :, 0] = 1 # vertical line
filters[3, :, :, 1] = 1 # horizontal line
# Create a graph with input X plus a convolutional layer applying the 2 filters
X = tf.placeholder(tf.float32, shape=(None, height, width, channels))
convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME")
with tf.Session() as sess:
output = sess.run(convolution, feed_dict={X: dataset})
plt.imshow(output[0, :, :, 1], cmap="gray") # plot 1st image's 2nd feature map
plt.show()
大部分代码是不言而喻的,但conv2d()
这一行值得解释一下:
X
是输入小批次(4D 张量,如前所述)- 卷积核是应用的一组卷积核(也是一个 4D 张量,如前所述)。
- 步幅是一个四元素的一维数组,其中两个中间的值是垂直和水平的步幅(
sh
和sw
)。 第一个和最后一个元素现在必须等于 1。他们可能有一天会被用来指定批量步长(跳过一些实例)和频道步幅(跳过上一层的特征映射或通道)。 padding
必须是"VALID"
或"SAME"
:- 如果设置为
"VALID"
,卷积层不使用零填充,并且可能会忽略输入图像底部和右侧的某些行和列,具体取决于步幅,如图 13-7 所示(为简单起见, 这里只显示水平尺寸,当然,垂直尺寸也适用相同的逻辑) - 如果设置为
"SAME"
,则卷积层在必要时使用零填充。 在这种情况下,输出神经元的数量等于输入神经元的数量除以该步幅,向上舍入(在这个例子中,ceil(13/5)= 3
)。 然后在输入周围尽可能均匀地添加零。
- 如果设置为
不幸的是,卷积图层有很多超参数:你必须选择卷积核的数量,高度和宽度,步幅和填充类型。 与往常一样,您可以使用交叉验证来查找正确的超参数值,但这非常耗时。 稍后我们将讨论常见的 CNN 体系结构,以便让您了解超参数值在实践中的最佳工作方式。