详细笔记地址: http://www.ai-start.com/dl2017/
这里只是做些自己的摘抄与理解
吴恩达(英语:Andrew Ng)是斯坦福大学计算机科学系和电气工程系的客座教授,曾任斯坦福人工智能实验室主任。他还与达芙妮·科勒一起创建了在线教育平台Coursera。
吴恩达老师的机器学习课程可以说是入门机器学习的同学最先接触的课程,当然后续的deeplearning.ai是更深入的课程。对在线教育,以及人工智能领域的发展提供了很大的帮助,感谢。
输入层输入的是特征,什么是特征,与预测或处理物体息息相关的事情都可以考虑作为特征,只是特征有轻有重,不同的特征对应的权重不一样,所以需要神经网络去学习特征前的权重参数。
给予足够多的训练样本有关 和,神经网络非常擅长计算从到的精准映射函数。
传统的算法面对大数据时候性能有瓶颈
对于神经网络而言,得益于大数据的发展以及计算性能的提升,再次得到发展。
想要获得较高的性能体现,那么你有两个条件要完成,第一个是你需要训练一个规模足够大的神经网络,以发挥数据规模量巨大的优点
小型网络、中型网络以及大型网络对应的数据量以及其性能
另外就是算法上的创新
在电脑的眼里,图片是用矩阵的形式表示
这里将矩阵转化为列向量后作为神经网络的输入
为什么用逻辑回归而不是线性回归,因为线性回归wx+b的输出值比1大,或者是比 0小,无法比较输出类别的概率大小,因此使用sigmoid函数对其进行非线性激活,将范围变为0-1之间
损失函数:用来衡量预测输出值和实际值有多接近
逻辑回归不实用mse均方误差这类损失函数是由于其不是凸函数,只能找到多个局部最优值,梯度下降法很可能找不到全局最优值。
在逻辑回归中用到的损失函数是二元交叉熵损失函数:
(^ , ) = −log(^) − (1 − )log(1 − ^)
一个神经网络的计算,都是按照前向或反向传播过程组织的。首先我们计算出一个新的网络的输出(前向过程),紧接着进行一个反向传输操作。
以单样本为例,损失函数L为
-(ylog(a) + (1-y)log(1-a)) y是标签,a是激活值
求解得到
dl/da = (-y/a + (1-y)/(1-a))
dl/dz = dl/da * da/dz = (-y/a + (1-y)/(1-a)) * a(1-a) = a-y
dl/dw1 = dl/da * da/dz * dz/dw1 = (a-y) * x1
向量化是非常基础的去除代码中 for 循环的艺术
用向量操作替换循环元素处理
输入层:传递输入
隐藏层:线性加权求和,再通过激活函数激活
输出层:预测值
正数的导数为1,负数的导数为0,神经元此时不会训练,易导致稀疏性。
避免了ReLU负数阶段的导数为0,以一个非常小的数作为梯度值。
总结
如果不确定哪一个激活函数效果更好,可以把它们都试试,然
后在验证集或者发展集上进行评价。然后看哪一种表现的更好,就去使用它。
如果隐藏层使用的是线性函数的话就没有意义,等价于逻辑回归时候,中间的多个隐藏层可以直接由一个线性函数表示。
对于神经网络而言,就是需要使用非线性激活函数来获得有意思的函数映射。
但是对于回归问题,其输出层可以使用线性激活函数。唯一可以用线性激活函数的通常就是输出层。
梯度下降算法用于更新网络中的参数w和偏置b,基于输出值与预期值之间的误差函数来进行反向传播来更新的。
当你训练神经网络时,权重随机初始化是很重要的。如果你把权重或者参数都初始化为 0,那么梯度下降将不会起作用。
对于可以随机初始化,可以初始化为 0。
= ..(2,2) ∗ 0.01
= .((2,1))
通常倾向于初始化为很小的随机数, 你用 tanh 或者sigmoid 激活函数,或者说只在输出层是 sigmoid,如果(数值)波动太大,当计算激活值时,如果很大,就会很大。的激活值就会很大或者很小,这种情况下很可能停在 tanh/sigmoid 函数的平坦的地方,这些地方梯度很小也就意味着梯度下降会很慢,因此学习也就很慢。
到有一些函数,只有非常深的神经网络能学会,而更浅的模型则学不到。尽管对于任何给定的问题很难去提前预测到底需要多深的神经网络,所以先去尝试逻辑回归,尝试一层然后两层隐含层,然后把隐含层的数量看做是另一个可以自由选择大小的超参数,然后再保留交叉验证数据上评估,或者用你的开发集来评估。
深度神经网络的这许多隐藏层中,较早的前几层能学习一些低层次的简单特征,等到后几层,就能把简单的特征结合起来,去探测更加复杂的东西。
对训练执行算法,通过验证集或简单交叉验证集选择最好的模型。
在机器学习发展的小数据量时代,常见做法是将所有数据三七分,就是人们常说的 70%验证集,30%测试集,如果没有明确设置验证集,也可以按照 60%训练,20%验证和 20%测试集来划分。
深度学习可能存在过拟合问题——高方差,有两个解决方法,一个是正则化,另一个是准备更多的数据。但准备更多的数据比较耗时耗力。
以逻辑回归损失函数为例:
实现参数的稀疏有什么好处吗?
参数值越小代表模型越简单吗?
总结
是正则化参数,通常使用验证集或交叉验证集来配置这个参数,尝试各种各样的数据,寻找最好的参数,要考虑训练集之间的权衡,把参数设置为较小值,这样可以避免过拟合
如果正则化参数变得很大,参数很小,也会相对变小,此时忽略的影响,会相对变小,实际上,的取值范围很小,曲线函数ℎ会相对呈线性,整个神经网络会计算离线性函数近的值,这个线性函数非常简单,并不是一个极复杂的高度非线性函数,不会发生过拟合。
实现方式:反向随机失活(inverted dropout)
在测试阶段,当我们评估一个神经网络时,也就是用绿线框标注的反向随机失活方法,使测试阶段变得更容易
反向随机失活(inverted dropout)方法通过除以 keep-prob,确保激活值a的期望值不变。
在测试阶段,并未使用 dropout,自然也就不用抛硬币来决定失活概率,以及要消除哪些隐藏单元,因为在测试阶段进行预测时,不期望输出结果是随机的。
dropout好处:
dropout缺点:
使用经验:
只有存在过拟合时,才决定是否使用dropout。如果不存在过拟合,使用它并不一定能够提升模型性能。
方法:水平垂直翻转、随机裁剪、随机放大裁剪、轻微形变
验证集性能有多少次迭代都没有变化时,使用early stop,在此时停止。
优点:
缺点:
建议还是使用L2正则化来代替early stopping。
标准化需要两个步骤:
训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度。
随机高斯 初始化变量,然后除以每层节点数的平方根
设置的权重矩阵既不会增长过快,也不会太快下降到 0,从而训练出一个权重或梯度不会增长或消失过快的深度网络,也可以加快收敛速度。
batch: 每次都拿全部的样本进行梯度更新来训练网络,导致速度很慢。
mini-batch: 把训练集分割为小一点的子集,然后用子集进行训练。
mini-batch = m ----> batch
mini-batch = 1 ----> sgd
做偏差修正,可以让平均数运算更加准确。初始时候预测结果不准确,导致前期结果有一段不准确。使用偏差修正能够解决这类问题。
计算梯度的指数加权平均数,并利用该梯度更新权重。比一般的梯度下降算法要快。
等高线纵轴方向波动小些,横轴方向移动快些。
root mean square prop
减缓方向的学习,即纵轴方向,同时加快,至少不是减缓横轴方向的学习。
与动量梯度下降有些相似,但是偏导数的平方项,且在进行参数更新的时候,除以开方数。
在横轴方向或者在例子中的方向,我们希望学习速度快,而在垂直方向,也就是例子中的方向,希望减缓纵轴上的摆动,所以有了和,我们希望会相对较小,所以我们要除以一个较小的数,而希望又较大,所以要除以较大的数字,这样就可以减缓纵轴上的变化。
Adam 优化算法基本上就是将 Momentum 和 RMSprop 结合在一起。
加快学习算法的一个办法就是随时间慢慢减少学习率,将之称为学习率衰减。
减少的本质在于,在学习初期,能承受较大的步伐,但当开始收敛的时候,小一些的学习率能步伐小一些
Batch归一化会使你的参数搜索问题变得很容易,使神经网络对超参数的选择更加稳定,超参数的范围会更加庞大,工作效果也很好,也会是你的训练更加容易
为什么有效:
总结:
Softmax将逻辑回归推广到C类上,当C==2时,等同于逻辑回归。
输出是多维向量,维度与类别数一致,表明属于每一类的概率值,相加为1。
softmax激活函数分为以下步骤:
在机器学习中,可以观察你的系统,然后说这一部分是错的,它在训练集上做的不好、在开发集上做的不好、它在测试集上做的不好,或者它在测试集上做的不错,但在现实世界中不好,这就很好。必须弄清楚到底是什么地方出问题了,然后刚好有对应的旋钮,或者一组对应的旋钮,刚好可以解决那个问题,那个限制了机器学习系统性能的问题。
一般做法:
有这样一个开发集,加上单实数评估指标,迭代速度肯定会很快,它可以加速改进机器学习算法的迭代过程
有一个单实数评估指标真的可以提高效率,或者提高团
队做出这些决策的效率
准确度与时间上面的综合权衡
考虑个指标,有时候选择其中一个指标做为优化指标是合
理的。所以你想尽量优化那个指标,然后剩下 − 1个指标都是满足指标,意味着只要它们达到一定阈值,例如运行时间快于 100 毫秒,但只要达到一定的阈值,你不在乎它超过那个门槛之后的表现,但它们必须达到这个门槛。
用训练集训练不同的模型,然后使用开发集来评估不同的思路,然后选择一个,然后不断迭代去改善开发集的性能,直到最后你可以得到一个令你满意的成本,然后你再用测试集去评估
注意:
划分比例:
改变数据集:
好的模型就两件事:
方差上的提升(过拟合):
搭建应用系统,那这个简单的人工统计步骤,错误分析,可以节省大量时间,可以迅速决定什么是最重要的,或者最有希望的方向
进行错误分析,应该找一组错误样本,可能在开发集里或者测试集里,观察错误标记的样本,看看假阳性(false positives)和假阴性(false negatives),统计属于不同错误类型的错误数量
如果这些标记错误严重影响了你在开发集上评估算法的能力,那么就应该去花时间修正错误的标签。如果它们没有严重影响到你用开发集评估成本偏差的能力,那么可能就不应该花宝贵的时间去处理。
在构造实际系统时,通常需要更多的人工错误分析,更多的人类见解来架构这些系统,尽管深度学习的研究人员不愿意承认这点
应该尽快建立你的第一个系统原型,然后快速迭代
主要目标是弄出能用的系统,并不是发明全新的机器学习算法。可以从现有大量学术文献为基础出发,一开始就搭建比较复杂的系统。
越来越多的团队都用来自和开发集、测试集分布不同的数据来训练,这里有一些微妙的地方,一些最佳做法来处理训练集和测试集存在差异的情况。
这是由于项目任务所针对的图片类型决定的,比如手机app要识别的是用户手机拍摄的猫,而这类数据集少,网上爬虫的数据集大,但与任务的数据不是同一个分布,将其混合起来再划分这样的方法并不好,这是由于混一起后验证集、测试集中任务所要针对的图片占的比例很低。
开发集和测试集都是手机图。而训练集包含了来自网页的 20 万张图片,还有 5000 张来自应用的图片,开发集就是 2500 张来自应用的图片,测试集也是 2500 张来自应用的图片。这样将数据分成训练集、开发集和测试集的好处在于,现在你瞄准的目标就是你想要处理的目标。
有助于提高你的学习算法的性能,但是,潜在问题就不只是偏差和方差问题,这样做会引入第三个潜在问题,数据不匹配。
将训练集划分为训练集与训练-验证集(不用来训练,只测试)来看偏差与方差的关系。
存在数据不匹配问题,建议你做错误分析,或者看看训练集,或者看看开发集,试图找出,试图了解这两个数据分布到底有什么不同,然后看看是否有办法收集更多看起来像开发集的数据作训练。
把神经网络最后的输出层拿走,就把它删掉,还有进入到最后一层的权重删掉,然后为最后一层重新赋予随机权重,然后让它在放射诊断数据上训练。
如果你有足够多的数据,你可以重新训练神经网络中剩下的所有层。经验规则是,如果你有一个小数据集,就只训练输出层前的最后一层,或者也许是最后一两层。
在多任务学习中,同时开始学习的,试图让单个神经网络同时做几件事情,然后希望这里每个任务都能帮到其他所有任务。
什么时候可以使用多任务学习:
多任务学习能让你训练一个神经网络来执行许多任务,这可以给你更高的性能,比单独完成各个任务更高的性能
以前有一些数据处理系统或者学习系统,它们需要多个阶段的处理。那么端到端深度学习就是忽略所有这些不同的阶段,用单个神经网络代替它。
输入数据,构建网络模型,直接得到结果。这需要大量的数据以及好的应用场景。
如果不好一步到位,使用分任务的方式将其串起来也是很好的解决方案。
应用:
边缘检测算子中的数字用于进行边缘检测
计算机视觉不一定要去使用那些研究者们所选择的这九个数字,而是将这 9 个数字当成学习参数
valid: 不填充,卷积后尺寸变小
same: 填充,卷积后尺寸不变
这也是为什么通常将卷积核设置为奇数的充分原因
按照计算机视觉的惯例,当你的输入有特定的高宽和通道数时,你的过滤器可以有不同的高,不同的宽,但是必须一样的通道数。
参数计算:
(每个卷积核的参数+1个bias) * 卷积核的个数
逐层提取特征,在最后一层进行特征展开,为一个向量,输入到逻辑回归或者softmax分类器,得到最终分类结果。
除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性。
最大池化: max pooling 输出的每个元素都是其对应颜色区域中的最大元素值。
最大化运算的实际作用就是,如果在过滤器中提取到某个特征,那么保留其最大值。如果没有提取到这个特征,可能在右上象限中不存在这个特征,那么其中的最大值也还是很小,这就是最大池化的直观理解。
一般而言,最大池化比平均池化要常用些,但例外就是深度很深的神经网络,可以用平均池化来分解规模为 7×7×1000 的网络的表示层,在整个空间内求平均值,得到1×1×1000,取代全连接层。
输入通道与输出通道个数相同,因为我们对每个通道都做了池化。
池化过程中没有需要学习的参数。执行反向传播时,反向传播没有参数适用于最大池化。
池化层的反向传播
需要保证传递的loss(或者梯度)总和不变
和只用全连接层相比,卷积层的两个主要优势在于参数共享和稀疏连接。
在计算机视觉任务中表现良好的神经网络框架往往也适用于其它任务, 完全可以借鉴别人的神经网络框架来解决自己的问题。
这些层分别拆分到两个不同的 GPU 上,同时还专门有一个方法用于两个 GPU 进行交流
叫作“局部响应归一化层”(Local Response Normalization),即 LRN 层
padding都是same,conv层输出的尺寸没有变化。
由 64 翻倍变成 128,再到 256 和 512。作者可能认为 512 已经足够大了,所以后面的层就不再翻倍了。无论如何,每一步都进行翻倍,或者说在每一组卷积层进行过滤器翻倍操作,正是设计此种网络结构的另一个简单原则。
随着网络的加深,图像的高度和宽度都在以一定的规律不断缩小,每次池化后刚好缩小一半,而通道数量在不断增加,而且刚好也是在每组卷积操作后增加一倍。
在残差网络中有一点变化,我们将[]直接向后,拷贝到神经网络的深层,在 ReLU 非线性激活函数前加上[],这是一条捷径。[]的信息直接到达神经网络的深层,不再沿着主路径传递。
[+2] = ([+2] + [])
当训练计算机视觉模型的时候,数据增强会有所帮助。
提升基准测试或者竞赛:
算法判断图片中是不是一辆汽车,还要在图片中标记出它的位置,用边框或红色方框把汽车圈起来,这就是定位分类问题
目标检测在原有的图像分类基础上又增加了几个输出:边界框,, ℎ和,这四个数字是被检测对象的边界框的参数化表示。
标签
:
第一个组件表示是否含有对象,如果对象属于前三类(行人、汽车、摩托车),则 = 1,如果是背景,则图片中没有要检测的对象,则 = 0。我们可以这样理解,它表示被检测对象属于某一分类的概率,背景分类除外。
= 1,同时输出1、2和3,表示该对象属于 1-3 类中的哪一类。
损失函数:
神经网络可以通过输出图片上特征点的(, )坐标来实现对目标特征的识别
准备一个卷积网络和一些特征集,将人脸图片输入卷积网络,输出 1 或 0, 1 表示有人脸,0 表示没有人脸,然后输出(1,1)……直到(64,64)。这里我用代表一个特征,这里有129 个输出单元,其中1表示图片中有人脸,因为有64个特征,64×2=128,所以最终输出 128+1=129 个单元
人体姿态检测,你还可以定义一些关键特征点,如胸部的中点,左肩,左肘,腰等。然后通过神经网络标注人物姿态的关键特征点,再输出这些标注过的特征点,就相当于输出了人物的姿态动作。
滑动窗检测:
滑动窗口目标检测算法接下来会继续处理第二个图像,即红色方框稍向右滑动之后的区域,并输入给卷积网络,因此输入给卷积网络的只有红色方框内的区域,再次运行卷积网络,然后处理第三个图像,依次重复操作,直到这个窗口滑过图像的每一个角落。
不需要把输入图像分割成四个子集,分别执行前向传播,
而是把它们作为一张图片输入给卷积网络进行计算,其中的公共区域可以共享很多计算。
在滑动窗口法中,你取这些离散的位置集合,然后在它们上运行分类器,在这种情况下,这些边界框没有一个能完美匹配汽车位置。
yolo算法可以获得准确的方格。在图像上放一个网格。基本思路是使用图像分类和定位算法。对于每个格子都指定一个标签y
普通的卷积网络,卷积层,最大池化层等等,最后你会有这个,选择卷积层和最大池化层,这样最后就映射到一个 3×3×8 输出尺寸。所以你要做的是,有一个输入,就是这样的输入
图像,然后你有这些 3×3×8 的目标标签。
优点在于神经网络可以输出精确的边界框,但是每个格子只能有一个对象
注意:
读不懂研究论文的时候,必须去读源代码,或者联系作者之类的才能弄清楚这些算法的细节
一般约定,在计算机检测任务中,如果 ≥ 0.5,就说检测正确,如果预测器和实际边界框完美重叠,loU 就是 1,因为交集就等于并集。但一般来说只要 ≥ 0.5,那么结果是可以接受的,看起来还可以。
非极大值抑制这个方法可以确保你的算法对每个对象只检测一次
会对同一个对象做出多次检测,所以非极大值抑制做的就是清理这些检测结果。这样一辆车只检测一次,而不是每辆车都触发多次检测。
pc*c1、c2、c3
先用阈值丢弃一些结果
然后去掉所有剩下的边界框,任何没有达到输出标准的边界框,之前没有抛弃的边界框,把这些和输出边界框有高重叠面积和上一步输出边界框有很高交并比的边界框全部抛弃
预先定义两个不同形状的 anchor box,或者 anchor
box 形状,你要做的是把预测结果和这两个 anchor box 关联起来。
观察哪一个 anchor box 和实际边界框(编号1,红色框)的交并比更高,不管选的是哪一个,这个对象不只分配到一个格子,而是分配到一对,即(grid cell,anchor box)对,这就是对象在目标标签中的编码方式。所以现在输出 就是 3×3×16,上一张幻灯片中你们看到 现在是 16 维的,或者你也可以看成是3×3×2×8,因为现在这里有 2 个 anchor box,而 是 8 维的。
anchor box 这个概念,是为了处理两个对象出现在同一个格子的情况
对于每个类别单独运行非极大值抑制,处理预测结果所属类别的边界框,用非极大值抑制来处理行人类别,用非极大值抑制处理车子类别,然后对摩托车类别进行非极大值抑制,运行
三次来得到最终的预测结果。所以算法的输出最好能够检测出图像里所有的车子,还有所有的行人
人脸验证与人脸识别的区别
人脸验证问题:如果你有一张输入图片,以及某人的 ID 或者是名字,这个系统要做的是,验证输入图片是否是这个人。有时候也被称作 1 对 1 问题,只需要弄明白这个人是否和他声称的身份相符
人脸识别问题:比人脸验证问题难很多,是1对k的问题
需要通过单单一张图片或者单单一个人脸样例就能去识别这个人, 训练样本只有一个。
不再是分类问题,而是要学习一个能够衡量二者区别的函数
输入不再是一个图片,而是图片对。输出二者的维度为128维,然后比较二者的距离。
损失函数可以:
应用三元组损失函数,你需要比较成对的图像。一个 Anchor图片,想让 Anchor 图片和 Positive 图片(Positive 意味着是同一个人)的距离很接近。然而,当 Anchor 图片与 Negative图片(Negative 意味着是非同一个人)对比时,会想让其距离离得更远一点。
anchor与正样本之间的距离小于anchor与负样本之间的距离
为了确保网络对于所有的编码不会总是输出 0,也为了确保它不会把所有的编码都设成互相相等的
是另一个超参数,这个就可以阻止网络输出无用的结果。
损失函数:
如何构建训练样本:
代价函数:
内容代价函数:
风格代价函数
利用风格矩阵表示各自的风格,然后计算二者矩阵差,求和求均值