Logo
Section 1 / 6

线性分类器

探索线性分类器、其基本原理及训练过程。

导入

线性分类器

探索线性分类器、其基本原理及训练过程。

什么是线性分类器?

假设我们想构建一个机器学习模型,根据点的颜色将其分为两类。很容易看出,我们可以找到一个单一点将它们完美地分开。我们的模型目标就是找出这个点。

...
线性可分的一维数据点

最简单的方法是构建一个线性分类器。我们的分类器形式为 f(x,w)=w1∗x1+w2f(x, w) = w_1*x_1+w_2。函数 f(x,w)f(x,w) 的作用是寻找参数 w1w_1 和 w2w_2,使得任意标量点(一维)都能被准确区分。如果 f(x,w)>0f(x,w)>0,则该点属于蓝色类别;否则属于红色类别。
听起来很简单对吧?

现在我们将这个想法扩展到二维数据点!

每个点现在表示为 (x1,x2)(x_1, x_2)。

在二维情况下,我们需要找到一条直线(而不是一个点)来分割这些二维点,因此分类器的形式变为:
f(x,w)=w1∗x1+w2∗x2+w3f(x,w) = w_1*x_1 +w_2*x_2+ w_3。
同样,我们需要训练分类器以找到最优的 w1w_1、w2w_2 和 w3w_3。

...
线性可分的二维数据点

这个思想可以自然地推广到任意 N 维空间。在二维中是一条直线,在三维中是一个平面,在更高维度中则是 N 维超平面。我们称其为 N 维空间中的超平面,它可以将空间划分为两个类别(红色和蓝色)。

我们将利用线性代数和矩阵来表达这一概念。为了便于阅读,矩阵用粗体表示。

最终,我们得到:
f(x,W)=W∗x+bf(x,\mathbf{W}) =\mathbf{W}*x +b,
其中 xx 是一个 N 维向量,bb 是一个标量,W\mathbf{W} 是一个 1×N1 \times N 的矩阵。我们需要找到合适的 W\mathbf{W} 和 bb 来定义这个超平面。一旦确定了这两个参数,就可以对任意数据点 xx 判断其类别 yy。

从现在起,我们将分类器记作 f(xi,W)f(x_i, \mathbf{W})。

...
线性分类器

在 PyTorch 中,只需一行代码就可以构建一个具有 5 个输入和 10 个输出的线性分类器。以下代码会初始化一个可训练的矩阵 W\mathbf{W} 和一个向量 bb,每次使用分类器实例 classifier 时,都会执行操作 y=W∗x+by = \mathbf{W}*x +b。

1## 基本导入 2import torch 3import torch.nn as nn 4 5## 初始化矩阵 W 和向量 b 6classifier = nn.Linear(5, 10)

训练分类器

我们知道,要完成分类任务,需要找到合适的矩阵 W\mathbf{W} 和向量 bb。

但具体怎么做呢?

首先,我们需要训练数据。训练数据是指那些我们已知类别(目标类别 tt)的数据点 (xx)。我们可以利用这些已知信息来“训练”分类器。

“训练”分类器指的是通过输入已知的数据点,不断调整并寻找最优矩阵 W\mathbf{W} 的过程。

由于我们知道数据的“标签”(即类别),这类方法被称为监督学习。数据以成对形式 (x,t)(x,t) 提供:我们将 xx 输入分类器,用标签 tt 来计算损失(误差)。注意,yy 表示分类器的输出,满足 y=W∗x+by= \mathbf{W}*x +b。

直观上,我们要让一个随机初始化的模型逐步学会从输入 xx 到标签 tt 的映射关系。

在描述训练过程之前,还需要介绍两个重要概念。

损失函数

损失(或代价)用于衡量某个数据点分类结果的好坏程度。换句话说,它表示分类器对数据点 xx 的预测输出 yy 与真实类别 tt 之间的差距。我们来明确一下:

给定一个包含 N 个样本的数据集 (xi,ti){(x_i,t_i)},其中 xix_i 是一个 N 维空间中的点,tit_i 是表示其类别的整数,那么损失就是 f(xi,W)f(x_i, W) 与 tit_i 之间的距离。Ci(f(xi,W),ti)C_i( f(x_i,W),t_i) 表示单个样本 xix_i 的代价。

整个训练数据的总损失就是所有个体损失的平均值。但在实际应用中,我们通常不会对全部数据点的损失求平均。

需要注意的是,损失函数的选择取决于具体问题和数据形式。在此我们采用均方误差作为损失函数,定义如下:

C=∑(f(xi,W)−ti)2C= \sum(f(x_i,W) - t_i)^2

注意,这里的求和是对向量元素进行的。下面是一个代码示例:

1import torch 2import torch.nn as nn 3 4model = nn.Linear(10,3) 5loss = nn.MSELoss() 6## 虚构输入 x 7input_vector = torch.randn(10) 8## 类别 3,表示为一个仅在类别索引位置为 1 的向量 9target = torch.tensor([0,0,1]) 10## 数学中的 y 11pred = model(input_vector) 12output = loss(pred, target) 13print("预测值: " ,pred) 14print("损失值: " , output)

需要理解的是,尽管目标类别本身是一个标量(如上面的例子中为 3),但我们将其转换为张量形式。对于三个类别,可能的目标向量 tt 如下:

1类别 1 -> [1,0,0] 2类别 2 -> [0,1,0] 3类别 3 -> [0,0,1]

优化与训练过程

优化是指寻找使损失函数最小化的权重矩阵 W\mathbf{W} 的过程。换句话说,就是选择各个权重 wiw_i,使得分类器的预测输出 yy 尽可能接近样本的真实标签 tt。

数学上可以表示为:

w′=argminw(C(w))w^{\prime} = argmin_w(C(w))

目前我们只需知道,优化是一个抽象概念,描述了我们如何选择权重矩阵的过程。更详细的讨论将在下一课关于神经网络的部分展开。

现在我们可以完整描述训练算法的流程:

给定一组带有标签 tit_i 的训练样本 xix_i,我们需要:

  • 使用随机初始化的权重矩阵 W\mathbf{W} 初始化分类器 f(xi,W)f(x_i,\mathbf{W});
  • 将一个训练样本输入分类器,得到输出 yiy_i;
  • 计算预测值 yiy_i 与真实标签 tit_i 之间的损失;
  • 根据损失 CiC_i 调整权重 W\mathbf{W}(具体方法见下一课);
  • 对所有训练样本重复上述步骤。

这正是所有深度学习模型的核心思想。最终,我们会得到一个训练好的分类器,能够泛化到之前未见过的新样本上。

目前唯一还不清楚的步骤是如何调整权重,我们将在下一课详细讨论这一点。

学习深度学习

优化与梯度下降