本节中,我们将介绍模型训练的基本数学原理,以及在分布式训练中我们需要考虑的精度,优化器等问题。
训练的数学原理
在最优化里面,我们需要解决的问题一般有如下形式:
$$ \min_x\ f(x) $$这里 $f$是我们的目标函数, $x$是我们的变量。一个比较简单的例子就是求一个给定函数的最小值。
如果说,我们想要基于数据来训练一个模型,这个时候,我们目标函数的输入就包括两部分,一部分是模型参数,另一部分是数据,为了方便起见,我们使用$\theta$来代表模型的参数,用 ${x_i,y_i}_{i=1}^N$ 来表示模型的训练集。上述的优化问题改写如下:
$$ \min_{\theta}\ \frac{1}{N}\sum_{i=1}^Nf(x_i,y_i\;\theta) $$比如我们训练 resnet 作为分类器,那么 resnet 的模型参数就是这里的 $\theta$, 训练集就是我们的图片和对应的标签,比如ImageNet等,对应的$f$可以设定为 cross entropy loss.
现在有了优化问题之后,我们就需要设计算法求解这个优化问题。一个最简单的优化算法就是梯度下降算法:
$$ \theta^{k+1} = \theta^k - \alpha_k\frac{1}{N}\sum_{i=1}^N\nabla_{\theta}f(x_i,y_i;\theta^k) $$这里 $\nabla_{\theta}f(x;\theta^k)$ 是 $f$ 相对于 $\theta$ 在 $\theta^k$ 处的梯度。
但是,当我们模型过于复杂的时候,梯度往往计算起来非常复杂。为了简化模型的训练,现在的框架如tensorflow和pytorch都支持自动微分。因此,我们只需要定义如何从输入 $(x_i,y_i)$计算得到 $f(x_i,y_i;\theta)$ 就可以了,框架会帮我们计算参数的梯度。
自动微分
自动微分的目的是将求导的过程交给框架,从而让用户专注于模型的开发(也就是设计forward
函数)。
自动微分的核心思想就是链式法则.
$$ \frac{dy}{dx} = \frac{dy}{df}\frac{df}{dg}\frac{dg}{dh}\frac{dh}{dx} $$如果我们的中间函数 $g$, $h$非常复杂的话,那么整个求导过程就会非常复杂。而链式法则则是将这样一个全局过程给分解成了若干个局部过程。我们将 $y$ 表示为:
$$ \begin{aligned} y &= f(y_1)\\ y_1&=g(y_2)\\ y_2&=h(y_3)\\ y_3&=x \end{aligned} $$接下来,
总结
在本文中,我们简单介绍了一下如何训练一个模型,我们使用pytorch作为例子展示了现在训练框架的工作方式。在下一篇博客中,我们将会探究训练精度和优化器。训练精度和优化器是模型在训练过程中需要考虑的重点之一。