Deep Learning with Python 读书笔记(四)导数、梯度和随机梯度下降

什么是导数(derivative)?

一个连续函数f(x) = y,其中x和y都是实数,当x值有个微小的变化时,y的值也会只有一个微小的变化,所以f(x+epsilon_x) = y+epsilon_y,这里epsilon_x和epsilon_y都是一个很小的值。当f(x)函数代表一条光滑的曲线时,我们可以用一条直线模拟f(x)在点p周围的微小变化,因此我们可以再把上面的公式写成:

f(x+epsilon_x) = y + a*epsilon_x (前提是epsilon_x和epsilon_y都是一个很小的值),这里a是曲线f在点p的斜率,见下图。

 

 这个斜率a也被称作是函数f在点p处的导数。当a是负数时,x在点p附近的一个小小的增加会引起f(x)值的减少;反之,就会引起f(x)值的一个很小的增加。所以对所有可导函数来说,在所有的点上都存在一个对应关系f(x) = f'(x) * a,其中f'(x)就是f(x)的导函数。如果f(x) = cos(x),f'(x) 就是-sin(x);如果f(x) = ax,f'(x) = a。所以,如果你要减小f(x)的值的话,你只需要沿着与导数相反的方向稍微移动x即可。

张量运算的“导数” - 梯度(Gradient)

张量运算的导数是多变量函数导数概念的扩展,因为张量运算可以被看成是以张量作为参数的函数。现在有一个输入向量x,权重矩阵W,目标y和损失函数loss,我们可以用W来计算预测值y_pred和损失值,于是我们有:

y_pred = dot(W, x)

loss_value = loss(y_pred, y)

如果输入x和输出y保持不变,那么loss_value = loss(dot(W, x), y),它也可以被看成是一个W的函数,loss_value = f(W)

假如W的当前值是W0,那么f在点W0的导数就是梯度gradient (f) (W0)(好像上面曲线例子中的斜率),也就是说W0矩阵里面的任何一个元素值的微小变化都会引起loss_value的微小变化,变化方向也如上面所说,就是沿着与导数相反的方面变化就会让loss_value稍微变小。提示:这里f(W)的导数就好像是多变量函数的偏微分。

随机梯度下降(Stochastic Gradient Descent)

给出一个可微函数,理论上我们总可以找到其最小值,因为我们知道函数的最小值对应的点导数为0,所以我们只需要找出该函数所有导数为0的点,然后从中找出给出函数最小值的那个点就可以了。对于一个神经网络而言,这就意味着我们要找出使得损失函数值最小的权重矩阵Wi,也就是gradient (f) (Wi) = 0,这实际上是个多项式方程式,其中的变量个数是N(也是W中元素的个数)。

当N取一个很小的值的时候,上面问题很容易解决。但是在实际中,神经网络的权重矩阵可能包含几千甚至更多的元素,所以我们会用一种不同的方法,但基本道理还是一样,只是这种方法更容易在电脑上实现。其步骤如下:

  1. 从训练数据集中抽取一批数据x和对应的输出标签y
  2. 在神经网络中计算x的预测值y_pred
  3. 计算这批数据对应的损失函数值(y和y_pred之间的差值)
  4. 计算对应该权重矩阵的梯度
  5. 沿着跟梯度相反的方向微调权重矩阵,使得损失函数值下降

上面所描述的过程被称作“迷你”批量随机梯度下降(minibatch SGD)。这里“随机”的意思是指每批数据都是随机抽取的。下图给出了一个及其简化的场景(权重矩阵只有一个元素,训练样本只有一个数据点),但是也能说明一些主要问题。

 

 

猜你喜欢

转载自www.cnblogs.com/jointech/p/12347884.html