动手学深度学习-多重感知机笔记

  • 多层感知机
    • 多层感知机的从零开始实现
    • 多层感知机的简洁实现
  • 范数与权重衰减(weight decay)
  • 暂退法(Dropout)
  • 前向传播和反向传播
  • 梯度消失和梯度爆炸
  • 模型验证方法
  • 过拟合和欠拟合

多层感知机

多层感知机(multilayer perceptron,简称MLP):由多层神经元组成,每一层都与下面一层和上面一层完全相连。

图1:含有一个隐藏层的多层感知机

图1的感知机模型层数为2,输入层不涉及计算,所以一般不算输入层。隐藏层和输出层是全连接的。每个输入都会影响隐藏层中的每个神经元,而隐藏层中的每个神经元又会影响输出层中的每个神经元。

我们通过矩阵X∈Rn×dX\in R^{n×d}X∈Rn×d来表示n个样本的小批量,其中每个样本具有d个输入特征。对于具有h个隐藏单元的单隐藏层多层感知机,用H∈Rn×hH∈R^{n×h}H∈Rn×h表示隐藏层的输出。隐藏层权重W(1)∈Rd×hW^{(1)}∈R^{d×h}W(1)∈Rd×h和隐藏层偏置b(1)∈R1×hb^{(1)}∈R^{1×h}b(1)∈R1×h以及输出层权重W(2)∈Rh×qW^{(2)}∈R^{h×q}W(2)∈Rh×q 和输出层偏置b(2)∈R1×qb^{(2)}∈R^{1×q}b(2)∈R1×q。形式上,我们按如下方式计算单隐藏层多层感知机的输出 O∈Rn×qO∈R^{n×q}O∈Rn×q:
H=σ(XW(1)+b(1))O=HW(2)+b(2)H=\sigma (XW^{(1)}+b^{(1)})\\ O=HW^{(2)}+b^{(2)} H=σ(XW(1)+b(1))O=HW(2)+b(2)在仿射变换之后应用非线性激活函数σ(⋅)\sigma(·)σ(⋅)防止多层感知机退化成线性模型。

(由于XXX中的每一行对应于小批量中的一个样本,出于记号习惯的考量,我们定义非线性函数σ也以按行的方式作用于其输入,即一次计算一个样本。)

多层感知机在输出层和输入层之间增加一个或多个全连接隐藏层,并通过激活函数转换隐藏层的输出。

常用的激活函数包括ReLU函数、Sigmoid函数和Tanh函数。


多层感知机的从零开始实现

Fashion-MNIST中的每个图像由 28 × 28 = 784个灰度像素值组成。所有图像共分为10个类别。忽略像素之间的空间结构,我们可以将每个图像视为具有784个输入特征和10个类的简单分类数据集。首先,我们将实现一个具有单隐藏层的多层感知机,它包含256个隐藏单元。通常,我们选择2的若干次幂作为层的宽度。因为内存在硬件中的分配和寻址方式,这么做往往可以在计算上更高效。

import torch
from torch import nn
from d2l import torch as d2lbatch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs, num_outputs, num_hiddens = 784, 10, 256# 初始化模型参数
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]# 定义ReLU激活函数
def relu(X):a = torch.zeros_like(X) return torch.max(X, a)# 多重感知机
def net(X):X = X.reshape((-1, num_inputs))H = relu(X@W1 + b1) # 这里“@”代表矩阵乘法return (H@W2 + b2)
loss = nn.CrossEntropyLoss()num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)d2l.predict_ch3(net, test_iter)

多层感知机的简洁实现

import torch
from torch import nn
from d2l import torch as d2lnet = nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10))
def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=lr)train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

范数与权重衰减(weight decay)

权重衰减是正则化的技术之一,它通常也被称为L2正则化。

L1正则化线性回归通常被称为套索回归(lasso regression),L1 正则化会导致模型将权重集中在一小部分特征上, 而将其他权重清除为零,可用于特征选择。

L2正则化线性模型构成经典的岭回归(ridge regression)算法。L2范数对权重向量的大分量施加了巨大的惩罚,这使得我们的学习算法偏向于在大量特征上均匀分布权重的模型。

• 正则化是处理过拟合的常用方法:在训练集的损失函数中加入惩罚项,以降低学习到的模型的复杂度。

L2正则化线性模型损失函数:
L(w,b)=1n∑i=1nl(i)(w,b)+λ2∣∣w∣∣2L(\mathbf w,b)=\frac{1}{n}\sum_{i=1}^nl^{(i)}(\mathbf w,b)+\frac{\lambda}{2}||\mathbf w||^2 L(w,b)=n1​i=1∑n​l(i)(w,b)+2λ​∣∣w∣∣2
L2正则化回归的小批量随机梯度下降更新如下式:
w←(1−ηλ)w−η∣B∣∑i∈B∂wl(i)(w,b)\mathbf w\gets{\color{Red}(1-\eta\lambda)\mathbf w}-\frac{\eta}{|\mathcal B|}\sum_{i\in\mathcal B}{\partial}_{\mathbf w}l^{(i)}(\mathbf w,b) w←(1−ηλ)w−∣B∣η​i∈B∑​∂w​l(i)(w,b)
根据估计值与观测值之间的差异来更新w\mathbf ww,同时也在试图将w\mathbf ww的大小缩小到零。这就是为什么这种方法有时被称为权重衰减。较小的λ值对应较少约束的w\mathbf ww,而较大的λ值对w\mathbf ww的约束更大。

%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2ln_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)def train_concise(wd):net = nn.Sequential(nn.Linear(num_inputs, 1)) for param in net.parameters():param.data.normal_()loss = nn.MSELoss(reduction='none') num_epochs, lr = 100, 0.003# 偏置参数没有衰减trainer = torch.optim.SGD([{"params":net[0].weight,'weight_decay': wd},{"params":net[0].bias}], lr=lr)animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test']) for epoch in range(num_epochs):for X, y in train_iter: trainer.zero_grad() l = loss(net(X), y) l.sum().backward() trainer.step()if (epoch + 1) % 5 == 0: animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范数:', net[0].weight.norm().item())
# train_concise(0)
train_concise(3)

• 正则化是处理过拟合的常用方法:在训练集的损失函数中加入惩罚项,以降低学习到的模型的复杂度。

• 保持模型简单的一个特别的选择是使用L2惩罚的权重衰减。这会导致学习算法更新步骤中的权重衰减。

• 权重衰减功能在深度学习框架的优化器中提供。

暂退法(Dropout)

如图有1个隐藏层和5个隐藏单元的多层感知机。将暂退法应用到隐藏层,以p的概率将隐藏单元置为零时,结果可以看作是一个只包含原始神经元子集的网络。比如删除了h2h_2h2​和h5h_5h5​, 因此输出的计算不再依赖于h2h_2h2​或h5h_5h5​ ,并且它们各自的梯度在执行反向传播时也会消失。这样,输出层的计算不能过度依赖于h1,...,h5h_1, . . . , h_5h1​,...,h5​的任何一个元素。

可以将暂退法应用于每个隐藏层的输出(在激活函数之后),并且可以为每一层分别设置暂退概率:常⻅的技巧是在靠近输入层的地方设置较低的暂退概率。一般暂退法只在训练期间有效。在测试时,Dropout层仅传递数据。

dropout1, dropout2 = 0.2, 0.5
num_epochs, lr, batch_size = 10, 0.5, 256net = nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),# 在第一个全连接层之后添加一个dropout层 nn.Dropout(dropout1), nn.Linear(256, 256),nn.ReLU(),# 在第二个全连接层之后添加一个dropout层 nn.Dropout(dropout2), nn.Linear(256, 10))def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)loss = nn.CrossEntropyLoss()
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
net.apply(init_weights)
trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

前向传播和反向传播

训练神经网络时,交替使用前向传播和反向传播,利用反向传播给出的梯度来更新模型参数。

注意,反向传播重复利用前向传播中存储的中间值,以避免重复计算。带来的影响之一是我们需要保留中间值,直到反向传播完成。这也是训练比单纯的预测需要更多的内存(显存)的原因之一。此外,这些中间值的大小与网络层的数量和批量的大小大致成正比。

梯度消失和梯度爆炸

梯度爆炸(gradient exploding)问题:参数更新过大,破坏了模型的稳定收敛;

梯度消 失(gradient vanishing)问题:参数更新过小,在每次更新时几乎不会移动,导致模型无法学习。

模型评估指标可以看这个(模型验证方法、欠拟合和过拟合等)

模型验证方法

Holdout检验:将原始的样本集合随机划分成训练集和验证集两部分,常见的是70%的样本为训练集;30% 的样本为验证集。

k折交叉验证:将数据集划分为k个相等的子集,每次取一个子集作为验证集,其余k-1个作为训练集,最后将k次结果取平均,实际中,k常取10。

自助法(Bootstrap):当数据集规模比较小时再划分训练集和测试集会影响模型训练效果。对于总数为n的样本集合,进行n次有放回的随机抽样,得到大小为n的训练集。n次采样过程中,有的样本会被重复采样,有的样本没有被抽出过,将这些没有被抽出的样本作为验证集,进行模型验证,这就是自助法的验证过程。

过拟合和欠拟合

过拟合:指模型对于训练数据拟合过当,导致模型在训练集上的表现很好,但在测试集和新数据上的表现较差。

欠拟合:指模型在训练和预测时表现都不好的情况。

过拟合说明模型过于复杂,把噪声数据的特征也学习到模型中,导致模型泛化能力下降。降低“过拟合”,可以通过以下方法:

1)使用更多的训练数据让模型学习到更多更有效的特征,减小噪声的影响。

2)降低模型复杂度以避免模型拟合过多的采样噪声。

3)正则化,如L1正则化L=L0+λ∣∣w∣∣1L=L_0+\lambda||w||_1L=L0​+λ∣∣w∣∣1​,L2正则化L=L0+λ2∣∣w∣∣22L=L_0+\frac{\lambda}{2}||w||^2_2L=L0​+2λ​∣∣w∣∣22​。

4)集成学习,如基于Bagging的算法和基于Boosting的算法。

降低“过拟合”,可以通过以下方法:

1)添加新特征,当特征不足或者现有特征与样本标签的相关性不强时,模型容易出现欠拟合。

2)增加模型复杂度。

3)减小正则化系数。

多层感知机总结-PyTorch相关推荐

  1. 深度学习笔记其三:多层感知机和PYTORCH

    深度学习笔记其三:多层感知机和PYTORCH 1. 多层感知机 1.1 隐藏层 1.1.1 线性模型可能会出错 1.1.2 在网络中加入隐藏层 1.1.3 从线性到非线性 1.1.4 通用近似定理 1 ...

  2. PyTorch 笔记(14)— nn.module 实现简单感知机和多层感知机

    autograd 实现了自动微分系统,然而对深度学习来说过于底层,而本节将介绍 nn 模块,是构建于 autograd 之上的神经网络模块. 1. 简单感知机 使用 autograd 可实现深度学习模 ...

  3. 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(三)

    [深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(三) 文章目录 [深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(三) 1 权重衰减 1.1 范数 1.2 L ...

  4. 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(二)

    [深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(二) 文章目录1 代码实现 2 训练误差和泛化误差 3 模型复杂性 4 多项式回归4.1 生成数据集4.2 对模型进行训练和测试4 ...

  5. 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(一)

    [深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(一) 文章目录 1 概述 2 从线性到非线性-激活函数2.1 ReLU函数2.2 sigmoid函数2.3 tanh函数 3 注意 ...

  6. (pytorch-深度学习系列)pytorch实现多层感知机(自动定义模型)对Fashion-MNIST数据集进行分类-学习笔记

    pytorch实现多层感知机(自动定义模型)对Fashion-MNIST数据集进行分类 导入模块: import torch from torch import nn from torch.nn im ...

  7. (pytorch-深度学习系列)pytorch实现多层感知机(手动定义模型)对Fashion-MNIST数据集进行分类-学习笔记

    pytorch实现多层感知机对Fashion-MNIST数据集进行分类(手动定义模型) 多层感知机: 多层感知机在单层神经网络的基础上引入了一到多个隐藏层(hidden layer).隐藏层位于输入层 ...

  8. 动手学深度学习(PyTorch实现)(五)--多层感知机

    多层感知机 1. 基本知识 2. 激活函数 2.1 ReLU函数 2.2 Sigmoid函数 2.3 tanh函数 2.4 关于激活函数的选择 3. PyTorch实现 3.1 导入相应的包 3.2 ...

  9. 从零开始学Pytorch(三)之多层感知机的实现

    多层感知机的基本知识 我们将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念. 隐藏层 下图展示了一个多层感知机的神经网络图,它含有一个隐藏层,该层中有5 ...

最新文章

  1. 漫谈计算机体系.md
  2. pymssql 安装后只有 .disk-info_变频空调安装注意事项
  3. gedit emacs
  4. Linux学习---Day02
  5. git for windows
  6. c++ 指针的指针参数
  7. 深入理解C指针第一章小结1
  8. C#:ref和out的联系及区别。
  9. matlab7.0安装说明
  10. iterator remove_Iterator与fast-fail机制
  11. 在ubuntu 16.04中安装source insight 4.0破解版
  12. Windows7之SSH,安装OpenSSH实现SSH客户端及服务
  13. RHEL 6 配置yum源
  14. 一个分组查询的SQL 常用算法(附源码可直接执行)
  15. 自然语言处理之语料库
  16. 龙格库塔(Runge-Kutta)法求四元数微分方程
  17. ctf逆向解题——re1
  18. vue实现折叠组件-collapse
  19. 华为HCNA独家视频课程
  20. SAP中经遇到溢出如何理解

热门文章

  1. mldonkey系列之四──Mldonkey命令解释[zt]
  2. php实现指数平滑预测
  3. 绿色版eclipse
  4. final cut pro(fcpx) 导出视频的图文方法
  5. 社群裂变工具有哪些?进群宝到底有哪些实用的功能?
  6. 引流软件哪个好,脚本引流软件实战解说
  7. stm dfu_如何在Windows上修复dfu-util,STM,WinUSB,Zadig,Bootloader和其他固件刷新问题
  8. 客快物流大数据项目(一百零三):快递追踪需求介绍
  9. day-01 one-day projects
  10. wsl2 (Windows Subsystem for Linux)使用学习