《TensorFlow实战》读书笔记(完结)
1 TensorFlow基础
---1.1TensorFlow概要
- TensorFlow使用数据流图进行计算,一次编写,各处运行.
---1.2 TensorFlow编程模型简介
- TensorFlow中的计算是一个有向图,每一个运算操作都是一个节点.每一个节点可以有任意多个输入和输出,在计算图的边中流动(flow)的数据被称为张量(tensor).
- 一个运算操作代表了一种类型的抽象运算,运算操作的所有属性必须被预先设置,或者能在创建计算图时被推断出来.
- Variable为变量,在创建时赋值,它可以将tensor储存在内存或显存中.placeholder为形参,可以在计算图中赋值.
- Session是交互接口,通过Run方法可以执行计算图,TensorFlow会自动寻找所有需要计算的节点并按依赖顺序执行它们.
- TensorFlow可以根据链式法则自行计算梯度,从而实现反向传播.
- 在使用高阶语言的控制流时,它们会被自动编译为TensorFlow的原生控制流.
2 TensorFlow和其他深度学习框架的对比(略)
3 TensorFlow第一步
---3.1 TensorFlow的编译及安装(略)
---3.2 TensorFlow实现Softmax Regression识别手写数字
- 从TensorFlow自动导入MNIST数据集失败的话可以手动下载.
- 多分类任务最后一层通常使用Softmax,用于计算某个类的概率分布.而损失函数则选用交叉熵.
- TensorFlow算法设计的核心步骤是:
- 定义算法公式,也就是前向计算
- 定义loss,选定优化器,并且指定优化器优化loss
- 迭代地对数据进行训练
- 在测试集或验证集上对准确率进行评测
4 TensorFlow实现自编码器及多层感知机
---4.1 自编码器简介
- 使用少量的基本特征组合可以得到更高层抽象的特征,所以需要多层神经网络.
- 自编码器就是用自身的稀疏的高阶特征编码自己,输入节点和输出节点是一致的,因此需要加入几种限制以防单纯地复制:
- 减少中间隐含层节点的数量,并使用L1正则化控制稀疏程度
- 给数据加入噪声(如高斯噪声).
- 通过自编码器和监督学习的结合,可以解决梯度弥散问题,训练深层网络.也可以利用学习到的高阶特征来实现降维.
---4.2 TensorFlow实现自编码器
- 使用的是Xaiver初始化,它会根据某一层网络的输入和输出节点自动调整最合适的分布,也就是让权重满足均值为0,方差为2/(nin+nout).可以使用tf.random_uniform创建一个(-sqrt(6/(nin+nout)),sqrt(6/(nin+nout)))的均匀分布来实现.
- 将输入数据加上噪声,然后与权重w1相乘后加上偏置b1,再经过激活函数处理后得到隐含层的结果.将隐含层的结果与权重w2相乘后加上偏置b2就得到了输出.
- 损失函数选用平方误差.
- 训练前先对数据进行标准化处理,需要先在训练集上fit出一个scaler,然后将它用到训练和测试数据上.
- 去噪自编码器的实现和一个单隐含层的神经网络差不多,只不过在数据输入时做了标准化,并加上了高斯噪声,同时输出结果是复原的数据而非分类结果.
---4.3 多层感知机简介
- Dropout是在训练时将神经网络某一层的输出节点数据随机丢弃一部分(训练时小于1,预测时等于1),这等于创造出了很多新的随机样本,也算是一种bagging.
- ReLU解决了Sigmoid的梯度弥散问题,FCN和CNN的隐含层一般都使用ReLU及其变种,但是输出层一般还是使用接近概率输出分布的Sigmoid.主要变化是:
- 单侧抑制
- 相对宽阔的兴奋边界
- 稀疏激活性
---4.4 TensorFlow实现多层感知机
- ReLU层的权重可以用截断正态分布进行初始化,偏置可以用一些小的非零值来初始化以避免dead neuron.Sigmoid层的权重和偏置则都初始化为0即可.
- 使用ReLU作为隐藏层,并添加dropout,就实现了多层感知机.
5 TensorFlow实现卷积神经网络
---5.1 卷积神经网络简介
- CNN最初是为解决图像识别等问题而设计的,因为图像特征难以人工提取.
- CNN可以利用空间结构关系减少需要学习的参数,从而提高反向传播的效率.
- CNN的一个卷积层通常都进行以下操作:
- 通过卷积核的滤波并添加偏置,提取出局部特征.
- 将滤波输出结果进行非线性激活函数处理(如ReLU).
- 对激活函数的结果进行池化操作(如最大池化).
- 可以再加上BN层或LRN层.
- CNN一般由多个卷积层构成,每个卷积层可以对应多个卷积核,每个卷积核的输出图像对应一种图片特征.单个卷积核是权值共享的.
- 局部连接和权值共享降低了参数量,赋予了CNN对平移的容忍性,池化层降采样进一步降低了参数量,赋予了对轻度形变的容忍性,提高了泛化能力.
---5.2 TensorFlow实现简单的卷积网络
- 激活函数选用ReLU,所以使用截断的正态分布初始化权重来打破完全对称,使用小的正值(0.1)来初始化偏置以避免死亡节点.
- 两个卷积层,一个全连接层,一个Dropout层和一个Softmax层的CNN在MNIST上的准确率已经达到了99.8%.
---5.3 TensorFlow实现进阶的卷积网络
- CIFAR-10是一个经典的图像数据集,包含60000张32*32的彩色图片,训练集50000张,测试集10000张.这里按书下载数据集时出现了一些问题,于是手动将cifar10.py和cifar10_input.py移到了notebook的根目录下,并且在运行时添加以下代码:
tf.app.flags.DEFINE_string('f', '', 'kernel')
- 在这个CNN中使用了新的技巧:
- 对权重进行L2正则化,用于惩罚特征权重.
- 对图片进行翻转,随机剪切等数据增强,制造更多样本
- 在每个卷积-最大池化层后面使用了LRN层(现在一般用BN层替代),增强模型的泛化能力.
- 设计CNN主要就是安排卷积层,池化层,全连接层的分布和顺序,以及它们的超参数和Trick的使用.
- 深度学习的特点就是数据量越大效果越好,这与一般的机器学习模型不同.
6 TensorFlow实现经典卷积神经网络
---6.1 TensorFlow实现AlexNet
- AlexNet的新技术点:
- ReLU作为激活函数,解决了Sigmoid在网络较深时的梯度弥散问题
- Dropout随机忽略一部分神经元,避免过拟合
- 重叠的最大池化
- LRN层
- CUDA加速深度卷积网络的训练
- 数据增强,截取原始图像的部分增加训练数据量,预测时提取图片的四个角和中间位置,并进行左右翻转,对10个图片预测并求均值.
---6.2 TensorFlow实现VGGNet
- VGGNet全部使用3*3的卷积核和2*2的池化核,通过不断加深网络结构来提升性能.两个3*3的卷积核串联相当于1个5*5的卷积核,而且有更多的非线性变换.
- 在预测时使用滑窗的方式进行平均预测,在训练时将原始图像缩放到不同尺寸再随机裁切来增加数据量.
- VGGNet放弃了LRN层,通过多段卷积网络将图像变长缩小,卷积输出通道增加.
---6.3 TensorFlow实现Google Inception Net
- Inception V1去除了最后的全连接层,用全局平均池化层代替.
- 采用Inception Module结构,其中有4个分支:第一个分支是1*1卷积,第二个分支是1*1卷积连接3*3卷积,第三个分支是1*1卷积连接5*5卷积,第四个分支是3*3最大池化连接1*1卷积.最后通过聚合操作在输出通道数维度上进行合并.靠后的Inception Module应该捕捉更高阶的特征,因此大面积卷积核的占比会更高.
- 1*1卷积的性价比很高,可以跨通道组织信息,并对输出通道升降维.同时1*1卷积体现了Hebbian原理,即"一起发射的神经元会连在一起".
- Inception Net有22层深,其中间某一层会作为辅助分类节点,按一个小权重加到最终分类结果中.
- Inception V2用两个3*3的卷积代替5*5的卷积,并使用BN层,对每一个mini-batch数据进行标准化处理.BN某种意义上起到了正则化的作用,所以可以减少或取消Dropout和L2正则,简化网络结构.
- Inception V3采用Factorization into small convolutions思想,将一个较大的二维卷积拆成两个较小的一维卷积(如3*3卷积拆成3*1卷积和1*3卷积),节约了参数并减轻了过拟合.还优化了Inception Module的结构.
- 卷积网络从输入到输出,应该让图片尺寸逐渐减小,输出通道数逐渐增加,即将空间结构简化,将空间信息转化为高阶抽象的特征信息.
---6.4 TensorFlow实现ResNet
- ResNet的残差学习单元(Residual Unit)不再学习一个完整的输出H(x),而是学习残差H(x)-x.ResNet有很多支线将输入直接连到后面的层,使得后面的层可以直接学习残差,这种结构被称为shortcut.
- 两层的残差学习单元包含两个相同输出通道数的3x3卷积,三层的残差学习单元则是1x1卷积,3x3卷积,1x1卷积,并且先降维再升维.
7 TensorFlow实现循环神经网络及Word2Vec
---7.1 TensorFlow实现Word2Vec
- Word2Vec是一个将语言中的字词转化为向量形式表达的模型.
- One-Hot编码的问题是对特征的编码是随机的,没有考虑字词间的关系.并且稀疏数据的训练效率较低.
- 向量空间模型假设在相同语境中出现的词的语义也相近,分为计数模型(统计在语料库中相邻出现的词的频率)和预测模型(根据一个词周围的词推测出这个词).
- Word2Vec就是一种非常高效的预测模型,分为CBOW(Continuous Bag of Words,从原始语句推测目标词句)和Skip-Gram(从目标字词推测原始语句).
- CBOW训练一个二元的分类模型来区分真实的目标词汇和编造的词汇(噪声)两类.当模型预测真实的目标词汇为高概率时,学习目标就被最优化了.使用编造的噪声词汇训练的方法叫Negative Sampling,只需要计算随机选择的k个词汇,因此训练速度很快.对应的损失函数是Noise-Contrastive Estimation Loss.
- Skip-Gram需要先构造一个语境与目标词汇的映射关系,即为选定单词左边和右边滑窗尺寸数量的词汇.因为它是从目标词汇预测出语境,所以数据集就是(目标词汇,相邻单词).
---7.2 TensorFlow实现基于LSTM的语言模型
- RNN的特点是神经元的某些输出可作为输入再次传输到神经元中.但RNN难以记忆间隔太远的信息.LSTM解决了这个问题.