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