| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> 2021-08-05 -> 正文阅读 |
|
[人工智能]2021-08-05 |
最近邻算法:(比较两幅图片) ? ?? 最近邻分类器代码: Train():用来存储训练数据 测试的时候,对测试图像使用L1距离函数,将测试图片与训练实例进行比较,然后再训练集中找到最相似的实例。 最近邻算法的缺点:训练很快,但测试很慢,这与我们的要求刚好相反。因为训练都是在运算量很大的后台机器进行,而测试我们希望在手机、网页等低功耗设备上进行,所以说最近邻算法无法满足我们的要求。 下面看卷积神经网络和其他参数模型则刚好相反,他们将更多的时间用在训练上,而在测试上非常快。 K近邻算法:(KNN) 不只是寻找最近的点,做一些特殊的操作,根据我们的距离度量,找到最近的K个点,然后在这些相邻点中进行投票,然后票数多的近邻点,预测出结果。 L2距离(欧氏距离): 注:L2距离并不适合用来表示图像间视觉感知的差异 如何根据你的问题和数据,选择像距离、k值这些超参数? 千万不要根据对于你的数据集表现更好,准确率更高来进行选择。 因为我们的目的不是尽可能的拟合训练集。而是让我们的分类器在训练集以外的未知的数据表现更好。 同样,也千万不要使用将数据集分为测试和训练,依据训练集的准确度进行选择,这也非常糟糕。 因为机器学习系统的目的,是让我们了解算法表现究竟如何,所以测试集的目的,是给我们一种预估方法,即在没遇到的数据上,算法表现究竟如何。 如果采用这种用不同的超参数训练不同算法的策略,然后选择在测试集上表现最好的超参数,那么很可能我们选择了一组超参数,只是让我们的算法在这组测试集上表现得更好,但是测试集上的表现,无法代表在全新的,从未见过的数据上的表现。 最常见的做法: 将数据分为三组,大部分数据 作为训练集,然后建立一个验证集,一个测试集,通常在训练集上用不同的超参数训练算法,在验证集上进行评估,然后用一组超参数,选择在验证集上表现最好的,把这组在验证集上表现最好的分类器拿出来,在测试集上跑一跑。 注意:必须分隔验证集与测试集。 设定超参数的另外一个策略:交叉验证(常用于小数据集) 取出测试集,将剩余数据分成很多份,轮流将每一份都当做验证集。 在最后可以使用类似于下面的一幅图来表现出不同超参数对于性能的影响,来进行对于参数的挑选。 总结:k近邻算法在于图像分类时候很少使用,原因在于
问题就在于,如果想要练数据能密集的分布在空间中,可能需要指数倍的训练数据。(指数倍从来不是个好消息) KNN小结: 介绍了图像分类的基本思路,借助训练集的图片和相应的标记,可以预测测试集中数据的分类。 线性分类: 卷积神经网络关注图像,循环神经网络关注语言(对于图像的描述性语句),将两个网络组装起来,一起进行训练,可以有一些额外的效果。 举例: 线性分类器只允许学习一个类别的一个模板。(怎么理解?) 这就造成了线性分类器的困境: 很容易出现线性分类器无法划分的情形。 损失函数(为了完整性,虽然已经有所了解)(衡量当前的分类器的优秀程度) ? 数据集的损失函数是每个样本损失的总和。 ? 如何理解上式?就是max(0,非正确类别的分数-正确类别的分数+1)再求和 如果正确类别得到的分数大于不正确类别分数1以上,那么损失就是0说明预测正确,最终结果肯定是越小越好,说明离我们想要的正确结果离得越近。 上式中对于1的选择,具有任意性,因为我们并不关心正确分类的值,而是关心正确分数与不正确分类之间的差值。 所谓的svm ?loss:如上形式 SVM意为:支持向量机,一种快速可靠的分类算法,可以在数据量有限的情况下很好地完成任务。 最终求出总和之后,再取平均。就是整个数据集的损失函数。 ? 使得L为0的W并不是唯一的。 ? “正则项”:鼓励模型以某种方式选择更简单的W,主要目的是减轻模型的复杂度,而不是拟合数据。 “simple”:取决于任务的规模和模型的种类。 如此,标准损失函数就有了两个项 ? 常用的正则项: ? L2范数(可以用一种相对粗糙的方式,去度量分类器的复杂性)、L1范数,弹性网络,最大形式归一化,丢弃法,批量归一化随机深度等 梯度下降算法: 增加了mini_batch 卷积层:和全连接层的主要区别在于,它可以保全空间结构。 如何理解呢?全连接层是将图片变为展平。例如24*24的图片,将其展平为786的向量 而卷积层仍然保留空间结构,32*32*3仍保持原状。 然后将同样具有空间结构的卷积核在其上进行滑动。 卷积之后的尺寸: 例如对于32*32的图片,使用5*5的卷积核,卷积之后的尺寸为28*28. 计算:32-(5-1) (当然这是在步长为1的情况下) 最大池化层相比较于均值池化层使用的更多,因为它有着这样的意义: 更有利于信息的寻找。(不够完善) 是否可以只滑动步长而不池化?或者只池化不滑动步长? 答案是可以的,已经有人在实践中通过滑动代替池化去做降采样。 一般不在池化层做填充(0),因为池化层只做降采样,这样就不会导致,卷积核扫过边缘时,有一部分超出了输入的范围,这样池化时就不需要担心这样的问题。 选择超参数例如学习率的策略: 一:执行交叉验证,交叉验证是在训练集上进行训练,再验证集上验证。观察这些超参数的实验结果。 二:选择相当分散的数值,然后用几个epoch的迭代去学习,经过几个epochs,就可以很好的知道哪些超参数有效,哪些值好或者不好。然后做出相应的调整。通常这样做就可以发现比较好的参数区间,有了区间,就可以搜索更精确的值。 数据预处理关于数据预处理我们有3个常用的符号,数据矩阵X,假设其尺寸是[N x D](N是数据样本的数量,D是数据的维度)。 均值减法(Mean subtraction)是预处理最常用的形式。它对数据中每个独立特征减去平均值,从几何上可以理解为在每个维度上都将数据云的中心都迁移到原点。在numpy中,该操作可以通过代码X -= np.mean(X, axis=0)实现。而对于图像,更常用的是对所有像素都减去一个值,可以用X -= np.mean(X)实现,也可以在3个颜色通道上分别操作。 归一化(Normalization)是指将数据的所有维度都归一化,使其数值范围都近似相等。有两种常用方法可以实现归一化。第一种是先对数据做零中心化(zero-centered)处理,然后每个维度都除以其标准差,实现代码为X /= np.std(X, axis=0)。第二种方法是对每个维度都做归一化,使得每个维度的最大和最小值是1和-1。这个预处理操作只有在确信不同的输入特征有不同的数值范围(或计量单位)时才有意义,但要注意预处理操作的重要性几乎等同于学习算法本身。在图像处理中,由于像素的数值范围几乎是一致的(都在0-255之间),所以进行这个额外的预处理步骤并不是很必要。 ? 一般数据预处理流程:左边:原始的2维输入数据。中间:在每个维度上都减去平均值后得到零中心化数据,现在数据云是以原点为中心的。右边:每个维度都除以其标准差来调整其数值范围。红色的线指出了数据各维度的数值范围,在中间的零中心化数据的数值范围不同,但在右边归一化数据中数值范围相同。 采用中心化和归一化的原因:会使数据分布均值为0,方差为1 更直观一些 ? 对于这个例子,第一张图数据分布没有进行中心化、归一化,距离坐标系很远,虽然也可以通过一条直线进行分类,但是当对直线稍微进行旋转就会发现,整个分类器会被完全破坏。这意味着,在左边的例子中,损失函数对我们的权重矩阵中的线性分类器中的小扰动,非常敏感,这会使深度学习变得异常困难。(还要注意,不仅仅在线性分类中需要进行归一化,在整个深度学习过程中,都很重要) 所以加入一层batch normalization,来让数据均值为0,方差为1。 PCA和白化(Whitening)是另一种预处理形式。在这种处理中,先对数据进行零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。 数据协方差矩阵的第(i, j)个元素是数据第i个和第j个维度的协方差。具体来说,该矩阵的对角线上的元素是方差。还有,协方差矩阵是对称和半正定的。我们可以对数据协方差矩阵进行SVD(奇异值分解)运算。 随机梯度下降算法存在的问题: 问题一: ? 可以看到,当采用梯度下降,发现呈现之字型,这是因为梯度下降方向并不是指向最小值的一条直线,所以在目标方向上前进的非常缓慢。这个问题在高维空间更为常见。 问题二: 局部极小值或鞍点。 ? 如果曲线是这种情况,因为中间是极小值点,所以SGD会卡在中间这个地方。鞍点位置梯度为0,不会做任何动作。 如果上升到高维,当包含成千上万个参数,这种情况发生的更为频繁。 问题三:当存在噪声的时候,SGD的前进路线会非常曲折,需要花费很长的时间,才能得到最小值。 ? 解决问题的简单方法: 在我们的随机梯度下降中,加入一个动量项 普通的sgd与加入动量项之后的进行对比。 ?? ? Rho是“摩擦”,通常是为0.9或0.99,用来衰减速度,再将其加到梯度上 带动量sgd的思想: 保持一个不随时间变化的速度(通常将速度初始化为0,甚至不算一个超参数),并且我们将梯度估计添加到这个速度上,然后在这个速度的方向上步进,而不是在梯度的方向上步进(这样就可以保证,即使在梯度很小的地方,依然会有速度) ? ?蓝色是带动量的,它更平稳,没那么多的曲折。 ? ?这是梯度向量与速度向量以及真实步进的示意图 ? ?这称为Nesterov向量,可以看到,它把顺序改变了。 先是在速度方向上步进,评估终点处的梯度,然后回到出发点,将梯度与速度混合,然后再进行真是的步进。 Nesterov的具体公式: ? 使用换元: ? 比较可以发现,SGD会困在极小值点,而带向量的会越过极小值点,从而找到真正的最小值点。 另一种常见的优化策略:AdaGrad算法 ? 核心思想:在优化的过程中,需要保持一个在训练过程中的每一步的梯度的平方和的持续估计。 ?(np.sqrt是求平方根的) 与速度项不同,现在我们有了一个梯度平方项,训练时,我们会一直累加当前梯度的平方到这个梯度平方项,当我们在更新我们的参数向量时,我们会除以这个梯度平方项。 问题是:这样的放缩,对于矩阵中条件数很大的情形,有什么改进呢? 如果函数是凸函数,那么随着进行,步长越来越小,接近收敛的时候步长很小。 如果是凹函数,那么有可能会被困在极小值点。 对于算法的改进: ? 在RMSRrop中,我们让平方梯度按照一定比率下降,看起来和动量优化法很像。相当于给梯度平方加上了动量(通常衰减率是0.9或0.99)。 效果都比单纯的SGD好,但是他们在轨迹上有一点不同。 带动量的SGD会绕过最小值然后再回来,而RMSProp会不断调整自己的路线。 这样就可以在每个维度上做出大致相同的优化。 把上面两种算法结合到一起,就得到了Adam(不完全)算法: ? Beta1和beta2是衰减率 最后一步在分母中加上一个很小的数1e-7,只是为了确保除以的不是0 红框里:让第一梯度的估计值等于我们的加权和。 注意出现的问题:一开始将second_moment初始化为0,又由于beta2是0.9或0.99,是一个非常接近1的值,所以第一次计算后的second_moment仍然是一个很小的值,这就会导致最后一步作为分母很小,导致步长很大,而这么大的步长不是因为梯度很大,只是我们认为的将第二动量初始化为了0. 为了避免最初的步长过大,把事情搞砸,Adam算法也增加了偏置校正项。 ? 总结:Adam算法是一个非常好的最优化算法 ,对于不同的问题Adam算法都能得到非常不错的结果,可以将其看做解决任何新问题的默认算法。 ?超参数的设置,这些可以作为初始设置。 对于学习率设置的想法: 学习率过大可能会造成爆炸,过小可能会造成长时间无法收敛, 一种做法是,不必在整个训练过程中都使用同一个学习率,有时候会把学习率沿着时间衰减。(开始时候可能较大,然后再训练过程中逐渐衰减的越来越小)一个衰减的策略是步长衰减。 同时,学习率衰减在带动量的SGD中常用,像Adam算法中就很少用。而且,学习率衰减是二阶超参数(因为学习率已经是超参数),不应该一上来就进行学习率衰减,通常开始时选择不错的学习率,且不带衰减的。尝试在交叉验证中同时调学习率衰减和初始学习率。 正则化:(目的是为了提高单一模型的效果) 在模型上加入一些成分,防止训练集上的过拟合,从而使测试集上的效果得到提升。 方法一:在损失函数上加入额外的一项 ? 另外非常常用的方法dropout(丢弃法): 概念:每次在网络中正向传递时,在每一层随机将一部分神经元置零。每次正向传递时,随机被置零的神经元都不是完全相同的。(所谓置零,是将激活函数置零,因为每一层都是在计算上一个激活函数的结果乘以权重矩阵,得到下一个激活函数前的结果) 一般是在全连接层使用,在卷积层有时也会见到。(卷积层有可能是把整个特征映射置零) 卷积神经网络中可能要把几个通道置零,而不是将几个元素置零 反转dropout(inverted dropout) 正则化:一种普遍的模式 在训练中:加入随机噪声 在测试中:抵消这些噪声(淡化噪声) 例子有: Dropout 批量归一化(这可能是使用较多的正则化方法) 数据增强(色彩抖动、改变图像的对比度和亮度、) 可以使得你的问题变得富有创造性 对下面这些操作随机混合:(不改变标签的前提下) 翻译、旋转、拉伸、剪切、镜头失真等 注意:不要盲目的使用这些方法,而是有的放矢,例如当出现过拟合的时候可以进行使用 迁移学习 可以使得深度学习不需要大量的数据集,也能训练 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/22 15:11:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |