动手学深度学习——多层感知机(原理解释+代码详解)

news2024/11/29 6:27:39

目录

  • 一、多层感知机
    • 1. 隐藏层
      • 1.1 线性模型可能会出错
      • 1.2 在网络中加入隐藏层
      • 1.3 从线性到非线性
      • 1.4 通用近似定理
    • 2. 激活函数
      • 2.1 ReLU函数
      • 2.2 sigmoid函数
      • 2.3 tanh函数
    • 3. 小结
  • 二、多层感知机的从零开始实现
    • 2.1 初始化模型参数
    • 2.2 激活函数
    • 2.3 模型
    • 2.4 损失函数
    • 2.5 训练
  • 三、多层感知机的简洁实现

一、多层感知机

1. 隐藏层

1.1 线性模型可能会出错

  1. 线性意味着单调假设: 特征的增大导致模型输出的增大(权重为正), 或者导致模型输出的减小(权重为负)。
  2. 数据通过一种表示,这种表示会考虑到特征之间的相关交互作用。

1.2 在网络中加入隐藏层

  1. 在网络中加入一个或多个隐藏层来克服线性模型的限制, 使其能处理更普遍的函数关系类型。
  2. 将许多全连接层堆叠在一起, 每一层都输出到上面的层,直到生成最后的输出。 前L-1层看作表示,把最后一层看作线性预测器。这种架构通常称为多层感知机(multilayer perceptron),通常缩写为MLP。在这里插入图片描述
  3. 这个多层感知机有4个输入,3个输出,其隐藏层包含5个隐藏单元。输入层不涉及任何计算,因此使用此网络产生输出只需要实现隐藏层和输出层的计算。 因此,这个多层感知机中的层数为2。

1.3 从线性到非线性

  1. 对于h个隐藏单元的单隐藏层多层感知机, 用H表示隐藏层的输出, 称为隐藏表示。
  2. W(1)为隐藏层权重,W(2)为输出层权重,b(1)为隐藏层偏置,b(2)为输出层偏置。
    在这里插入图片描述
  3. 此时模型依然是仿射函数,需要在仿射变换之后对每个隐藏单元应用非线性的激活函数,之后多层感知机不会退化成线性模型。在这里插入图片描述

1.4 通用近似定理

  1. 多层感知机可以通过隐藏神经元,捕捉到输入之间复杂的相互作用, 这些神经元依赖于每个输入的值,可以很容易地设计隐藏节点来执行任意计算。
  2. 可以使用更深的网络来逼近许多函数。

2. 激活函数

  1. 激活函数通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。
  2. 大多数激活函数都是非线性的,如ReLU函数,sigmoid函数和tanh函数。

2.1 ReLU函数

  1. ReLU函数是修正线性单元,提供了一种非常简单的非线性变换,它实现简单,同时在各种预测任务中表现良好。
  2. ReLU函数通过将相应的活性值设为0,仅保留正元素并丢弃所有负元素。在这里插入图片描述
  • detach():返回一个新的tensor,并且这个tensor是从当前的计算图中分离出来的。但是返回的tensor和原来的tensor是共享内存空间的。
  • figsize:Matplotlib库中的一个函数,用于设置图形的尺寸大小。
    figsize(width, height) :其中,width和height分别表示图像的宽度和高度,单位为英寸(inch)。
  • requires_grad =True:输出张量需要梯度。
%matplotlib inline
import torch
from d2l import torch as d2l

# 生成一个从-8.0到7.9的列表,以0.1为跳跃点
# 需要梯度
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)

# 通过relu函数激活
y = torch.relu(x)
d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize=(5, 2.5))

在这里插入图片描述
ReLU函数的导数

  • torch.ones_like():返回一个与输入张量input形状相同的张量,所有元素都设置为1。
  • retain_graph=True:第一次计算完梯度后,计算图会被保留下来,再次计算梯度时,就可以重复使用这个计算图,从而避免重复构建计算图,提高计算效率。
y.backward(torch.ones_like(x), retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of relu', figsize=(5, 2.5))

在这里插入图片描述

  1. 当输入为负时,ReLU函数的导数为0,而当输入为正时,ReLU函数的导数为1(输入值精确等于0时,ReLU函数不可导,但输入不会为0,一般用左边值替代)。

2.2 sigmoid函数

  1. sigmoid函数将输入变换为区间(0, 1)上的输出,也叫挤压函数,它是一个平滑的、可微的阈值单元近似。。在这里插入图片描述

  2. sigmoid在隐藏层中已经较少使用, 它在大部分时候被更简单、更容易训练的ReLU所取代。

y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize=(5, 2.5))

在这里插入图片描述
sigmoid函数的导数

# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of sigmoid', figsize=(5, 2.5))

在这里插入图片描述

3.当输入为0时,sigmoid函数的导数达到最大值0.25; 而输入在任一方向上越远离0点时,导数越接近0。

2.3 tanh函数

  1. tanh(双曲正切)函数也能将其输入压缩转换到区间(-1, 1)上。在这里插入图片描述
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize=(5, 2.5))

在这里插入图片描述
tanh函数的导数

# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of tanh', figsize=(5, 2.5))

在这里插入图片描述

  1. 当输入接近0时,tanh函数的导数接近最大值1。 输入在任一方向上越远离0点,导数越接近0。

3. 小结

  1. 多层感知机在输出层和输入层之间增加一个或多个全连接隐藏层,并通过激活函数转换隐藏层的输出。
  2. 常用的激活函数包括ReLU函数、sigmoid函数和tanh函数。

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

使用Fashion-MNIST图像分类数据集 。

import torch
from torch import nn
from d2l import torch as d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

2.1 初始化模型参数

  1. Fashion-MNIST中的每个图像由28×28=784个灰度像素值组成, 所有图像共分为10个类别。
  2. 将每个图像视为具有784个输入特征 和10个类的简单分类数据集。
  3. 实现一个具有单隐藏层的多层感知机, 它包含256个隐藏单元。
  • torch.zeros()函数:返回一个形状为为size,类型为torch.dtype,里面的每一个值都是0的tensor。
  • torch.randn:用来生成随机数字的tensor,这些随机数字满足标准正态(0~1)。
num_inputs, num_outputs, num_hiddens = 784, 10, 256

# 定义参数w1,w2,b1,b2
# w1,w2为满足标准正态分布的随机数字,b1,b2为0
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]

2.2 激活函数

自己实现ReLU激活函数。

def relu(X):
    a = torch.zeros_like(X)
    return torch.max(X, a)

2.3 模型

使用reshape将每个二维图像转换为一个长度为num_inputs的向量。

def net(X):
    X = X.reshape((-1, num_inputs))
    H = relu(X@W1 + b1)  # 这里“@”代表矩阵乘法
    return (H@W2 + b2)

2.4 损失函数

  1. 直接使用高级API中的内置函数来计算softmax和交叉熵损失。
  • reduction = none:表示直接返回n分样本的loss。
loss = nn.CrossEntropyLoss(reduction='none')

2.5 训练

直接调用d2l包的train_ch3函数,详细见之前的线性回归。

# 迭代轮数为10,学习率为0.1
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)

在这里插入图片描述

三、多层感知机的简洁实现

  1. 通过高级API更简洁地实现多层感知机。
# 导入d2l包
import torch
from torch import nn
from d2l import torch as d2l
  1. 添加2个全连接层, 第一层是隐藏层,它包含256个隐藏单元,并使用了ReLU激活函数,第二层是输出层。
  • nn.Sequential():一个序列容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。把多个模块封装成一个模块。
  • nn.Flatten():将连续的维度范围展平为张量。 经常在nn.Sequential()中出现,一般写在某个神经网络模型之后,用于对神经网络模型的输出进行处理,得到tensor类型的数据。
  • nn.Linear():定义一个神经网络的线性层:
    torch.nn.Linear(in_features, # 输入的神经元个数
    out_features, # 输出神经元个数
    bias=True # 是否包含偏置
    )
  • torch.nn.init.normal_(tensor, mean=0.0, std=1.0):tensor为一个n维torch.Tensor,mean为正态分布的平均值,std为正态分布的标准差。
  • init_weights:初始化网络的权重。它还将神经网络的权重设置为非零值,这对神经网络来说是有帮助的,因为神经网络往往会陷入局部最小值,所以给它们许多不同的起始值是个好主意。
  • apply(fn):该方法会将fn递归的应用于模块的每一个子模块(.children()的结果)及其自身。
net = nn.Sequential(nn.Flatten(), # 展平为张量
					
					# 定义784输入神经单元,256个输出神经单元的线性层
                    nn.Linear(784, 256), 
                    
					# ReLU激活函数
                    nn.ReLU(),

					# 定义256输入神经单元,10个输出神经单元的线性层
                    nn.Linear(256, 10))

# 初始化网络权重
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01) #初始化权重:标准差为0.01

# 每层都循环一下,最后对整个Sequential也进行操作,递归调用
net.apply(init_weights);

# 批量大小:256,学习率:10,迭代轮数:10
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)

在这里插入图片描述

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

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

相关文章

【数据结构刷题】消失的数字和轮转数组

目录 一.消失的数字 方法一:异或全部元素 方法二:利用等差数列求和-该数组全部元素之和。 二.轮转数组 题型1:实现一个函数,可以左旋字符串中的k个字符。 写法1:暴力求解 根据该题写出右旋转 写法2:三步旋转法(左逆序,右逆序,整体…

2023年7月字节前端青训营入营题目记录(大题)

前言&#xff1a; 不一定是完整的题目内容&#xff0c;但意思差不多是一个意思 1.实现一个url解析成对象的函数&#xff1a; function ParseParams(url: string): Record<string, any> {const paramsstr url.split("?")[1];const paramsArr paramsstr.spl…

IDEA中把导航栏的字体放大

IDEA中如何把导航栏的字体放大&#xff1f; 选择File--Settings--Appearance&#xff0c;找到下面的size,选择自己想要的字体大小后点击 OK 即可。 字体大了果然看的更舒服了~写代码都有动力了哈哈哈哈 服了~

MySQL基本语句

目录 一、MySQL数据库管理 查看数据库信息 查看数据库中的表信息use 数据库名 #切换到书库中 显示数据表的结构&#xff08;字段&#xff09; 二、SQL语句 1.创建新的数据库 2.创建新的表 3.增加&#xff08;insert&#xff09; 4.删除 4.1清空表 4.2删除表 5.修改…

SpringMVC的数据响应-直接回写json字符串

一般我们操作对象&#xff0c;将对象转变为json 这时导入json 转换工具的包 包1 包2-json数据绑定 包3 返回的就是json字符串你直接返回就行了 返回一个json格式的字符串 直接回写就加这个res.... 内部字符串要进行相应的转意 能够看到json字符串 能不能你封装对象&#xff0c…

jenkins+python+pytest+selenium 自动化执行脚本并发送报告

目录 安装jenkins jenkins 安装网址&#xff1a; 傻瓜式安装 配置环境 键path 或者随便填 构建后操作 在jenkins上展示html的报告&#xff0c;需要添加一个HTML Publisher plugin插件 查看报告显示丢失了css样式 加载css样式丢失解决&#xff1a;https://www.cnblogs.com/…

如何使用Dom4J解析XML文档

文章目录 XML解析的方式使用Dom4J解析XML文档Dom4J结合XPath解析XML 最近在手写MyBatis的源码&#xff0c;在写到XMLConfigBuilder的时候&#xff0c;其中要解析xml文件构建Configuration。在MyBatis的早期版本中使用了DOM4J来解析配置文件和映射文件。但是从3.x版本开始,MyBat…

数据结构——绪论

基本概念 数据&#xff1a;数据是信息的载体&#xff0c;对客观事物的字符表示。 数据元素&#xff1a;数据的基本单位&#xff0c;通常作为一个整体进行考虑和处理。 数据项&#xff1a; 一个数据元素由多个数据项组成&#xff0c;数据项是数据元素不可分割的最小单位。 数据…

流程图如何制作?几个流程图实用制作方法教给你

流程图如何制作&#xff1f;流程图是一种重要的图表类型&#xff0c;通常用于描绘系统、流程或程序的步骤和关系。它们在各种领域都有广泛的应用&#xff0c;包括工程、科学、商业和教育等。本文将介绍一些制作流程图的实用方法&#xff0c;以及一些快速、易于使用的工具。 制作…

k8s之Pod容器资源限制

目录 一、Pod 容器的资源限制二、CPU 资源单位三、内存资源单位四、为本地临时性存储设置请求和限制五、总结 一、Pod 容器的资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为…

MySQL索引事务与存储引擎

MySQL索引事务与存储引擎 索引概念索引作用副作用索引场景创建索引原则索引分类 事务概念:特性事务隔离级别 MYSQL存储引擎概念常用的存储引擎MyISAMInnoDB 索引 概念 是一个排序的列表&#xff0c;存储着索引值和这个值所对应的物理地址无须对整个表进行扫描&#xff0c;通过…

Vant安装及必坑

vant官网地址 Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. 1.通过npm安装&#xff1a; 注意vue2和vue3不同&#xff0c;版本过高会报错 vue2 npm i vantlatest-v2或者npm i vant -Svue3 npm i vant或者npm i vantnext -S 备注&#xff1a…

为什么信创国产化替代 必备 “开放式ETL产品“(下篇)

信创国产化通俗来讲&#xff0c;就是在核心芯片、基础硬件、操作系统、中间件、数据服务器等领域实现信创产业的国产替代。ETL技术 属于基础软件类中间件技术。发展自己研制的安全可靠的能够保证国家信息安全的设备&#xff0c;随着信息安全问题日益突出&#xff0c;信息安全已…

小程序 点击view内部元素 不传参

点击 内部图片和文字 type 得到的是空 无法传递参数 解决办法: 用 currentTarget 代替 target

【LangChain】数据连接(Data connection)

概要 许多LLM申请需要特定于用户的数据&#xff0c;这些数据不属于模型训练集的一部分。 LangChain 为您提供了通过以下方式加载、转换、存储和查询数据的构建块&#xff1a; Document loaders &#xff1a; 从许多不同来源加载文档Document transformers&#xff1a;拆分文档…

怎么把文档翻译成英文?这几款文档翻译工具都能实现

听说你正在寻找免费的文档翻译软件&#xff0c;我来给你一些建议吧&#xff01;翻译软件的确是个很有用的工具&#xff0c;能够帮助我们快速翻译各种语言的文档。而且现在有很多免费的选择&#xff0c;真是再好不过了&#xff01;但是随着市面上文档翻译软件数量的增多&#xf…

车载测试:车联网功能组件及安全测试策略

目录 一、车联网功能组件 车域网 IVI TBOX ECU TSP APP 通信及密码特殊指标 车端特殊指标 APP特殊指标 测试用例 一、车联网功能组件 车联网是以汽车智能化、网联化为基础&#xff0c;广泛应用新一代通信技术、人工智能技术构建起的新型基础设施。在整体架构上&…

单据小票打印模板自定义设计,手机收银软件APP搭配蓝牙便携打印机,移动便携打印零售单单据小票

单据小票打印模板自定义设计&#xff0c;手机收银软件APP搭配蓝牙便携打印机&#xff0c;移动便携打印零售单单据小票&#xff0c;轻松实现仓库条码管理&#xff0c;扫码入库出库盘点_哔哩哔哩_bilibili单据小票打印模板自定义设计&#xff0c;手机收银软件APP搭配蓝牙便携打印…

突破平凡:创造独特而吸引人的登陆页UI设计灵感

今天&#xff0c;我们从移动APP产品经理或者UI设计师的角度再来聊一聊APP登录设计方式和如何去设计这些有意思的APP登录模块。 1、熟悉目前常见的手机APP登陆方式 ① 账号登陆&#xff08;手机、邮箱&#xff09; ② 第三方登陆&#xff08;微信&#xff0c;QQ&#xff0c;微博…

Java编程-IDEA中Java的main方法、sout快捷键设置

目的 我打出psvm这四个字母时&#xff0c;可快速打出main方法 我打出syso,sout时&#xff0c;可快速打出System.out.println(); 步骤&#xff1a; 1、打开IDEA&#xff0c;点击文件&#xff0c;选择Editor中的 Live Templates选项&#xff0c;点击右侧边栏中的 号 2、选中…