TensorFlow中重要的数据结构
鸢尾花数据集案例
使用机器学习的方法和深度学习的方法做了一个流程的对比
深度学习与机器学习之间的区别和联系
深度学习是机器学习的一个发展方向,到目前为止发展最好的
机器学习做数据的预处理可能需要一些专业的知识,在深度学习里面,不用人工去做这些数据的预处理,深度学习模型特别是卷积神经网络能够自动提取特征,正式因为这样的操作,导致深度学习模型可解释性差,是一个黑盒操作
神经网络:
是一个仿照人类的神经系统用来表示数据的计算的方式的模型
单元结构:
注意:每个神经元之间的连线代表一个权重
激活函数
引入非线性激活函数的目的就是让深度学习模型能够在样本线性不可分的情况下达到好的效果
Sigmoid
处处可导,关于点(0,0.5)对称
导数的取值范围:(0, 1/4]
tanh:
处处可导,关于原点对称,值域是(-1, 1)
导数的取值范围:(0,1]
Relu(rectified linear unit):
现阶段使用的最为广泛的一种激活函数
输入如果小于0,导数值为0
leaky Relu:
在RELU的基础上做了一些修改
如果训练深层神经网络模型的时,使用RELU达不到更好的效果,可以尝试使用它
softmax:
应用场景:一般用在输出层的不同类别概率结果输出
激活函数的选择:
隐藏层:一般优先选择使用RELU,如果效果不理想,在去选择使用LeakyRELU,缺陷是可能会导致大批量的神经元死亡,我们一般可以去初始化一个较小的学习率去缓解这个问题
分类任务:
回归问题:使用恒等映射 y = x
深度学习模型的参数初始化的意义及常用方式
意义:让模型快速收敛
常用的方式:
1、随机初始化:使用标准正态分布随机出来的数值来初始化参数
2、注意:深度学习里面,参数一般指:权重、偏置、卷积核的模板中的权重
3、Xavier初始化(Glorot初始化)
/1、正态化初始化:tf.keras.initializers.glorot_normal()
特点:它从以 0 为中心,标准差为 stddev = sqrt(2 / (fan_in + fan_out)) 的正态分布中抽取样本
limit 是 sqrt(6 / (fan_in + fan_out))论文中指出这样的初始化方法配合tanh和softsign激活函数使用效果更好
4、He初始化
1、正态化He初始化:tf.keras.initializers.he_normal()
stddev = sqrt(2 / fan_in) 的截断正态分布中抽取样本limit 是 sqrt(6 / fan_in)论文中指出这样的初始化方法与RELU或者RELU系列的激活函数搭配使用效果更好
模型的构建
方式:1、通过Sequantial的方式去构建;2、通过继承Model抽象子类进行构建;3、通过函数式的方式构建 深度学习的优缺点:
优点:精度高,可以近似任意函数
常见损失函数:
常见的优化方法:
SGD,随机梯度下降,在TensorFlow中SGD这个API一般指的是小批量梯度下降,tf.keras.optimizers.SGD(learning_rate=0.1)
常用术语:
epoch:表示将在整个数据集交给模型训练多少遍
iteration(step):表示训练完所有的epoch所需要的迭代的次数
反向传播(BP,backward propagation):
前向反馈,得到预测值
对比预测值和真实值之间的差距(损失函数)
使用反向传播去进行求导,更新前面神经网络层中的参数
链式求导法则:对复合函数的求导
梯度下降中(损失函数优化的过程中)经常会遇到这些问题:
在平坦区域下降很慢
找到的是鞍点,非极值点
找到的是非全局最优解,而是局部最优解
解决方法:
鞍点问题:使用动量算法优化,使用指数加权平均对原始的梯度进行一个加权平均操作,将之前计算出来的梯度也考虑了进来
API:tf.keras.optimizers.SGD(learning_rate=0.1, momentum=0.9)
Nesterov accelerated gradient(NAG):tf.keras.optimizers.SGD(learningrate=0.1, momentum=0.9)tf.keras.optimizers.SGD(learningrate=0.1, momentum=0.9, nesterov=True)
在接近最优解时在最优解附近来回振荡,无法快速收敛:使用AdamGrad优化方法去解决,它的思想是越往后训练,学习率的值越小
API:
python
tf.keras.optimizers.Adagrad(
learning_rate=0.001, initial_accumulator_value=0.1, epsilon=1e-07
)
解决AdaGrad后期学习率过小,无法快速收敛:RMSprop进行优化(加权平均)
API:
python
tf.keras.optimizers.RMSprop(
learning_rate=0.001, rho=0.9, momentum=0.0, epsilon=1e-07, centered=False,
name='RMSprop', **kwargs
)
Adam:综合了momentum和RMSprop的优势,即对学习率做了修正,又对梯度进行了修正
没有经验性的调参建议,那么优先使用Adam
API:
python
tf.keras.optimizers.Adam(
learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07
)
学习率退火(在模型训练的过程中,通过callbacks回调函数调用)
1/t衰减
常用正则化方法:
L1、L2、L1L2正则化
Dropout:让模型在训练的过程中随机的让部分神经元失活(不参与到模型的计算),rate是神经元失活的概率,其它没有被失活的神经元的输入的值变成了 原始值/(1-rate)
Dropout API:layer = tf.keras.layers.Dropout(0,input_shape=(2,))
Early stopping:通过在模型训练过程中产生的指标,例如训练误差和验证误差进行一个观察,如果当训练误差不断减小的过程中,验证误差经历了达到最小后上升的过程,那么我们就可以断定当验证误差最小时,是当前条件下模型的最优表现,那么我们就可以设定对应的迭代阈值,让模型的训练及时停止
API实现:
python
tf.keras.callbacks.EarlyStopping(
monitor='val_loss', patience=5
)
使用是在模型的训练过程中添加回调函数即可:
python
model.fit(X, Y, epochs=10, batch_size=1, callbacks=[callback], verbose=1)
批标准化(BN, batch normalization):
在输入到下一层网络进行计算前,将前一层的每个神经元的输出进行标准化处理(计算每一个批次样本的均值和方差),对最后标准化的结果再做一个线性缩放,其中 $$\gamma$$ 和 $$\beta$$ 这两个参数也是需要在反向传播中和其它参数一起被优化
API:
python
tf.keras.layers.BatchNormalization(
epsilon=0.001, center=True, scale=True,
beta_initializer='zeros', gamma_initializer='ones',
)
简易全连接层的神经网络案例:
1、数据加载
mnist手写数字图片数据,每一张图片都是28*28的大小,训练集有60000个样本,测试集有10000个样本
python
from tensorflow.keras.datasets import mnist
mnist.load_data()
2、数据处理
首先,因为我们使用的是全连接层,所以要将特征向量展开成一维的特征向量,使用reshape改变特征向量的形状
最后对数据进行归一化,减少计算量
3、模型构建
4、模型训练
引入Tensorboard实现模型训练过程参数的可视化以及模型计算过程的可视化
先进入到对应的虚拟环境,然后使用命令行启动tensorboard服务,使用浏览器访问它提供的链接,即可看到可视化后的结果
5、模型评估
model.evaluate()
6、模型的保存与加载
保存:model.save(),一般以h5的格式保存模型文件
加载:tf.keras.models.load_model()
全连接网络的局限性:
数据量大,造成模型的训练效率比较低下
无法正确表示特征之间的关联,对于模型去提取一些关键特征来说影响较大
卷积神经网络:
提高模型的训练效率,同时更好的去提取和表征原始数据的特征
主要组成结构:
卷积层、池化层、全连接层、激活层
1、卷积层:提取特征
卷积核:就是前面OpenCV中提到的滤波器,是带有权重的一种计算结构
padding:当我们需要指定输出的feature map的大小是可以指定padding的大小,一般的选择是‘same’或者‘valid’。
stride:卷积核进行滑动扫描提取特征时的步长是多少
多通道卷积:对应通道的卷积核与特征图进行卷积操作,然后将所有通道的卷积结果按位置相加,即得最后的输出feature map
多卷积核卷积:最后得到的feature map的通道数只与卷积核的个数相等
输出的feature map大小的计算方式:
输入的图片:H1 x W1 X C1
卷积操作:
卷积核个数K
零填充大小P
输出的feature map的大小:
高:H2 = (H1 - F + 2P)/ S + 1
通道数:C2 = K
API 实现:
python
tf.keras.layers.Conv2D(
filters, kernel_size, strides=(1, 1), padding='valid',
activation=None
)
2、激活层:获取非线性输出,让模型具有非线性样本的处理能力
3、池化层:对提取后的特征进行降维
最大池化
通过扫描窗口扫描特征图,在窗口内的最大值作为最终的输出结果
API:
python
tf.keras.layers.MaxPool2D(
pool_size=(2, 2), strides=None, padding='valid'
)
平均池化
通过扫描窗口扫描特征图,在窗口内的所有特征的平均值作为最终的输出结果
API:
python
tf.keras.layers.AveragePooling2D(
pool_size=(2, 2), strides=None, padding='valid'
)
4、全连接层:一般用来输出结果,将最后得到的feature map展开成一维的特征向量,然后进行分类或者回归操作
图像分类
目的:为了给输入的图片贴上类别标签
AlexNet:
引入了图像增强,让模型提取的特征更加丰富 卷积核大小对特征提取的影响:
卷积核越大,提取特征后特征图的大小越小,忽略一些局部特征,得到的描述是全局的(宏观的)的特征,反之,提取的都是一些细节(局部)特征。
神经网络的层数(深度)对模型的影响:
参数和超参数的区别:
感受野(receptived field):
VGG:
GoogLeNet:
ResNet(Residual Net):
图像增强:
模型的微调(fine-tuning):