多层感知机总结-PyTorch
动手学深度学习-多重感知机笔记
- 多层感知机
- 多层感知机的从零开始实现
- 多层感知机的简洁实现
- 范数与权重衰减(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)=n1i=1∑nl(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∑∂wl(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相关推荐
- 深度学习笔记其三:多层感知机和PYTORCH
深度学习笔记其三:多层感知机和PYTORCH 1. 多层感知机 1.1 隐藏层 1.1.1 线性模型可能会出错 1.1.2 在网络中加入隐藏层 1.1.3 从线性到非线性 1.1.4 通用近似定理 1 ...
- PyTorch 笔记(14)— nn.module 实现简单感知机和多层感知机
autograd 实现了自动微分系统,然而对深度学习来说过于底层,而本节将介绍 nn 模块,是构建于 autograd 之上的神经网络模块. 1. 简单感知机 使用 autograd 可实现深度学习模 ...
- 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(三)
[深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(三) 文章目录 [深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(三) 1 权重衰减 1.1 范数 1.2 L ...
- 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(二)
[深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(二) 文章目录1 代码实现 2 训练误差和泛化误差 3 模型复杂性 4 多项式回归4.1 生成数据集4.2 对模型进行训练和测试4 ...
- 【深度学习】基于Pytorch多层感知机的高级API实现和注意力机制(一)
[深度学习]基于Pytorch多层感知机的高级API实现和注意力机制(一) 文章目录 1 概述 2 从线性到非线性-激活函数2.1 ReLU函数2.2 sigmoid函数2.3 tanh函数 3 注意 ...
- (pytorch-深度学习系列)pytorch实现多层感知机(自动定义模型)对Fashion-MNIST数据集进行分类-学习笔记
pytorch实现多层感知机(自动定义模型)对Fashion-MNIST数据集进行分类 导入模块: import torch from torch import nn from torch.nn im ...
- (pytorch-深度学习系列)pytorch实现多层感知机(手动定义模型)对Fashion-MNIST数据集进行分类-学习笔记
pytorch实现多层感知机对Fashion-MNIST数据集进行分类(手动定义模型) 多层感知机: 多层感知机在单层神经网络的基础上引入了一到多个隐藏层(hidden layer).隐藏层位于输入层 ...
- 动手学深度学习(PyTorch实现)(五)--多层感知机
多层感知机 1. 基本知识 2. 激活函数 2.1 ReLU函数 2.2 Sigmoid函数 2.3 tanh函数 2.4 关于激活函数的选择 3. PyTorch实现 3.1 导入相应的包 3.2 ...
- 从零开始学Pytorch(三)之多层感知机的实现
多层感知机的基本知识 我们将以多层感知机(multilayer perceptron,MLP)为例,介绍多层神经网络的概念. 隐藏层 下图展示了一个多层感知机的神经网络图,它含有一个隐藏层,该层中有5 ...
最新文章
- 漫谈计算机体系.md
- pymssql 安装后只有 .disk-info_变频空调安装注意事项
- gedit emacs
- Linux学习---Day02
- git for windows
- c++ 指针的指针参数
- 深入理解C指针第一章小结1
- C#:ref和out的联系及区别。
- matlab7.0安装说明
- iterator remove_Iterator与fast-fail机制
- 在ubuntu 16.04中安装source insight 4.0破解版
- Windows7之SSH,安装OpenSSH实现SSH客户端及服务
- RHEL 6 配置yum源
- 一个分组查询的SQL 常用算法(附源码可直接执行)
- 自然语言处理之语料库
- 龙格库塔(Runge-Kutta)法求四元数微分方程
- ctf逆向解题——re1
- vue实现折叠组件-collapse
- 华为HCNA独家视频课程
- SAP中经遇到溢出如何理解
热门文章
- mldonkey系列之四──Mldonkey命令解释[zt]
- php实现指数平滑预测
- 绿色版eclipse
- final cut pro(fcpx) 导出视频的图文方法
- 社群裂变工具有哪些?进群宝到底有哪些实用的功能?
- 引流软件哪个好,脚本引流软件实战解说
- stm dfu_如何在Windows上修复dfu-util,STM,WinUSB,Zadig,Bootloader和其他固件刷新问题
- 客快物流大数据项目(一百零三):快递追踪需求介绍
- day-01 one-day projects
- wsl2 (Windows Subsystem for Linux)使用学习