Pytorch nn.Linear()的基本用法与原理详解及全连接层简介

2023-12-19 04:52

本文主要是介绍Pytorch nn.Linear()的基本用法与原理详解及全连接层简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

主要引用参考:
https://blog.csdn.net/zhaohongfei_358/article/details/122797190
https://blog.csdn.net/weixin_43135178/article/details/118735850

nn.Linear的基本定义

nn.Linear定义一个神经网络的线性层,方法签名如下:

torch.nn.Linear(in_features, # 输入的神经元个数out_features, # 输出神经元个数bias=True # 是否包含偏置)

Linear其实就是对输入 X n × i X_{n\times i} Xn×i执行了一个线性变换,即:
Y n × o = X n × i W i × o + b Y_{n\times o}=X_{n\times i}W_{i\times o}+b Yn×o=Xn×iWi×o+b
其中 W W W是模型想要学习的参数, W W W的维度为 W i × o W_{i\times o} Wi×o,b是o维的向量偏置,n为输入向量的行数(例如,你想一次输入10个样本,即batch_size为10,则n=10),i为输入神经元的个数(例如你的样本特征为5,则i=5),o为输出神经元的个数。

示例:

from torch import nn
import torchmodel = nn.Linear(2, 1) # 输入特征数为2,输出特征数为1
input = torch.Tensor([1, 2]) # 给一个样本,该样本有2个特征(这两个特征的值分别为1和2)
output = model(input)
output
tensor([-1.4166], grad_fn=<AddBackward0>)

我们的输入为[1,2],输出了[-1.4166]。可以查看模型参数验证一下上述的式子:

# 查看模型参数
for param in model.parameters():print(param)
Parameter containing:
tensor([[ 0.1098, -0.5404]], requires_grad=True)
Parameter containing:
tensor([-0.4456], requires_grad=True)

可以看到,模型有3个参数,分别为两个权重和一个偏执。计算可得:
y = [ 1 , 2 ] ∗ [ 0.1098 , − 0.5404 ] T − 0.4456 = − 1.4166 y=[1,2]*[0.1098,-0.5404]^T-0.4456=-1.4166 y=[1,2][0.1098,0.5404]T0.4456=1.4166


实战

假设我们的一次输入三个样本A,B,C(即batch_size为3),每个样本的特征数量为5:

A: [0.1,0.2,0.3,0.3,0.3]
B: [0.4,0.5,0.6,0.6,0.6]
C: [0.7,0.8,0.9,0.9,0.9]

则我们的输入向量 X 3 × 5 X_{3\times 5} X3×5为:

X = torch.Tensor([[0.1,0.2,0.3,0.3,0.3],[0.4,0.5,0.6,0.6,0.6],[0.7,0.8,0.9,0.9,0.9],
])
X
tensor([[0.1000, 0.2000, 0.3000, 0.3000, 0.3000],[0.4000, 0.5000, 0.6000, 0.6000, 0.6000],[0.7000, 0.8000, 0.9000, 0.9000, 0.9000]])

定义线性层,我们的输入特征为5,所以in_feature=5,我们想让下一层的神经元个数为10,所以out_feature=10,则模型参数为: W 5 × 10 W_{5\times 10} W5×10

model = nn.Linear(in_features=5, out_features=10, bias=True)

经过线性层,其实就是做了一件事,即:
Y 3 × 10 = X 3 × 5 W 5 × 10 + b Y_{3\times 10}=X_{3\times 5}W_{5\times 10}+b Y3×10=X3×5W5×10+b
具体表示为:
[ Y 00 Y 01 ⋯ Y 08 Y 09 Y 10 Y 11 ⋯ Y 18 Y 19 Y 20 Y 21 ⋯ Y 28 Y 29 ] = [ X 00 X 01 X 02 X 03 X 04 X 10 X 11 X 12 X 13 X 14 X 20 X 21 X 22 X 23 X 23 ] [ W 00 W 01 ⋯ W 08 W 09 W 10 W 11 ⋯ W 18 W 19 W 20 W 21 ⋯ W 28 W 29 W 30 W 31 ⋯ W 38 W 39 W 40 W 41 ⋯ W 48 W 49 ] + b \begin{equation} \left[ \begin{array}{ccc} Y_{00} & Y_{01} &\cdots & Y_{08} &Y_{09} \\ Y_{10} & Y_{11} &\cdots & Y_{18} &Y_{19} \\ Y_{20} & Y_{21} &\cdots & Y_{28} &Y_{29} \end{array} \right] =\left[ \begin{array}{ccc} X_{00} & X_{01} &X_{02} & X_{03} &X_{04} \\ X_{10} & X_{11} &X_{12} & X_{13} &X_{14} \\ X_{20} & X_{21} &X_{22} & X_{23} &X_{23} \end{array}\nonumber \right] \left[ \begin{array}{ccc} W_{00} & W_{01} &\cdots & W_{08} &W_{09} \\ W_{10} & W_{11} &\cdots & W_{18} &W_{19} \\ W_{20} & W_{21} &\cdots & W_{28} &W_{29} \\ W_{30} & W_{31} &\cdots & W_{38} &W_{39} \\ W_{40} & W_{41} &\cdots & W_{48} &W_{49} \\ \end{array} \right] +b \end{equation}\nonumber Y00Y10Y20Y01Y11Y21Y08Y18Y28Y09Y19Y29 = X00X10X20X01X11X21X02X12X22X03X13X23X04X14X23 W00W10W20W30W40W01W11W21W31W41W08W18W28W38W48W09W19W29W39W49 +b

个人的理解:比如 X X X第一行和 W W W矩阵的第一列相乘就相当于对样本A做了全局卷积,最后得到了1个特征,因为 W W W有10列,所以最后得到10个特征,也就是把5个特征转变为了10个特征。

其中 X i . X_i. Xi.就表示第i个样本, W . j W_{.j} W.j表示所有输入神经元到第j个输出神经元的权重。
在这里插入图片描述

注意:这里图有点问题,应该是 W 00 , W 01 , W 02 , . . . , W 07 , W 08 , W 09 W_{00}, W_{01}, W_{02}, ..., W_{07}, W_{08},W_{09} W00,W01,W02,...,W07,W08,W09(我没觉得图有问题)

因为有三个样本,所以相当于依次进行了三次 Y 3 × 10 = X 3 × 5 W 5 × 10 + b Y_{3\times 10}=X_{3\times 5}W_{5\times 10}+b Y3×10=X3×5W5×10+b,然后再将三个 Y 1 × 10 Y_{1\times 10} Y1×10叠在一起

经过线性层后,我们最终的到了3×10维的矩阵,即 输入3个样本,每个样本维度为5,输出为3个样本,将每个样本扩展成了10维

model(X).size()
torch.Size([3, 10])

全连接层

概述
全连接层 Fully Connected Layer 一般位于整个卷积神经网络的最后,负责将卷积输出的二维特征图转化成一维的一个向量,由此实现了端到端的学习过程(即:输入一张图像或一段语音,输出一个向量或信息)。全连接层的每一个结点都与上一层的所有结点相连因而称之为全连接层。由于其全相连的特性,一般全连接层的参数也是最多的。

主要作用
全连接层的主要作用就是将前层(卷积、池化等层)计算得到的特征空间映射样本标记空间。简单的说就是将特征表示整合成一个值,其优点在于减少特征位置对于分类结果的影响,提高了整个网络的鲁棒性。
全连接在整个网络卷积神经网络中起到“分类器”的作用,如果说卷积层、池化层和激活函数等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的特征表示映射到样本的标记空间的作用。其实,就是把特征整合到一起,方便交给最后的分类器或者回归。

实际操作
在实际使用中,全连接层可由卷积操作实现:对前层是全连接的全连接层可以转换为卷积核为1*1的卷积;而前层是卷积层的全连接层可以转换为卷积核为前层卷积输出结果的高和宽一样大小的全局卷积。

一个通俗的例子:
以VGG-16为例,对224x224x3的输入,最后一层卷积可得输出为7x7x512,如后层是一层含4096个神经元的FC,则可用卷积核为7x7x512x4096的全局卷积来实现这一全连接运算过程,其中该卷积核参数如下:“filter size = 7, padding = 0, stride = 1, D_in = 512, D_out = 4096”经过此卷积操作后可得输出为1x1x4096。如需再次叠加一个2048的FC,则可设定参数为“filter size = 1, padding = 0, stride = 1, D_in = 4096, D_out = 2048”的卷积层操作(个人理解就是用1×1×4096×2048的卷积核来卷积)。(参考:https://www.zhihu.com/question/41037974/answer/150522307)

这篇关于Pytorch nn.Linear()的基本用法与原理详解及全连接层简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/510949

相关文章

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

C语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream