在上一节中,我们学习了最简单的神经网络模型--单层感知器,这是一种线性两类分类模型。
在本节中,我们将把这一模型扩展到一个更灵活的框架中,使我们能够
- 除两级分类外,还能进行多级分类。
- 除了分类,还能解决**回归问题
- 分离不可线性分离的类别
我们还将用 Python 开发自己的模块化框架,以便构建不同的神经网络架构。
让我们从机器学习问题的形式化开始。假设我们有一个标有Y的训练数据集X,我们需要建立一个能做出最准确预测的模型f。预测的质量由损失函数 ℒ来衡量。通常会用到以下损失函数:
- 对于回归问题,当我们需要预测一个数字时,我们可以使用绝对误差。 ∑i|f(x(i))-y(i)|, 或平方误差 ∑i(f(x(i))-y(i))2
- 对于分类,我们使用0-1损失(与模型的准确率基本相同)或逻辑损失。
对于单级感知器,函数 f 被定义为线性函数 f(x)=wx+b(此处 w 为权重矩阵,x 为输入特征向量,b 为偏置向量)。对于不同的神经网络架构,该函数的形式可能更为复杂。
在分类的情况下,通常希望得到相应类别的概率作为网络输出。为了将任意数字转换为概率(例如,对输出进行归一化处理),我们经常使用 softmax函数 σ,函数 f 变为 f(x)=σ(wx+b)
在上面f的定义中,w和b被称为参数 θ=⟨w,b⟩。给定数据集⟨X,Y⟩,我们可以计算出整个数据集的总体误差作为参数 θ 的函数。
✅ 神经网络训练的目标是通过改变参数 θ 使误差最小化。
有一种众所周知的函数优化方法叫梯度下降。其原理是,我们可以计算损失函数相对于参数的导数(在多维情况下称为梯度),并通过改变参数来减少误差。具体方法如下
- 用一些随机值初始化参数 w(0), b(0)
- 重复以下步骤多次:
- w(i+1) = w(i)-η∂ℒ/∂w
- b(i+1) = b(i)-η∂ℒ/∂b
在训练过程中,优化步骤的计算应该考虑整个数据集(请记住,损失的计算是所有训练样本的总和)。然而,在现实生活中,我们会从数据集中抽取一小部分数据,称为小批量,然后根据数据子集计算梯度。由于每次都是随机抽取子集,因此这种方法被称为随机梯度下降**(SGD)。
如上所述,单层网络能够对线性可分离的类别进行分类。为了建立更丰富的模型,我们可以将多层网络结合起来。从数学上讲,这意味着函数 f 的形式将更加复杂,并将分几步进行计算:
- z1=w1x+b1
- z2=w2α(z1)+b2
- f = σ(z2)
这里,α是一个非线性激活函数,σ是一个软最大函数,参数为 θ=<w1,b1,w2,b2>.
梯度下降算法将保持不变,但计算梯度将更加困难。根据链微分法则,我们可以计算出导数:
- ∂ℒ/∂w2 = (∂ℒ/∂σ)(∂σ/∂z2)(∂z2/∂w2)
- ∂ℒ/∂w1 = (∂ℒ/∂σ)(∂σ/∂z2)(∂z2/∂α)(∂α/∂z1)(∂z1/∂w1)
✅链微分法则用于计算损失函数相对于参数的导数。
请注意,所有这些表达式的最左侧部分都是相同的,因此我们可以有效地从损失函数开始计算导数,并在计算图中 "倒推"。因此,训练多层感知器的方法被称为反向推导,或 "反向推导"。
✅我们将在笔记本范例中更详细地介绍 backprop。
在本课中,我们建立了自己的神经网络库,并用它完成了一个简单的二维分类任务。
在随附的笔记本中,你将实现自己的多层感知器构建和训练框架。您将能够详细了解现代神经网络是如何运行的。
进入 OwnFramework 笔记本并完成它。
反向传播是人工智能和 ML 中常用的算法,值得 [详细] 学习(https://wikipedia.org/wiki/Backpropagation)
本实验要求您使用本课构建的框架来解决 MNIST 手写数字分类问题。