这个笔记的话,由于自己的课件之间有一些耦合性,可是关联性也不是很大,这里的话,由于我是在雷锋网上看的整个视频课程,感谢字幕组有整理出来每个Lecture的关键词,这里的话个人笔记组织的话,主要就是以名词为主进行组织:python
Adaboost是一种迭代的算法,本质上实际上是对于一个训练集来训练不一样的分类器classifier,而后把这些classifier进行集合,组成一个更强的classifier。其实本质上仍是一个级联的过程。算法
整个算法的话,过程的话实际上是:编程
一、先对于N个训练样本进行学习获得第一个弱分类器;网络
二、而后把粉错误的样本和新的样本数据一块儿构成一个新的N个的新的训练样本,对于这个新的样本集合进行学习获得第二个弱分类器;架构
三、以此类推,每次都把以前全部的classifier分错误的样本+新的样本组成一个N个训练样本集,再经过学习获得后续的分类器;框架
四、最终的话,咱们获得一个强分类器,所以咱们的数据被分割成为哪一类是由分类器的权值决定的。机器学习
这里面的话,实际上是Li Fei Fei组的一个研究方向,由于咱们自己的话但愿的是经过天然语言和机器视觉的结合实现,咱们看到一幅图片,机器对应生成语言来进行描述图片。分布式
这里的话,实际上是早期学者研究的时候学者对于世界的一种简单建模。函数
其实不少时候,发现自己的话仍是先从图形的边缘特征入手,来构建图像中物体的框架,而后更抽象的就是提取出对应的特征点,而后把整个图像的特征抽象为一个点。性能
在这里的话,其实咱们看到Bounding Box的话,是最初的一种图像目标检测的一种方法,通常来讲咱们想要检测一个目标,不仅仅是要获得一个分类,更但愿可以把物体单独提取出来,这里的话简单的就是拿一个框框出来,这个很是的简单,可是的话,将来想作的是可以直接抠图出来,那就涉及到了图像分割问题。
卷积神经网路——也就是咱们所说的CNN network structure, 是经过构建一个神经网络来进行图像的分类问题。
这里的话,咱们使用了这些网络架构,进而能够获得很好的性能提高。上图除了2010仍是传统的分类方法以外,2012年以后的都是深度学习的方法。
其实的话,所谓的深度学习本质上只是机器学习的一个子集。所谓的深度Depth其实不是什么新鲜事,仅仅是实现了层级数比较多的神经网络进而进行机器学习而已。
这里的卷积神经网络其实和以前Lecun的手写数字识别模型是很是的相似的。
这里的话,其实能够看出,深度学习也是受益于硬件提高很是的多,若是没有高性能CPU、GPU的出现,那么咱们在实现CNN的过程当中不会有这么大的提高。
这里的咱们的fully connected layers主要指的是CNN中的一个特别的层级,在中文中能够被翻译为:全连接层/彻底连接层;在CNN中间,咱们的Fully-connected Layers主要实现一种功能:经过把学习到了的分布式特征表示来映射到咱们的样本标记空间中。其实就至关于咱们的CNN以前的步骤作的是特征提取的过程,可是最后的话咱们若是想要实现一个分类的过程的话,仍是须要Fully-connected layer来进行实现的。
在这里面的话,咱们的全连接层的操做能够有卷积层操做实现,经常你们使用的一种方法是借助传统机器学习中的一个神经元的激活方法进行表示全连接的。这里的话,整个全连接的核心操做就是$y = W x$,进而把一个特征空间线性变换到了另外一个特征空间中,目标空间中的任意一个维度的话也就会受到源空间的每个维度的影响,因此说目标向量其实能够是源向量的加权和。
这里的话,咱们最后两个fully connected layers主要作的工做就是对于咱们的特征作分类,其实这里的话认为咱们使用传统的softmax操做也是能够的。
在深度学习(机器学习)中间,其实比较重要的一个概念就是咱们想要尽量的实现模型的generalization,由于咱们但愿创建一个通用的模型,从而可以对于尽量多的问题进行咱们想要的操做。这里的话不知道咱们的人脸方法和其余超分辨率方法能不能有一种泛化模型。
这是一种能够比较好的表示图片的方法,经过构建一个图片的梯度直方图,可以把整个画面中的相关特征经过统计建模转换成几率模型,这样子的话在咱们后面的处理过程当中也能够有比较大的提高。
其实这里面的话,并非彻底的研究说成像,而是但愿从生物体自己的一种对于图像感知的方法上面获得启发从而构建机器的视觉模型。下面的话我结合PPT中间的一张图像对于人眼成像的原理进行简单的介绍:
一、人眼其实一开始对于图像的话是一个简单感知的过程。在最开始,咱们的人眼是有一个叫Primary Visual Corte(初级视觉皮层)的过程,这歌层级的话其实主要就是获得咱们第二张的Edge Image,经过咱们的Edge Image,咱们能够感知到整幅图像边缘信息,从而大概对于物体的轮廓有一个了解。其实咱们的超分辨率的话自己也能够概括成为一个低级视觉的问题。
二、在咱们提出出来对应的features以后,咱们进一步的就是构建了一个相对的深度等其余信息的结构图,进一步的可让咱们看出来整个图形是什么样子的,这样子的话这些辅助信息的话也能够帮助咱们进行物体的辨别;
这里的话其实有一个想法:在咱们进行图片分类任务的时候,其实若是我想要把整个过程用矩阵进行表示的话,其实就是:
$$Y = W * X$$
在这个公式之中,咱们能够理解成:X为咱们的输入图像,其中的尺寸是$width * height * channels$的一个三维矩阵(能够看做一个立方体),而后通过一个分类器classifier(广义)以后,咱们能够获得对应的输出,这里的输出的话实际上是咱们本身须要的结果,有的时候多是一幅图片$width * height *channel$或者是对应的标签(分类问题),这里的话,咱们并非单纯的生成一个标签,而有多是生成各个标签的权重值的列向量:{cat:1,dog:0.2348294....,car:0.231123123}。这样子的话其实根据咱们每个须要的结果不一样,咱们乘以的矩阵的维度也是不同的。这里的话惟一的要求应该就是知足矩阵运算的维度便可。
这里的话,咱们能够看出,若是咱们合理的设计咱们的分类器,咱们其实最简单的想法是经过hard-coding来进行编程,可是单单是识别猫的过程就是很是复杂的,咱们没有办法使用人力就写出来,这个时候的话咱们其实就但愿能不能有别的方法能够从数据中归纳出范式,咱们只须要解决这个概括过程就能够了呢?答案是确定的。不少人都在研究Data-dirven的method来进行图像的分类:
这里的话,其实最简单的办法就是使用nearest neighbor的方法对于整个图像特征进行判断,进而看看能不能实现一个简单的分类。其实这个方法的话,用数学方法来表示的话很是的简单:
这里的话,咱们首先假设咱们的Sampled image(已经标记好为若干分类)为$L_j,其中j = 0,1,2,...,n$,对应的咱们须要判断的图像分别为:$I_k, 其中k = 0,1,2,...,m$,咱们须要作的操做仅仅是分别计算一下每个待比较图像$I$和已经分类好的图像$L$之间的距离(像素与像素之间的差值大小),$Score = I_k - L_j$,而后再对于这个Score列向量提取出最大值而且对应到相应的标签就能够完成一个最简单的聚类过程。
这里面的话,引伸出来了其余的几个概念,能够在这个简单的聚类过程当中进行解答:
这里的话,咱们的整个比较过程的话,咱们是在以前简单的一个$|I_k - L_j|$这个公式完成的。这个公式其实区分能力很是的很差,咱们能够选择其余的评价图片与图片之间距离、类似度的函数进行比较,这个函数就能够叫作Comparison Function。
在这个聚类结果的图形中,其实咱们就能够看出,中间的这些不一样颜色的交界处其实就是咱们的decision boundaries,不一样聚类与聚类之间的边界线。可是咱们不少时候最好对于位于boundaries上面的每个点仔细的考察一下,可能可以对于模型有更好的修正。
这里面的话,咱们调节decision boundaries的时候,其实有不少种方法:一、改变咱们的comparison function能够帮助咱们调节咱们的decision boundaries
二、咱们能够改变判决的法则,以前咱们只是从最接近的一个临接处进行分类;如今的话,咱们须要结合已有分类中间的若干个点进行分类,而后进行一个majority vote从而获得对应的分类结果。
咱们通常使用的comparison function对于一些经典的函数,咱们总结称这些函数分别为:Distance function,咱们经常使用的Distance 函数有如下,也就是咱们常称的L-1,L-2距离。
当咱们使用不一样的distance function的时候,咱们获得的结果也存在不一样:
这里的话会引出来一个新的概念:超参数。超参数的意思其实并非什么超级的意思,更多时候表明咱们对于整个模型须要手动调节的参数。
这里的话,K表明的是咱们选取的参考点的数目,能够是1,也能够是3,5等值。 Distance表明的是咱们选择的Distance function,能够是L_1 Distance,也能够是L_2 Distance.
其实咱们在整个神经网络的过程当中,最重要的就是这个调参过程。怎么样获取一个更好的超参数呢?其实人们的方法也很蠢,就是不断的在数据集上面进行测试,不断的优化调节。
但其实在最后咱们能够看到,平时咱们正常的实践的时候,基本上仍是不用这种Means或者说K-means方法的,其中有一个缘由以下:
这个图片里咱们能够看出来,咱们的这里面3个图片有相同的L2距离。
同时的话,K-Means方法的运算量也是很是的巨大,其实不是很值得用作实际的应用。
Parametric Approach:
使用这个方法,经过把一幅图像通过咱们设计好的一个系数矩阵操做以后,转换为10个类别标签。
其实总感受这种方法和咱们的稀疏字典有一些能够参考的关系,其实主要的工做量应该是在如何设计这个W系数矩阵。这里的话有一个实际的例子:
这一种方法的话,在最后其实和咱们以前的聚类有一些相似的地方,同时也存在一些区别,不如说这里面每个score的话,都有对应的得分。最后训练获得的每个结果的话,都是对应的pattern。
上面这幅图仅仅是在CIFAR-10 数据集上训练获得的一个线性分类器,其实每一个里面都可以看出来很是模糊的样子,特别是Car这个类别,特征算是比较明显的了。
线性分类器本质上作了哪些工做呢?其实他主要的做用就是经过创建几个线性分割线,把咱们的线性空间进行了分割,从而实现一种分类的效果。
线性分类器这样子的话,看上去咱们对于高维空间也能有不错的分割效果,那是否是咱们只是用线性分类器就能够实现一切问题了呢?答案是否认的。线性分类器存在自身的失效的分类案例。
好比说下面的三个cases就是咱们的线性分类器没有办法作到的问题——可是,其实第二个仍是能够作到的,可是这里面的话首先就须要咱们对于整个样本空间进行一个变换,把对应的部分转换到对应的样本空间之中,再使用线性的方法进行分割。
这里的话还有一个问题,咱们学习到了一个系数矩阵,可是这个系数矩阵怎么样作可以使得咱们能够很好的衡量这个分类器呢?咱们的想法是:咱们能不能经过构造一个函数,而后经过咱们已知的分类以后的结果,对于正确分值的部分进行增长,错误分值的节点进行减少呢?
答案是能够的。这个时候就须要引出一个函数,来正确的表示咱们的系数矩阵对于判断正确与否的影响关系。经过这个函数,咱们可以知道往哪一个方向来修正咱们的系数矩阵。
Loss function:创建Loss function的目的是可以及时可以对咱们的系数矩阵有一个修正;而且咱们但愿经过loss function来进行优化相关的parameter。
这里的话,咱们创建了一个样本:${(x_i,y_i)}_{i=1}^N$,这里面的话$x_i$表明的是图片,$y_i$是标签。整个dataset的loss其实就是全部的样本的loss总和:
$$L = \frac{1}{N} \sum_i L_i(f(x_i,W),y_i)$$
这个是简单的一个整体loss的表达式。
这里的话,$(x_i,y_i)$,其中$x_i$表明图片,$y_i$表明标签。这里的话有一个分数:$s = f(x_i,W)$,咱们的SVM是有这样子的效果的:
$$L = begin{cases} 0, & text {if S_{y_i} bigger S_j+1 } \ s_j - S_{y_i}+1 , & text{otherwise}
end{cases}$$
$$L = \sum_{j \neq y_i} max(0,s_j - s_{y_j} +1)$$
举例:用一个例子演示公式是如何计算的。假设有3个分类,而且获得了分值s=[13,-7,11]。其中第一个类别是正确类别,即$y_i=0$。同时假设$\Delta$是10(后面会详细介绍该超参数)。上面的公式是将全部不正确分类$(j\not=y_i)$加起来,因此咱们获得两个部分:
$ Li=max(0,-7-13+10)+max(0,11-13+10)$
能够看到第一个部分结果是0,这是由于$[-7-13+10]$获得的是负数,通过max(0,-)函数处理后获得0。这一对类别分数和标签的损失值是0,这是由于正确分类的得分13与错误分类的得分-7的差为20,高于边界值10。而SVM只关心差距至少要大于10,更大的差值仍是算做损失值为0。第二个部分计算[11-13+10]获得8。虽然正确分类的得分比不正确分类的得分要高(13>11),可是比10的边界值仍是小了,分差只有2,这就是为何损失值等于8。简而言之,SVM的损失函数想要正确分类类别y_i的分数比不正确类别分数高,并且至少要高Delta。若是不知足这点,就开始计算损失值。
那么在此次的模型中,咱们面对的是线性评分函数$(f(x_i,W)=Wx_i)$,因此咱们能够将损失函数的公式稍微改写一下:
$L_i=\sum_{j\not=y_i}max(0,w^T_jx_i-w^T_{y_i}x_i+\Delta)$
其中$w_j$是权重$W$的第$j$行,被变形为列向量。然而,一旦开始考虑更复杂的评分函数f公式,这样作就不是必须的了。
在结束这一小节前,还必须提一下的属因而关于0的阀值:$max(0,-)$函数,它常被称为折叶损失(hinge loss)。有时候会听到人们使用平方折叶损失SVM(即L2-SVM),它使用的是$max(0,-)^2$,将更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,可是在某些数据集中,平方折叶损失会工做得更好。能够经过交叉验证来决定到底使用哪一个。
在上面的multiclass的损失函数中存在一个问题,这里的话假设咱们有一个数据集和一个weight matrix W,这里的话能够正确的分类每个数据(这里的话全部的边界都知足,对于全部的i都有$L_i = 0$),可是为题在于:这个W并非惟一的,同时也有可能有不少类似的W能够正确的分类全部的数据。
换句话说,咱们但愿能向某些特定的权重W添加一些偏好,对其余权重则不添加,以此来消除模糊性。这一点是可以实现的,方法是向损失函数增长一个正则化惩罚(regularization penalty)$R(W)$部分。最经常使用的正则化惩罚是L2范式,L2范式经过对全部参数进行逐元素的平方惩罚来抑制大数值的权重:
$R(W)=\sum_k \sum_l W^2_{k,l}$
上面的表达式中,将W中全部元素平方后求和。注意正则化函数不是数据的函数,仅基于权重。包含正则化惩罚后,就可以给出完整的多类SVM损失函数了,它由两个部分组成:数据损失(data loss),即全部样例的的平均损失L_i,以及正则化损失(regularization loss)。完整公式以下所示:
$L= \underbrace{ \frac{1}{N}\sum_i L_i}_{data \ loss}+\underbrace{\lambda R(W)}_{regularization \ loss}$
将其展开完整公式是:
$L=\frac{1}{N}\sum_i\sum_{j\not=y_i}[max(0,f(x_i;W)_j-f(x_i;W)_{y_i}+\Delta)]+\lambda \sum_k \sum_l W^2_{k,l}$
其中,N是训练集的数据量。如今正则化惩罚添加到了损失函数里面,并用超参数lambda来计算其权重。该超参数没法简单肯定,须要经过交叉验证来获取。
其中最好的性质就是对大数值权重进行惩罚,能够提高其泛化能力,由于这就意味着没有哪一个维度可以独自对于总体分值有过大的影响。举个例子,假设输入向量$x=[1,1,1,1]$,两个权重向量$w_1=[1,0,0,0]$,$w_2=[0.25,0.25,0.25,0.25$。那么$w^T_1x=w^T_2=1$,两个权重向量都获得一样的内积,可是$w_1$的L2惩罚是1.0,而$w_2$的L2惩罚是0.25。所以,根据L2惩罚来看,$w_2$更好,由于它的正则化损失更小。从直观上来看,这是由于w_2的权重值更小且更分散。既然L2惩罚倾向于更小更分散的权重向量,这就会鼓励分类器最终将全部维度上的特征都用起来,而不是强烈依赖其中少数几个维度。在后面的课程中能够看到,这一效果将会提高分类器的泛化能力,并避免过拟合。
这里的话咱们主要采用的Regularization方法分别有好几种,以下图所示:
Softmax分类器,它的损失函数与SVM的损失函数不一样。对于学习过二元逻辑回归分类器的读者来讲,Softmax分类器就能够理解为逻辑回归分类器面对多个分类的通常化概括。SVM将输出$f(x_i,W)$做为每一个分类的评分(由于无定标,因此难以直接解释)。与SVM不一样,Softmax的输出(归一化的分类几率)更加直观,而且从几率上能够解释,这一点后文会讨论。在Softmax分类器中,函数映射$f(x_i;W)=Wx_i$保持不变,但将这些评分值视为每一个分类的未归一化的对数几率,而且将折叶损失(hinge loss)替换为交叉熵损失(cross-entropy loss)。公式以下:
$$Li=-log(\frac{e^{f_{y_i}}}{\sum_je^{f_j}}) 或等价的 L_i=-f_{y_i}+log(\sum_je^{f_j})$$
在上式中,使用$f_j$来表示分类评分向量f中的第j个元素。和以前同样,整个数据集的损失值是数据集中全部样本数据的损失值L_i的均值与正则化损失R(W)之和。
其中函数$f_j(z)=\frac{e^{z_j}}{\sum_ke^{z_k}}$被称做softmax 函数:其输入值是一个向量,向量中元素为任意实数的评分值(z中的),函数对其进行压缩,输出一个向量,其中每一个元素值在0到1之间,且全部元素之和为1。
信息理论视角:在“真实”分布p和估计分布q之间的交叉熵定义以下:
$$H(p,q)=-\sum_xp(x) logq(x)$$
所以,Softmax分类器所作的就是最小化在估计分类几率(就是上面的$e^{f_{y_i}}/\sum_je^{f_j})$和“真实”分布之间的交叉熵,在这个解释中,“真实”分布就是全部几率密度都分布在正确的类别上(好比:$p=[0,...1,...,0]$中在$y_i$的位置就有一个单独的1)。还有,既然交叉熵能够写成熵和相对熵(Kullback-Leibler divergence)$H(p,q)=H(p)+D_{KL}(p||q)$,而且delta函数p的熵是0,那么就能等价的看作是对两个分布之间的相对熵作最小化操做。换句话说,交叉熵损失函数“想要”预测分布的全部几率密度都在正确分类上。
译者注:Kullback-Leibler差别(Kullback-Leibler Divergence)也叫作相对熵(Relative Entropy),它衡量的是相同事件空间里的两个几率分布的差别状况。
几率论解释:先看下面的公式:
$$P(y_i|x_i,W)=\frac{e^{f_{y_i}}}{\sum_je^{f_j}}$$
能够解释为是给定图像数据$x_i$,以W为参数,分配给正确分类标签$y_i$的归一化几率。为了理解这点,请回忆一下Softmax分类器将输出向量f中的评分值解释为没有归一化的对数几率。那么以这些数值作指数函数的幂就获得了没有归一化的几率,而除法操做则对数据进行了归一化处理,使得这些几率的和为1。从几率论的角度来理解,咱们就是在最小化正确分类的负对数几率,这能够看作是在进行最大似然估计(MLE)。该解释的另外一个好处是,损失函数中的正则化部分R(W)能够被看作是权重矩阵W的高斯先验,这里进行的是最大后验估计(MAP)而不是最大似然估计。说起这些解释只是为了让读者造成直观的印象,具体细节就超过本课程范围了。
实操事项:数值稳定。编程实现softmax函数计算的时候,中间项$e^{f_{y_i}}$和$\sum_j e^{f_j}$由于存在指数函数,因此数值可能很是大。除以大数值可能致使数值计算的不稳定,因此学会使用归一化技巧很是重要。若是在分式的分子和分母都乘以一个常数C,并把它变换到求和之中,就能获得一个从数学上等价的公式:
$$\frac{e^{f_{y_i}}}{\sum_je^{f_j}}=\frac{Ce^{f_{y_i}}}{C\sum_je^{f_j}}=\frac{e^{f_{y_i}+logC}}{\sum_je^{f_j+logC}}$$
C的值可自由选择,不会影响计算结果,经过使用这个技巧能够提升计算中的数值稳定性。一般将C设为$logC=-max_jf_j$。该技巧简单地说,就是应该将向量f中的数值进行平移,使得最大值为0。代码实现以下:
f = np.array([123, 456, 789]) # 例子中有3个分类,每一个评分的数值都很大 p = np.exp(f) / np.sum(np.exp(f)) # 不妙:数值问题,可能致使数值爆炸 # 那么将f中的值平移到最大值为0: f -= np.max(f) # f becomes [-666, -333, 0] p = np.exp(f) / np.sum(np.exp(f)) # 如今OK了,将给出正确结果
其实能够看得出,咱们使用softmax和svm的时候,都是同时对于咱们的获得的score函数进行一个判决。
不一样的是他们的判决方法是不一样的。SVM分类器将它们看作是分类评分,它的损失函数鼓励正确的分类的分值比其余分类的分值高出至少一个边界值。Softmax分类器将这些数值看作是每一个分类没有归一化的对数几率,鼓励正确分类的归一化的对数几率变高,其他的变低。(其实softmax更加的直观一些)
通常来讲的话,咱们对于图像数据$x_i$,咱们若是对于参数集$W$作出来的分类预测和咱们的真实状况一致的话,那么咱们的loss $L$就很小。
这里面的话,其实咱们就是但愿经过咱们的优化方法可以实现损失函数最小化参数$W$的过程。
这里的话,整个课程里面举的例子是:人们沿着一个路线下山,若是没有地图,咱们怎么样最快的下山呢?最好的办法,沿着最陡峭的地方下山。最终咱们若是到达了山谷,那么咱们在山谷这一点的斜率能够近似的看做是0.
这里的话,根据Justin整理的课程笔记的话,因为咱们是进行神经网络的深度学习的,咱们通常的损失函数都是定义在高纬度的空间中间的,这里咱们是仅仅使用CIFAR-10数据集的话,咱们的线性分类器的权重矩阵的大小就是$[10*3073]$,总共有30730个参数。这个时候的话,咱们若是想要把这个损失函数可视化就很是的苦难了。可是这个时候,咱们若是在某几个维度上面对高维空间进行了切片处理,咱们就能够近似的知道这个时候的导数变化状况。
这里的话,咱们想要让咱们的损失函数达到极小值,那咱们应该怎么办呢?这时候有三个备选方法:
方法一:随机搜索;在随机搜索的时候,咱们随机的尝试不少不一样的权重,而后根据不一样的权重对应的损失函数,进而比较哪个最好。这种办法的话成功的准确率是很低的。
方法二:沿斜率降低;在咱们的一维空间中,咱们的函数的导数定义以下:$$\frac{df(x)}{dx} = \lim_{h \to 0}\frac{f(x+h)-f(x)}{h}$$
在多维的空间中,咱们的导数定义的话没有那么复杂,仅仅是使用咱们在各个方向上的梯度就能够解决。这里的话,咱们在每个方向上面的斜率的话其实就是这个点上面导数和方向的点乘积,某一个方向上面若是斜率最大那么就能够称之为是negative gradient。
这种方法的话其实就很像是咱们的迭代方法,若是咱们不达到局部最优,咱们就跳不出咱们的迭代过程。
这种方法其实可能也比较直观,可是由于使用了迭代,运算的复杂度实际上是比较大的。
方法三:这里的话,其实和上课的课件是存在区别的,这里的话咱们按照justin整理的笔记为主,这种方法咱们称之为随机本地搜索。
咱们上面的方法的话,其实能够看做是咱们每走一步都随机的选择几个方向,若是这个方向是朝着山下的那么咱们就降低一步。咱们新的方法的话,咱们从一个彻底随机的$W$开始,在以后每一次咱们随机的产生一个小的误差(未来报道出现了误差,我也有责任的)$\delta W$,这个时候只有咱们的$W + \delta W$这个损失下降了,咱们才会更新咱们的模型。
===上面的话,因为是根据PPT和Justin的笔记一块儿进行写的,因此可能逻辑上不是很清晰,可是内容都覆盖到了===
咱们通常的话,其实在计算机实现计算梯度的方法有两种:
第一种办法:数值梯度法,这种方法其实就是咱们一开始学习导数时候的数值方法,这种方法咱们本身用起来方便,同时实现也就简单;
第二种方法:分析梯度法:其实就是数学方法人工计算梯度表达式,这里面的话计算迅速(还不是由于咱们人工已经搞定了),计算结果精确,可是在实现的时候容易出错,同时须要使用微分。
这里的恶化,能够参考一下给出来的python代码,看一看numerical gradient:下面的代码中,输入是函数f和向量x,计算返回f在x的梯度
'''python
def eval_numerical_gradient(f,x):
fx = f(x)
grad = np.zeros(x.shape)
h = 0.000001
it = np.nditer(x,flags = ['multi_index'],op_flags = ['readwrite'])
while not ot.finished:
ix = it.multi_index old_value = x[ix] x[ix] = old_value + h fxh = f(x) x[ix] = old_value grad[ix] = (fxh - fx) /h it.iternext()
return grad
'''