《机器学习实战——基于Scikit-Learn和TensorFlow》
这是一本非常好的机器学习和深度学习入门书,既有基本理论讲解,也有实战代码示例。
我将认真阅读此书,并为每一章内容做一个知识笔记。
我会摘录一些原书中的关键语句和代码,若有错误请为我指出。
目录
第十三章 卷积神经网络
1 视觉皮层的组织结构
视觉皮层神经元有一个小的局部 接受野 。
高阶神经元是基于相邻的低阶神经元的输出。
2 卷积层
每一层的神经元只与上一层接受野内的像素相连接。
这种结构允许网络集中在第一个隐藏层的低阶特征中,然后在下一个隐藏层中将它们组装成比较高阶的特征。
零填充 使上下有相同的高和宽,在输入周围填充零。
步幅 两个连续的接受野之间的距离。
2.1 过滤器
***过滤器(卷积内核)***。
一层使用了相同过滤器的神经元提供给我们一个 特征图,其中与过滤器特征相似的部分得到强化。
2.2 多个特征图的叠加
卷积层同时对其输入使用多个过滤器,使之能够检测到输入的多个特征。
特征图中所有神经元共享参数能够显著减小模型中的参数数量,但更重要的是,这一特性意味着一旦CNN学会了识别某个位置上的某个模式,它就可以在任何地方识别该模式。
相比之下,传统的DNN学会识别某个位置上的某个模式,它只能在特定的位置识别该模式。
2.3 TensorFlow实现
import numpy as np
from sklearn.datasets import load_sample_images
# 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()
2.4 内存需求
CNN的一个问题是卷积层需要大量的内存,特别是在训练期间,因为反向传播的方向传递需要在正向传递期间计算所有的中间值。
如果训练因为内存不足而崩溃,可以:
- 减小批次尺寸
- 减少步幅
- 删除图层
- 16位浮点取代32位浮点
- 分布式
3 池化层
通过对输入图像进行 二次采样 以减小计算负载、内存利用率和参数数量(降低过拟合风险)。
减小输入图像的大小同样可以使神经网络容忍一定的图像位移。
必须定义接受野的大小、步幅、填充类型。
池化使用 聚合函数 聚合输入(最大值或平均)。
即使内核为2*2,步幅为2,两个方向的输出都会减小为原来的1/2,面积减小为1/4。
4 CNN架构
略。