动手学DL——MLP多层感知机【深度学习】【PyTorch】

文章目录

  • 4、多层感知机( MLP)
    • 4.1、多层感知机
      • 4.1.1、隐层
      • 4.1.2、激活函数 σ
    • 4.2、从零实现多层感知机
    • 4.3、简单实现多层感知机
    • 4.4、模型选择、欠拟合、过拟合
    • 4.5、权重衰退
    • 4.6、丢失法|暂退法(Dropout)
      • 4.6.1、dropout 函数实现
      • 4.6.2、简洁实现
    • 4.7、数值稳定性

4、多层感知机( MLP)

4.1、多层感知机

加入一个或多个隐藏层+激活函数来克服线性模型的限制, 使其能处理更普遍的函数关系类型,这种架构通常称为多层感知机(multilayer perceptron)。

输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算。

在这里插入图片描述

4.1.1、隐层

通用近似定理

多层感知机可以通过隐藏神经元,捕捉到输入之间复杂的相互作用, 这些神经元依赖于每个输入的值。多层感知机是通用近似器, 即使是网络只有一个隐藏层,给定足够的神经元和正确的权重, 可以对任意函数建模。

通过使用更深(而不是更广)的网络,可以更容易地逼近许多函数。

4.1.2、激活函数 σ

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活,换句话说,激活函数的目的是引入非线性变化。

常见激活函数

ReLU 是绝大多数情况的选择。原因是它计算简单,不用跑指数运算,CPU跑指数运算是很费时间的,GPU会好一些。

1)ReLU

R e L U ( x ) = m a x ( x , 0 ) ReLU(x) = max(x,0) ReLU(x)=max(x,0)

使用 ReLU 的原因是,它求导表现得特别好:要么让参数消失,要么让参数通过。 这使得优化表现得更好,并且ReLU减轻了困扰以往神经网络的梯度消失问题目前还不理解,为什么这样优化表现更好?

2)Sigmoid

s i g m o i d ( x ) = 1 1 + e − x sigmoid(x) = \frac{1}{1+e^{-x}} sigmoid(x)=1+ex1

它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值。

3)tanh

t a n h ( x ) = 1 − e − 2 x 1 + e − 2 x tanh(x) = \frac{1-e^{-2x}}{1+e^{-2x}} tanh(x)=1+e2x1e2x

将其输入压缩转换到区间(-1, 1)上。

为什么要引入非线性变换?

非线性变换比线性变换有更强的表达能力。可逼近任意复杂函数,更加贴合真实世界问题,现实世界中单调、线性是极少存在的。

例如,如果我们试图预测一个人是否会偿还贷款。 我们可以认为,在其他条件不变的情况下, 收入较高的申请人比收入较低的申请人更有可能偿还贷款。 但是,虽然收入与还款概率存在单调性,但它们不是线性相关的。 收入从0增加到5万,可能比从100万增加到105万带来更大的还款可能性。 处理这一问题的一种方法是对我们的数据进行预处理, 使线性变得更合理,如使用收入的对数作为我们的特征。(该例来自 DIVE INTO DEEP LEARNING)

softmax 函数与隐层激活函数的区别?

softmax 函数主要用于输出层,而不是隐藏层。隐藏层的激活函数通常是为了引入非线性,而 softmax 函数则是为了将得分映射为概率,用于多分类问题的输出。

什么是层数塌陷?

梯度消失。

4.2、从零实现多层感知机

(损失函数、优化算法 来自 torch)

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
#生成了一个服从标准正态分布(均值为0,方差为1)的随机张量 大小(num_inputs, num_hiddens),作为 w 初始值。
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
# 大小为(num_hiddens,)的零张量 ,作为 b 的初始值 
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]

权重为什么要乘 0.01?

乘以0.01的目的是将初始权重缩放到一个较小的范围,以便更好地初始化网络。

激活函数

def relu(X):# 创建了一个与输入张量X具有相同形状的全零张量aa = torch.zeros_like(X)return torch.max(X, a)

定义模型

def net(X):# -1 表示该维度将根据张量的大小自动计算, 如:784, reshape(-1,28) 会得到28*28X = X.reshape((-1, num_inputs))H = relu(X@W1 + b1)  # 这里“@”代表矩阵乘法return (H@W2 + b2)

损失函数

# reduction='none':表示不进行降维,张量的形状通常与输入的标签张量的形状相同。
loss = nn.CrossEntropyLoss(reduction='none')

训练 & 优化算法

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)

4.3、简单实现多层感知机

import torch
from torch import nn
from d2l import torch as d2l
net = 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(reduction='none')
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)

4.4、模型选择、欠拟合、过拟合

模型选择

DL 的核心是,设计一个大的模型,控制它的容量,尽可能地降低泛化误差。

泛化误差(test_loss):模型在新数据上的误差。

训练误差(train_loss):模型在训练数据上的误差,反映了模型在训练数据上的拟合程度。

模型训练过程中用到的损失是 train_loss 。

测试集:只用一次的数据集【如竞赛提交后才进行测试的无法用于调超参数的不可知数据】。

验证集:用来评估模型好坏的数据集,根据结果调整超参数。

小数据集上做验证,通常使用K-则交叉验证,常用k=5或10。
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=42)这种分割之后,哪里涉及到验证损失?绘制出来的 test_loss 算测试损失还是验证损失?

沐神提到过,数据集分割中的X_test,y_text 是当作测试集实际上是验证集(val),不代表模型在新数据上真实泛化能力。
对上方红字,我的理解:数据集分割的test,在使用时确实是当测试集对待的,对代码来说他就是测试集,但是在代码之外,往往会根据这个结果人为地去调整下学习率、隐层节点之类的超参数,那么就更加贴合验证集的定义,是实际中的验证集
所以翻阅书籍看到 test 就应该啊理解为测试集,不要钻牛角尖说事实上我压根就没有测试集,到我手上了的都成为验证集了,因为我后续会调参,薛定谔的猫。所以书籍教程上谈 test为测试集,没有任何问题(一直纠结很久,所以记录一下)。

超参数:训练前预定义好的,训练中不会变,(lr、epoch、batchsize、正则化参数、隐层节点数)。

参数:权重w、偏移量b之类的。

过拟合&欠拟合

  • 低容量配简单数据时,高容量模型配复杂数据时,拟合正常。

  • 高容量模型数据少,容易过拟合;低容量模型数据复杂,易欠拟合。

    模型容量

    拟合各种函数的能力,高容量的模型可以记住所有训练数据。

    如何估计模型容量?

    • 参数个数
    • 参数值的选择范围

    VC维(Wapnik-Chervonenkis dimension)是统计学提供的量化模型容量的方法,提供一个为什么一个模型好的理论依据。在DL中使用VC维很困难。

    (图片来自 《DIVE INTO DEEP LEARNING》)

    数据复杂度

    样本数、没样本元素数、时空结构、多样性。

    更多的,模型容量和数据复杂度是直观感受,不断积累调参得来的感受。

4.5、权重衰退

权重衰减是最广泛使用的正则化的技术之一, 它通常也被称为 L 2 正则化 L_2正则化 L2正则化

正则化是处理过拟合常用方法,在训练集损失函数中加入惩罚项,以降低模型复杂度。保持模型简单的一个特别的选择是使用 L 2 惩罚 L_2惩罚 L2惩罚的权重衰减。

常见的正则化方法:

  1. L1 正则化(L1 Regularization):在损失函数中添加参数的绝对值之和,即 L1 范数。这将导致一些参数变为零,从而实现特征选择的效果,使得模型更稀疏。
  2. L2 正则化(L2 Regularization):在损失函数中添加参数的平方和的一半,即 L2 范数。这会使模型的参数更加平滑,防止参数过大,从而减轻过拟合。
  3. Elastic Net 正则化:结合了 L1 和 L2 正则化,同时对参数施加 L1 和 L2 惩罚项。
  4. Dropout 正则化:在训练过程中,随机地将一些神经元的输出设置为零,以降低神经网络的复杂性。
  5. 数据增强(Data Augmentation):通过对训练数据进行一系列随机变换(如翻转、旋转、缩放等),增加数据样本,从而提高模型的泛化能力。

参数更新法则

计算梯度

∂ ∂ w ( L ( w , b ) + λ 2 ∣ ∣ w ∣ ∣ 2 ) = ∂ L ( w , b ) ∂ w + λ w \frac{∂}{∂w}(L(w,b) + \frac{λ}{2}||w||^2) = \frac{∂L(w,b)}{∂w} + \lambda w w(L(w,b)+2λ∣∣w2)=wL(w,b)+λw

更新参数(时间t)

w t + 1 = ( 1 − η λ ) w t − η ∂ L ( w , b ) ∂ w wt+1 =(1-ηλ)wt - η\frac{∂L(w,b)}{∂w} wt+1=(1ηλ)wtηwL(w,b)

通常 η λ < 1 η\lambda < 1 ηλ<1,深度学习中这个就叫做权重衰减。

4.6、丢失法|暂退法(Dropout)

Dropout 是一种常用的正则化技术,正则技术就是用于防止神经网络过拟合。

丢弃法将一些输出项随机置0来控制模型复杂度,常作用在多层感知机的隐藏层输出上,丢弃概率是控制模型复杂度的超参数。

常用 dropout rate = 0.5 or 0.9 or 0.1

无偏差的加入噪音

x x x加入噪音得到 x ′ x' x,我们希望

E [ x ′ ] = x E[x'] = x E[x]=x

丢弃法对每个元素进行如下扰动

x i ′ = { 0 with probability p x i 1 − p otherise x_i' = \begin{cases} 0& \text{with probability p} \\ \frac{x_i}{1-p} &\text{otherise} \end{cases} xi={01pxiwith probability potherise

怎么能看出"加噪音"这个动作,这不是"丢弃"动作吗?

理论上 dropout 是在做一个隐层之间加噪音的操作,实际上是通过上述 x x x x ′ x' x实现的。

丢弃法的实际使用

通常将丢弃法作用于隐层的输出上。

[hidden layers]

​ ↓

[dropout layer]

​ ↓

[output layer]

h = σ ( W 1 x + b 1 ) h = σ(W_1x + b_1) h=σ(W1x+b1)

h ′ = d r o p o u t ( h ) h' = dropout(h) h=dropout(h)

o = W 2 h ′ + b 2 o = W_2h' + b_2 o=W2h+b2

y = s o f t m a x ( o ) y = softmax(o) y=softmax(o)

在这里插入图片描述
(图片来自 《DIVE INTO DEEP LEARNING》)

4.6.1、dropout 函数实现

import torch 
from torch import nn
from d2l import torch as d2ldef dropout_layer(X,dropout):#dropout只有在合理范围内,断言允许继续执行assert 0 <= dropout <=  1# dropout =1 分母无意义if dropout ==1:return torch.zeros_like(X)if dropout == 0:return Xmask = (torch.rand(X.shape) > dropout ).float()return mask * X / (1.0 - dropout)

4.6.2、简洁实现

在每个全连接层之后添加一个Dropout

net = 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)net.apply(init_weights);

训练和测试

trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

4.7、数值稳定性

参数初始化重要性:影响梯度和参数本身的稳定性

梯度计算的是矩阵与梯度向量的乘积,最初矩阵可能具有各种各样的特征值,他们的乘积可能非常大也可能非常小。

不稳定梯度带来的风险不止在于数值表示; 不稳定梯度也威胁到我们优化算法的稳定性。 梯度爆炸,参数更新过大,破坏模型稳定收敛;梯度消失,参数更新过小,模型无法学习。

当网络有很多层时,sigmoid函数的输入很大或是很小时,它的梯度都会消失,激活函数会选择更稳定的ReLU系列函数。

参数对称性

神经网络设计中的另一个问题是其参数化所固有的对称性。 假设我们有一个简单的多层感知机,它有一个隐藏层和两个隐藏单元。 在这种情况下,我们可以对第一层的权重 W ( 1 ) W^{(1)} W(1)进行重排列, 并且同样对输出层的权重进行重排列,可以获得相同的函数。 第一个隐藏单元与第二个隐藏单元没有什么特别的区别。 换句话说,我们在每一层的隐藏单元之间具有排列对称性。

这种对称性意味着在参数化的角度上,我们有多个等效的参数组合可以表示相同的函数。在神经网络训练过程中,可能会出现参数收敛到其中一个等效组合上,而忽略了其他等效组合。这可能导致训练过程不稳定或收敛较慢。

小批量随机梯度下降不会打破这种对称性,但暂退法正则化可以。

如何让训练更加稳定?

让梯度值在一个合理的范围。

  • 将乘法变加法【ResNet,LSTM】

  • 归一化【梯度归一化,梯度裁剪】

  • 合理的权重初始和激活函数

  • 让每层的方差是一个常数

    • 将每层的输出梯度看作随机变量
    • 让他们的均值和方差都保持一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/38200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据--难点--地图的制作

地图一直是亮点也是难点&#xff0c;刚刚进公司的时候也很难懂~~做出来的也很难看 纯CSS3使用vw和vh视口单位实现h5页面自适应&#xff0c;gulp自动监听sass改动并保存到css中 当修改了sass里面的代码后&#xff0c;gulp会自动监听修改内容并同名保存到css文件夹中&#xff0…

C#字符串占位符替换

using System;namespace myprog {class test{static void Main(string[] args){string str1 string.Format("{0}今年{1}岁&#xff0c;身高{2}cm&#xff0c;月收入{3}元&#xff1b;", "小李", 23, 177, 5000);Console.WriteLine(str1);Console.ReadKey(…

02-C++数据类型-高级

数据类型-高级 4、复合类型 4.4、结构简介 struct inflatable {char name[20];float vol;double price; };inflatable vincent; //C struct inflatable goose; //C例子 // structur.cpp -- a simple structure #include <iostream> struct inflatable // structu…

B057-spring增强 依赖注入 AOP 代理模式 创建Bean

目录 AOP概念代理模式引出AOP实现方式xml方式实现注解方式实现 AOP 概念 事务管理&#xff1a;比如可以抽取try catch的重复代码 日志监控&#xff1a;比如业务逻辑前后打印关于当前订单数量的日志&#xff0c;了解业务做了什么 性能监控&#xff1a;比如业务前后打印时间&…

浪潮信息赵帅:多元算力时代 开源开放的OpenBMC成为服务器管理优先解

“多元算力时代下&#xff0c;大规模的异构服务器设备面临多种处理器架构、多种设备协议、不同管理芯片兼容的系统化设计挑战&#xff0c;管理固件也迎来新的变革。开源开放的OpenBMC&#xff0c;以创新的分层解耦软件架构&#xff0c;兼容不同处理器架构、算力平台和管理芯片&…

人流目标跟踪pyqt界面_v5_deepsort

直接上效果图 代码仓库和视频演示b站视频006期&#xff1a; 到此一游7758258的个人空间-到此一游7758258个人主页-哔哩哔哩视频 代码展示&#xff1a; YOLOv5 DeepSORT介绍 YOLOv5 DeepSORT是一个结合了YOLOv5和DeepSORT算法的目标检测与多目标跟踪系统。让我为您详细解释一…

【字典学习+稀疏编码Sparse Encoding】简单介绍与sklearn的实现方式

文章目录 1、字典学习与稀疏编码2、sklearn的实现3、示例 1、字典学习与稀疏编码 简单来说&#xff0c;稀疏编码就是把输入向量&#xff08;信号&#xff09;/ 矩阵&#xff08;图像&#xff09;表示为稀疏的系数向量和一组超完备基向量&#xff08;字典&#xff09;的线性组合…

ASP.NET WEB API通过SugarSql连接MySQL数据库

注意&#xff1a;VS2022企业版可以&#xff0c;社区版可能存在问题。实体名称和字段和数据库中的要一致。 1、创建项目&#xff0c;安装SqlSugarCore、Pomelo.EntityFrameworkCore.MySql插件 2、文件结构 2、appsettings.json { “Logging”: { “LogLevel”: { “Default”: …

搭建WebDAV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,我们在群辉中开启WebDav服务,结合cpolar内网工具生成的公网地址,通过移动客户端ES文件…

docker通用镜像方法,程序更新时不用重新构建镜像

docker通用镜像方法&#xff0c;程序更新时不用重新构建镜像。更新可执行文件后&#xff0c;重新启动容器就可运行。 功能 1、在demo目录下添加脚本文件start.sh&#xff0c;里面执行demo.jar文件。 2、将demo目录映射到镜像下的 /workspace目录。 3、Dockerfile文件中默认…

台湾shopee:虾皮电商平台选品方法与市场机遇

台湾Shopee虾皮电商平台为台湾本土卖家和消费者提供了一个线上交易平台。对于想要在台湾市场做虾皮电商的卖家来说&#xff0c;选择合适的产品是非常重要的。本文介绍一些做虾皮电商的选品方法和策略。 首先&#xff0c;了解市场需求是选品的基础。在进入台湾Shopee市场之前&a…

【Spring专题】Spring之Bean的生命周期源码解析——阶段二(IOC之实例化)

目录 前言阅读准备阅读指引阅读建议 课程内容一、SpringIOC之实例化1.1 简单回顾1.2 概念回顾1.3 核心方法讲解 二、方法讲解2.1 AbstractBeanFactory#getMergedLocalBeanDefinition&#xff1a;合并BeanDefinition2.2 AbstractAutowireCapableBeanFactory#createBean&#xff…

安达发APS|APS排产软件之计划甘特图

在当今全球化和竞争激烈的市场环境下&#xff0c;制造业企业面临着巨大的压力&#xff0c;如何在保证产品质量、降低成本以及满足客户需求的同时&#xff0c;提高生产效率和竞争力成为企业需要迫切解决的问题。在这个背景下&#xff0c;生产计划的制定和执行显得尤为重要。然而…

2023年京东按摩仪行业数据分析(京东销售数据分析)

近年来&#xff0c;小家电行业凭借功能与颜值&#xff0c;取代黑电和白电&#xff0c;成为家电市场的主要增长点。在这一市场背景下&#xff0c;颜值更高、功能更丰富、品种更齐全的各类按摩仪&#xff0c;借助新消费和电子商务的风潮&#xff0c;陆续被推上市场。今年&#xf…

【Cocos Creator 项目实战 】消灭星星加强版(附带完整源码工程)

本文乃Siliphen原创&#xff0c;转载请注明出处 目录 概述 游戏整体流程 游戏框架设计 单一职责的类 主要流程控制类 核心玩法模块 UI&#xff1a; 游戏世界&#xff1a; 本文项目的代码组织结构 作者项目实践总结 场景只有一个入口脚本 尽量少在节点上挂载脚本 构…

从零构建深度学习推理框架-8 卷积算子实现

其实这一次课还蛮好理解的&#xff1a; 首先将kernel展平&#xff1a; for (uint32_t g 0; g < groups; g) {std::vector<arma::fmat> kernel_matrix_arr(kernel_count_group);arma::fmat kernel_matrix_c(1, row_len * input_c_group);for (uint32_t k 0; k < k…

macOS(m芯片)连接服务器及其进行文件传输的各种方式的详解

说明&#xff1a;使用了macOS后发现&#xff0c;win系统能使用的xshell、xftp等连接服务器及其文件传输等软件均不能使用了&#xff0c;没有兼容的版本。所以我们刚切换到mac系统该如何去适应呢。 一、连接远程服务器 macOS中前文也说道我们使用的是iterm2进行终端控制的&…

基于深度信念神经网络的矿石产量预测,基于DBN的矿石产量预测,DBN的详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN的矿石产量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN算法进行矿石产量预测 DB…

流量日志分析--实操

[鹤城杯 2021]流量分析 <--第一道流量分析不难,主要就是布尔盲注的流量包分析,直接查看http请求包即可我们可以通过观察看到注入成功的响应长度不同,这里成功的为978字节,失败的994字节.不要问为什么.其实也可以直接判断.978的流量比994的少了非常多 显然就是成功的(因为这里…

Docker中部署redis

1.部署redis要求 2.部署教程 连接容器中的redis redis部署完毕