2333, 还是一如既往的对什么都有兴趣,趁着这学期不忙,了解一些机器学习知识,跑几个小demo
在机器学习中,我们通常反复的实验,尝试不同的神经网络,修改层级数和神经元数量,已得到更优的模型。
图像是由大量像素点构成,而机器学习的输入只能是向量,所以,一般我没会把图片转换为[nn]的一个一维矩阵,这个过程叫做*扁平化**
在训练模型时,我们通常把数据集划分为不同的子集(训练集/测试集),原因是,当我们通过训练集训练模型后,我们希望通过模型没有见过的数据来看看模型的效果如何
通过测试数据集,我们可以使用网络从未见过的数据测试网络。这样我们便能检测模型的泛化程度,即泛化到训练期间未见过的数据的效果,而不是仅仅记住训练样本。
机器学习模型只有两种,一种是分类模型,一种是回归模型;区别在于我们是想得到一个数字,还是一组概率分布
密集层的概念
这是一种神经网络层级,他是完全连接的层级,所以Keras中称为密集层。这种连接灵活性很好,能够构建更庞大的网络,但是,有时候你可能一开始并不太了解到底应该如何设计网络,所以就设定一切都相互连接,这就是密集层。
当要解决的问题非线性时,我们可以通常在密集层添加一些数学函数,一遍可以达到更好的训练效果。如下面介绍的ReLU
修正线性单元 (ReLU)
ReLU 是修正线性单元的简称,他是一种激活函数,能够使模型解决非线性问题。并且是如下所示的数学函数:
如果输入是负数或 0,ReLU 函数的输出将是 0,如果输入是正数,那么输出将等于输入。
卷积神经网络CNN
卷积神经网络。即至少有一个卷积层的网络。典型的 CNN 还包括其他类型的层级,例如池化层和密集层
卷积层的原理是:创建另一个数字网格,叫做核或滤波器,然后利用核扫描图像,卷积层会将核应用到输入图像的各个区域(对于边缘像素,有多种解决方法,常见的一种为零填充)最终得到一个新的卷积图像。
卷积:是指向图像应用滤波器(核)的过程。
池化:通过总结区域减小输入图像大小的过程,新图像的大小取决于网格大小和步长;池化层有多种类型,常见的有平均池化、最大池化等
下采样:缩小图像,他的主要目的有两个:
- 使得图像符合显示区域的大小
- 生成对应图像的缩略图
CNN处理猫狗图片
两个挑战:
- 图片的尺寸不是固定的
- 图片是彩色的
挑战一:不同的图片尺寸
众所周知,神经网络要求输入尺寸是固定的,图片必须是固定大小的,如果才有之前衣服数据集的方法,将图像扁平化为一维数组,对于不同尺寸的图片,得到的数组大小是不一样的
解决方法是:始终将所有图片调整为相同尺寸(Resizing)
挑战二:如何处理彩色图像
计算机将灰度图像解析为二维数组,这个二维数组包含灰度图像对应的像素值,二维数组的宽高是由图像的尺寸决定的。
同理,计算机会将彩色图像解析为三维数组,三维数组的宽高是由图像的宽高决定的,深度由颜色通道数量决定。大多数彩色图像可以表示成三个颜色通道,分别是红绿蓝,这种图像被称为RGB图像。
在RGB图像中,每个颜色通道都有他自己的二维数组表示,由于有三个颜色通道,所以最终由三个二维数组,所以,对于RGB图像来说,他的深度等于红绿蓝通道对应的三个二维数组的堆叠层数
在调用函数时,三个参数,(x, y, d),之前模型中,因为是灰度图像,d设为了1
对彩色图像执行卷积运算
可以思考回顾一下灰阶图像的卷积操作
与灰阶图像的卷积操作类似,首先要选择特定尺寸的过滤器(3阶的),而且核的深度要与彩色图像的颜色通道数量一致,之后的卷积运算和灰阶图像一样(零填充,矩阵乘法),计算出每个颜色通道的卷积结果后,我没需要把他们相加起来,而且通过会再多加一个偏差值(通常为1),核对图像每个区域进行扫描后,就得到了卷积图像(二维数组)。
但是,对于彩色图像,通常会采用多个三维过滤器(当然也可以更多),这样就会得到三个卷积结果,我们可以将卷积结果看做三维数组,深度对应于过滤器数量
在代码中,我们通过设置filters来指定Conv2D层生成多少个输出结果,还可以通过kernel_size来指定三维过滤器的大小
1 | tf.keras.layers.Conv2D(filters, kernel_size, ...) |
注意,再训练CNN时,我们将更新三维核中的值,从而最小化损失函数
对彩色图像执行最大池化运算
最大池化和灰度图像的处理一样,只是处理后,得到的数据宽高会变小,深度不变
过拟合问题
训练次数过多时,会使网络开始过拟合或记住训练数据。有三种方法可以避免过拟合
早停法:验证集防止过拟合
判断过拟合的方法
查看训练损失和验证损失与周期的函数图,经过几个周期后,验证损失开始上升,而训练损失不断下降,并且再结束训练后,验证损失非常高,而训练损失非常低,这就表明升级网络过拟合训练数据,因为他无法很好的泛化到验证集上
启发:如果有多个潜在的模型结构可供选择,这种流程将会很有帮助。例如:如果你要决定再网络神经中添加多少个层级,你可以创建具有不同结构的各种模型,然后实验验证集比较他们,验证损失最低的结构将是最佳模型
疑问:为什么有了测试集,还需要设置验证集?直接使用测试集验证模型不行吗?
问题是,虽然再训练过程中,不适应验证集调试权重和偏差,但最终调试出的模型会同时再验证集和训练集上表现很好,所以神经网络最终将偏向于验证集,我们需要一个单独的测试集,实际检验模型泛化到从未见过的数据的效果
通过数据增强和丢弃,来避免过拟合
在训练CNN识别图像中的特定对象时,我们希望无论这些对象的大小和位置如何,CNN都能检测这些对象。对于各种可能的情况(如狗在左侧,中间,或者只有狗身体的一部分等),如果能有一个足够大的各种情况都有且量大的数据集,那么就可以训练出很好的模型,而且不会产生严重的过拟合。
但是,大多数时候,训练集并不包含很多不同的样本,在这种情况下,CNN有可能会过拟合,无法很好的泛化到之前没见过的数据上。对于这个问题,我们可以使用图像增强技巧来避免。
图像增强:是指通过对原始训练集应用各种随即图像转换,创造新的训练图像
丢弃是帮助避免过拟合的另一个技巧
我们知道,在训练过程中,神经网络通过调整权重和偏差来最小化 损失函数
一种方法是,在不同的训练周期中,指定每个神经元被丢弃的概率,这样就能很好的避免过拟合,还可以使网络变得更有弹性。因为他无法依赖于解决问题能用到的所有神经元,最终,其他神经元将能够起到作用
熟悉代码
1 | %matplotlib inline |