最优化 Optimization
最优化就是通过计算权重\(W\)来最小化损失函数。如果损失函数是SVM损失,那么这个凸函数是可以用凸优化的方法进行的。但是当损失函数扩展成为神经网络时,那么目标函数就不是凸函数了,而且损失函数中存在不可导点(kinks),使得这些点不可微,在这些点也没有梯度的定义。但是次梯度(subgradient)依然可以使用。
我们从最基本的方案开始逐步过渡到梯度的方法。
随机搜索
大量随机生成权重矩阵,然后比较它们的损失值,取最小的权重作为我们要找的权重去跑测试集。
当随机猜测时,正确概率是10%,这里用多次筛选得到随机矩阵提升了一点。如果我们能够设计一个迭代算法,使得每次迭代后的损失值都减少一点,那么就能找到更好的\(W\)。
随机本地搜索
设计一个迭代算法,每一次都随机尝试几个方向,如果方向是向下(能让损失值小一点),那就向该方向走一步。依然从随机的\(W\)开始,每次给予一个随机扰动\(\delta W\),如果扰动后损失值更小了,就更新权重矩阵。
用同样的方法,相比上述方法准确率更高(20%),但是因为迭代过程是随机的,所以训练时间和效果都不稳定。
跟随梯度
这里的迭代算法保证了每次都是走向局部最优的低处,这个方向就是损失函数的梯度(gradient)。梯度是各个维度的斜率组成的向量(导数derivatives)。当函数有多个参数时,梯度是每个维度上偏导数所形成的向量。
梯度计算
计算梯度的方法有两种:数值梯度法(近似),分析梯度法(精确,需要微分)。
用梯度公式\(\frac{f(x+h)-f(x)}{h}\)在所有维度上进行计算,得到的grad中包括了在每个维度上的偏导数。h的取值越小越好,实际中使用中心差值公式(centered difference formula,对称差分中一次项误差相消)会更好,公式为\(\frac{[f(x+h)-f(x-h)]}{2h}\)。以下函数是根据输入函数与向量计算函数梯度的函数:
通过这个函数可以计算任何函数在任意点上的梯度,并用于更新权重。这里是向着梯度的负方向进行更新,因为我们希望损失函数值是降低的。在这个计算过程中,学习步长是关键的超参数(学习率),过大的步长会导致更高的损失值。
使用数值近似的方法每一步要计算N维权值矩阵的每一个梯度,当神经网络中参数众多时,这个方法将不再适合。
用微分的方法得到损失函数的梯度公式,不好的地方在于容易出错。所以在实际应用时,会将分析梯度法与数值梯度法结果比较,来检查微分分析的正确性,这个步骤叫做梯度检查。
这里将SVM损失函数进行微分:
\(L_i=\sum_{j \neq y_i}[max(0,w_j^T x_i-w_{y_i}^T x_i+\Delta)]\)
\(\bigtriangledown_{w_{y_i}} L_i=-(\sum_{j \neq y_i}\mathbb{I}(w_j^T x_i-w_{y_i}^T x_i+\Delta>0))x_i\)
其中的\(\mathbb{I}\)是一个示性函数,若括号中条件为真则函数值为1,否则为0。这里的微分公式非常简单,不满足条件的分类乘以\(x_i\)就是梯度了。这里的梯度对应正确分类的权值矩阵行向量梯度,其他行的梯度为:
\[\bigtriangledown_{w_{y_i}} L_i=\mathbb{I}(w_j^T x_i-w_{y_i}^T x_i+\Delta>0)x_i\]
梯度下降
得到损失函数的梯度后就可以进行梯度下降的过程。普通的梯度下降法只适用于小数据量,在大数据量下,计算整个数据集来获取一个参数的代价过高,常用方法是计算训练集中的小批量(batches)数据。因为训练集中的数据大多相关,通过小批量数据梯度计算可以实现快速收敛,以此进行更频繁地更新。
当每个批量中只有一个数据样本时,这种策略被称为随机梯度下降(Stochastic Gradient Descent, SGD)。一般来说,小批量数据的大小一般使用2的指数,因为它由存储器限制,输入是2的倍数时运算会大大加快。
最优化是为了解决损失函数最小时权重矩阵如何得到的问题,也就是求参的问题。当损失函数为凸函数可以使用凸优化,而当不可微点多或非凸函数时,则要使用梯度下降的方法求局部最优,有时近似法也要用来进行梯度检查。
后面我将继续学习反向传播(backpropagation)机制,它使用链式法则来高效计算梯度,能够对包含CNN在内的大多数神经网络的损失函数进行最优化。