浅谈 softmax 回归

softmax 是一个线性分类模型,其核心在于 softmax 运算。

分类问题

回归可以用于预测多少的问题,如房价、住院天数;分类模型则可以用于判断某一目标是否属于某一类别。对于分类问题,我们又有硬性软性分类,前者只希望得到目标的类别,后者则还需要目标属于每个类别的概率大小。实践中,即便对于硬分类问题,我们也采用软分类算法解决。

假设我们有一个图像分类问题,输入为 2×22 \times 2 的灰度图像,类别可能是猫、狗、鸡中的一个。

那么,我们的输入特征就是像素值 x=x1,x2,x3,x4\mathbf{x} = x_1, x_2, x_3, x_4 。而对于类别的表示,我们采用独热编码(one-hot encoding)的方式:独热编码是一个和类别数目分量一致的向量,某一类别的独热编码表示为该类别对应分量为 11 ,其余分量为 00 。在上述例子中,我们可以假定向量 (1,0,0)(1, 0, 0) 表示猫,(0,1,0)(0, 1, 0) 表示狗,(0,0,1)(0, 0, 1) 表示鸡。那么我们的标签 y(1,0,0),(0,1,0),(0,0,1)y \in {(1, 0, 0), (0, 1, 0), (0, 0, 1)}

softmax 回归

与前文中线性回归模型不同,分类问题需要模型有多个输出来对应每个类别。为此,我们需要和类别数量一样多的仿射函数(affine function),即通过线性变换和平移变换后得到的函数。例如,我们需要 1212 个标量来表示上例中的权重:

o1=x1w1,1+x2w1,2+x3w1,3+x4w1,4+b1o2=x1w2,1+x2w2,2+x3w2,3+x4w2,4+b2o3=x1w3,1+x2w3,2+x3w3,3+x4w3,4+b3 o_1 = x_1w_{1,1} + x_2w_{1, 2} + x_3w_{1, 3} + x_4w_{1, 4} + b_1\\ o_2 = x_1w_{2,1} + x_2w_{2, 2} + x_3w_{2, 3} + x_4w_{2, 4} + b_2\\ o_3 = x_1w_{3,1} + x_2w_{3, 2} + x_3w_{3, 3} + x_4w_{3, 4} + b_3\\

形式化地,softmax 回归的模型可以表达为 o=Wx+b\mathbf{o} = \mathbf{Wx} + \mathbf{b} 。如上图所示,softmax 回归是一个单层的全连接的神经网络。这样的全连接层虽然性能开销较大,但便于理解。

根据前文中对于分类问题的一般定义,我们知道,分类模型的输出需要是检测目标属于每个类别的概率大小。那么对于硬分类问题我们可以选择最大输出值的类别 argmaxiy^i\arg\max_i\hat{y}_i 作为预测,对于软分类问题直接给出 y^\hat{y} 即可。

考虑输出 oio_i ,其值可以根据输入特征和权重的变换在整个 R\R 上变化,这显然违背了基本的概率公理。进一步地,我们需要使整个输出的加和等于 11 ,即 i=1noi=1\sum_{i=1}^{n}o_{i} = 1 。为此,我们需要一个方法来标准化模型输出。这一操作可以通过 softmax 函数 来实现。softmax 函数可以将未规范化的预测变换为非负数且总和为 11 ,同时保持模型可导的性质。这一绝佳的函数性质十分适合作为分类问题的目标函数:

y^=softmax(o) \hat{\mathbf{y}} = \text{softmax}(\mathbf{o})

其中

y^j=exp(oj)kexp(ok). \hat{y}_j = \frac{\exp(o_j)}{\sum_k\exp(o_k)}.

因此,y^\hat{\mathbf{y}} 可以视作一个正确的概率分布。尽管不难看出,softmax 函数并非一个线性函数,但 softmax 回归的输出仍然由输入特征的仿射变换决定,因此仍是一个线性模型。

损失函数

我们需要一个确定模型拟合程度好坏的度量,该度量被称作损失函数(loss function),能够量化目标的实际值与预测值之间的差距。损失通常是非负的,且数值越小代表损失越小。

平方损失函数

对于回归问题,最常用的损失函数为平方损失函数(Square Error Function)

l(i)(w,b)=12(y^(i)y(i))2. l^{(i)}(\mathbf{w}, b) = \frac{1}{2}(\hat{y}^{(i)} - {y}^{(i)})^2.

常数 12\frac{1}{2} 的意义在于使 ll 的导数常数系数为 1 。对于整个数据集,我们有:

L(w,b)=1ni=1nl(i)(w,b)=1ni=1n12(wx(i)+by(i))2. L(\mathbf{w}, b) = \frac{1}{n} \sum^n_{i = 1}l^{(i)}(\mathbf{w}, b) = \frac{1}{n}\sum^{n}_{i = 1}\frac{1}{2}(\mathbf{w}^{\top}\mathbf{x}^{(i)} + b - y^{(i)})^2 .

我们训练模型的过程即寻找一组参数 w,b\mathbf{w}^*,b^* ,使得 L(w,b)L(\mathbf{w}^*,b^*) 最小。那么如何求得这一组最优参数呢?

随机梯度下降

梯度下降(gradient descent)是一种通过不断地在损失函数递减的方向上更新参数来降低误差的方法,广泛应用于各类深度学习模型上。这其中,梯度即代表损失函数关于模型参数的导数。

为了避免在每一次更新时遍历一遍数据集,我们通常会在每次需要更新的时候随机抽取一小批样本,即小批量随机梯度下降(minibatch stochastic gradient descent)

在每次迭代时,我们首先随机抽样一个容量固定的小批量 B\mathcal{B} ,并计算小批量的平均损失关于模型参数的偏导数。最后,我们将梯度乘以一个预先确定的正数 η\eta学习率,learning rate),并从当前参数的值中减掉。

形式化地,对于每次迭代,我们有:

(w,b)(w,b)ηBiB(w,b)l(i)(w,b). (\mathbf{w}, b) \larr (\mathbf{w}, b) - \frac{\eta}{\vert\mathcal{B}\vert} \sum_{i \in \mathcal{B}}\partial_{(\mathbf{w}, b)}l^{(i)}(\mathbf{w}, b) .

其中

(w,b)l(i)(w,b)=(l(i)w,l(i)b) \partial_{(\mathbf{w}, b)}l^{(i)}(\mathbf{w}, b) = \left(\frac{\partial l^{(i)}}{\partial \mathbf{w}}, \frac{\partial l^{(i)}}{\partial b}\right)

对于类似 η\etaB\vert\mathcal{B}\vert批次大小,batch size) 的可以调整但是不在训练过程中的参数我们成为超参数(hyperparameter)调参(hyperparameter tuning) 即选择超参数的过程。

需要注意的是,即便函数完全遵循线性回归且无噪声,模型参数 w^\hat{\mathbf{w}}b^\hat{b} 也不会达到实际最小值,而是无限接近最小值。对于较为复杂的深度神经网络,损失平面通常包含多个最小值。实践上一般不会追求训练集上的最小损失,而是追求能在陌生数据上实现较小损失。这一过程即泛化(generalization)

交叉熵损失函数

让我们回到 softmax 回归。

softmax 函数让模型输出标准化为概率,如 y^1=P(y=x)\hat{y}_1 = P(y = 猫 \mid \mathbf{x}) 。假设数据集 {X,Y}\{\mathbf{X}, \mathbf{Y}\}nn 个样本,其中特征向量为 x(i)\mathbf{x}^{(i)} ,独热标签向量(ground truth)为 y(i)\mathbf{y}^{(i)} 。那么我们有:

P(YX)=i=1nP(y(i)x(i)). P(\mathbf{Y} \mid \mathbf{X}) = \prod^n_{i = 1}P(\mathbf{y}^{(i)}\mid \mathbf{x}^{(i)}).

我们称上式为整个数据集的似然(likelihood),其中 P(AB)P(A \mid B) 表示 A 在 B 发生的条件下发生的概率。

似然

让我们先回顾一下模型的本质。

在概率模型里,我们认为数据是从某个分布里“采样”来的。也就是说,世界上所有猫的照片,都是从某个潜在分布 P真实(x)P_{真实}(x) 中抽取的样本。所谓分布,即决定随机变量可能出现的“规律”,它告诉我们每个可能结果出现的概率有多大。我们显然只能获得从真实分布中抽取到的有限大小的样本,而我们希望模型从这些有限大小的样本中尽可能拟合出真实的分布。

似然,即当模型参数一定时,观察到数据的“可能性”大小。具体地,假设我们有一个参数为 θ\theta 的模型,其有一个概率分布 P(xθ)P(x \mid \theta) 。我们又有一组真实数据 xobsx_{\text{obs}} ,那么似然函数 L(θ)=P(xobsθ)L(\theta) = P(x_{\text{obs}} \mid \theta) ,即在参数为 θ\theta 时我们有多可能观测到 xobsx_{\text{obs}} 这一数据。相对于概率计算的是参数固定的情况下不同数据有多可能出现,似然计算的是数据固定的前提下,不同参数时的分布下这个数据有多可能出现。

我们通常要找让似然最大的参数,其根本原因在于我们试图找到一个概率分布 P(xθ)P(x \mid \theta) ,使得这一分布尽可能接近真实世界中的概率分布。我们的计算也就是在求 θ^MLE=argmaxθL(θ)\hat{\theta}_{\text{MLE}} = \arg\max_{\theta}L(\theta) ,其中 L(θ)L(\theta) 为似然函数。

回到交叉熵损失中,根据最大似然估计,我们最大化 P(YX)P(\mathbf{Y} \mid \mathbf{X}) ,相当于最小化负对数似然:

logP(YX)=i=1nlogP(y(i)x(i))=i=1nl(y(i),y^(i)). -\log P(\mathbf{Y} \mid \mathbf{X}) = \sum_{i = 1}^n -\log P(\mathbf{y}^{(i)} \mid \mathbf{x}^{(i)}) = \sum_{i = 1}^n l(\mathbf{y}^{(i)}, \hat{\mathbf{y}}^{(i)}).

即损失函数为

l(y,y^)=j=1qyjlogy^j. l(\mathbf{y}, \hat{\mathbf{y}}) = - \sum_{j=1}^q y_j \log \hat{y}_j.

我们称 ll交叉熵损失函数(cross-entropy loss function)。至于最小化负对数似然的原因,其一是由于对数运算的性质 logab=loga+logb\log ab = \log a + \log b 更便于梯度计算且对数函数单调递增,二是取负号方便进行最小化,满足损失函数最小时损失最小的性质,三是对数自然对应了信息量。

信息量

信息论中,我们称能量化数据中信息内容的量为分布 PP(entropy):

H[P]=jP(j)logP(j). H[P] = \sum_j - P(j) \log P(j).

上式中,P(j)P(j) 为事件 jj 发生的概率,log1P(j)=logP(j)\log \frac{1}{P(j)} = -\log P(j) 为事件 jj 的信息量(越不可能发生信息量的值越大)。直观地来讲,如果一件事经常发生,我们不会对它感到惊异,信息量就小;反之,如果一件事很少发生,我们会对其感到惊异,信息量就大。熵 H[P]H[P] 也就是通过把每件事发生的概率加权,求出所有可能事件的平均信息量。

那什么是交叉熵呢?我们记交叉熵为 H(P,Q)H(P, Q) ,描述一个主观概率为 QQ 的观察者在看到根据概率 PP 生成的数据时的预期差异。当 P=QP = Q 时,交叉熵达到最低,即 H(P,P)=H(P)H(P, P) = H(P)

回归到交叉熵损失函数中,如果对于某一组数据,真实类别是第 kk 类,那么 yk=1y_k = 1 ,其他全为 00 。损失化简为 l(i)=logy^kl^{(i)} = -\log \hat{y}_ky^k<0\hat{y}_k < 0 ,则 l(i)>0l^{(i)} > 0 ,且 y^k\hat{y}_k 越接近 11l(i)l^{(i)} 越小。也就是说,模型越相信正确类别(y^k\hat{y}_k越大),损失越小;反之损失越大。从信息论的角度来讲,交叉熵损失函数实际上是在计算模型输出的概率分布距离真实分布的不匹配度,衡量了预测分布与真实分布之间的差距。