Pytorch(笔记8神经网络nn)

news2025/1/18 12:00:02

1、nn.Module

torch.nn是专门为深度学习而设计的模块。torch.nn的核心数据结构是Module,它是一个抽象的概念,既可以表示神经网络中的某个层(layer),也可以表示一个包含很多层的神经网络。在实际使用中,最常见的做法是继承nn.Module,从而编写自己的网络/层。下面先来看看如何用nn.Module实现自己的全连接层。Y=AX+B

import torch as t
import torch.nn as nn

class network(nn.Module):
    def __init__(self, input, output):
        super().__init__()
        # 定义权重矩阵a,它是一个可训练的参数,形状为(input, output)
        self.a = nn.Parameter(t.randn(input, output))
        # 定义偏置向量b,它也是一个可训练的参数,形状为(output,)
        # 注意:偏置向量的长度应与输出特征的维度相匹配
        self.b = nn.Parameter(t.randn(output))

    def forward(self, x):
        """
        定义前向传播过程

        参数:
            x (torch.Tensor): 输入数据,形状应为(batch_size, input)

        返回:
            torch.Tensor: 输出数据,形状为(batch_size, output)
        """
        # 首先,使用权重矩阵a对输入x进行线性变换
        # x@self.a执行矩阵乘法,x的每一行与a相乘,结果形状为(batch_size, output)
        x = x @ self.a
        # 然后,将偏置向量b扩展(通过broadcasting)到与x相同的形状,并加到x上
        # self.b.expand_as(x)将b的形状从(output,)扩展到(batch_size, output)
        # x + self.b.expand_as(x)将偏置加到每个样本的输出上
        x = x + self.b.expand_as(x)
        # 返回变换后的输出
        return x


a = network(4, 3)
# 创建输入数据,形状为(6, 4),表示有6个样本,每个样本有4个特征
input = t.rand(6, 4)
# 通过网络前向传播得到输出
output = a(input)
# 打印输出,形状应为(6, 3),表示有6个样本,每个样本的输出特征维度为3
print(output)
  • 自定义层network必须继承nn.Module,并且在其构造函数中需调用nn.Module的构造函数,即super().init()或nn.Module.init(self),推荐使用第一种用法;
  • 在构造函数__init__中必须自行定义可学习的参数,并封装成Parameter,如在本例中我们把w和b封装成Parameter。Parameter是一种特殊的Tensor,但其默认需要求导(requires_grad
    = True)
  • forward函数实现前向传播过程,其输入可以是一个或多个Tensor;
  • 无需写反向传播函数,nn.Module能够利用autograd自动实现反向传播,这点比Function简单许多;
  • Module中的可学习参数可以通过named_parameters()或者parameters()返回一个迭代器,前者会给每个parameter都附上名字,使其更具有辨识度。

2、常用神经网络层

2.1 图像相关层

图像相关层主要包括卷积层(Conv)、池化层(Pool)等,这些层在实际使用中可分为一维(1D)、二维(2D)和三维(3D),池化方式又分为平均池化(AvgPool)、最大值池化(MaxPool)、自适应池化(AdaptiveAvgPool)等。而卷积层除了常用的前向卷积之外,还有逆卷积(TransposeConv)等等。下面将举例说明。

  • 特征提取
  • 保持数据空间结构
  • 引入非线性变换 在卷积操作之后,通常会应用一个激活函数(如ReLU、Sigmoid或Tanh)来引入非线性变换。这些激活函数能够增加CNN的表达能力,使其能够学习更加复杂的非线性关系。
  • 提高计算效率通过卷积操作和池化层的结合使用,卷积层能够降低特征图的空间维度,从而减少计算量并提高模型的计算效率。同时,池化层还能够增强特征的平移不变性,使模型对输入数据的小变化更加鲁棒。

卷积层

在深度学习中,与图像处理相关的网络结构中最重要的便是卷积层(Conv)。卷积神经网络的本质就是卷积层、池化层、激活层以及其他层的叠加,所以理解卷积层的工作原理是极其重要的,下面将举例说明卷积操作的具体过程。
在这里插入图片描述

# 导入PyTorch库  
import torch  
import torch.nn as nn  
  
# 从torchvision.transforms导入ToTensor和ToPILImage,用于图像张量和PIL图像之间的转换  
from torchvision.transforms import ToTensor, ToPILImage  
  
# 从PIL(Python Imaging Library,Pillow是其一个分支)导入Image模块,用于处理图像文件  
from PIL import Image  
  
# 使用PIL的Image.open函数打开指定路径的图片文件,并通过.convert("L")将其转换为灰度图像(单通道)  
img = Image.open("H:\\PYTHON_Proj\\handlearnpytorch\\OIP-C.jpg").convert("L")  
  
# 实例化ToTensor转换对象,用于将PIL图像转换为PyTorch张量  
to_tensor = ToTensor()  
  
# 实例化ToPILImage转换对象,用于将PyTorch张量转换回PIL图像  
to_PIL = ToPILImage()  
  
# 使用to_tensor将PIL图像转换为PyTorch张量,并通过.unsqueeze(0)在批次大小维度上增加一个维度,使其形状变为(1, 1, H, W)  
img = to_tensor(img).unsqueeze(0)  
  
# 创建一个3x3的卷积核(滤波器),初始时所有元素都被设置为-1/9,然后将中心元素设置为1  
kernel = torch.ones(3, 3) / (-9.0)  
kernel[1][1] = 1  
  
# 创建一个Conv2d层,指定输入通道数为1(因为是灰度图像),输出通道数也为1,卷积核大小为3x3,步长为1,填充为1(保持输出尺寸与输入相同),且不使用偏置项  
conv = nn.Conv2d(1, 1, 3, 1, 1, bias=False)  
  
# 将之前定义的卷积核赋值给Conv2d层的权重,注意要调整形状以匹配Conv2d层的期望(out_channels, in_channels, kernel_size[0], kernel_size[1])  
conv.weight.data = kernel.reshape(1, 1, 3, 3)  
  
# 对图像应用卷积操作,此时img是一个四维张量,Conv2d层会处理它并返回一个新的四维张量  
img = conv(img)  
  
# 使用to_PIL将卷积后的PyTorch张量转换回PIL图像,并通过.squeeze(0)移除批次大小维度  
img = to_PIL(img.squeeze(0))  
  
# 使用PIL的.show()方法显示图像  
img.show()

池化层

池化层可以看作是一种特殊的卷积层,其主要用于下采样,增加池化层可以在保留主要特征的同时降低参数量,从而一定程度上防止了过拟合。池化层没有可学习参数,它的weight是固定的。在torch.nn工具箱中封装好了各种池化层,常见的有最大池化(MaxPool)和平均池化(AvgPool),池化层(Pooling Layer)在卷积神经网络(CNN)中扮演着非常重要的角色。它的主要用处可以归纳为以下几点:

  • 降维(减少计算量):池化层通过减少数据的空间大小(即高度和宽度),来降低后续层的计算量和参数数量。这对于防止过拟合和加快计算速度是非常有益的。
  • 特征不变性:池化层能够使得模型学习到更加鲁棒的特征表示,即对输入数据的微小变化(如平移、旋转等)具有不变性。这是因为池化操作(如最大池化、平均池化等)会选取区域内的代表性特征,而不是依赖于具体的位置信息。
  • 提取主要特征:通过池化操作,可以提取出图像中最主要的特征,而忽略掉一些不重要的细节信息。这对于后续的卷积层进一步提取高层次的特征是有帮助的。
  • 扩大感受野:随着网络层数的增加,池化层能够逐步扩大后续层中每个神经元对应的输入区域(即感受野)。这有助于网络学习到更加全局的特征信息。
  • 减少过拟合:由于池化层通过减少数据的空间维度来降低参数数量,这在一定程度上可以减少模型的复杂度,从而有助于防止过拟合。

常见的池化操作包括:

  • 最大池化(Max Pooling):在池化窗口内选取最大值作为输出。这种方式有助于保留图像的边缘和纹理信息。
  • 平均池化(Average Pooling):在池化窗口内计算所有值的平均值作为输出。这种方式有助于保留图像的背景信息。
  • 随机池化(Stochastic Pooling):根据池化窗口内各元素的值大小,按概率随机选择元素作为输出。这种方式结合了最大池化和平均池化的优点,但计算复杂度较高。

总之,池化层是卷积神经网络中不可或缺的一部分,它通过减少数据的空间维度、提取主要特征、扩大感受野以及防止过拟合等方式,为整个网络的学习能力和性能提供了重要的支持。

# 导入PyTorch库  
import torch  
  
# 导入PyTorch的神经网络模块,用于构建和训练神经网络  
import torch.nn as nn  
  
# 从torchvision.transforms模块导入ToTensor和ToPILImage,这两个转换工具用于图像数据的预处理和后处理  
from torchvision.transforms import ToTensor, ToPILImage  
  
# 从PIL库导入Image模块,用于图像的打开、显示等操作  
from PIL import Image  
  
# 创建一个ToTensor的实例,用于将PIL图像或numpy.ndarray转换为FloatTensor,并归一化到[0.0, 1.0]  
to_tensor = ToTensor()  
  
# 创建一个ToPILImage的实例,用于将Tensor或ndarray转换为PIL图像  
to_pil = ToPILImage()  
  
# 使用PIL的Image.open方法打开指定路径的图像文件,并将其转换为灰度图像('L'模式)  
img = Image.open("H:\\PYTHON_Proj\\handlearnpytorch\\OIP-C.jpg").convert('L')  
  
# 使用PIL的show方法显示图像  
img.show()  
  
# 使用ToTensor转换将PIL图像转换为Tensor,并增加一个维度使其成为[1, H, W]形状,即增加一个批次维度  
img = to_tensor(img).unsqueeze(0)  
  
# 创建一个平均池化层实例,使用2x2的窗口大小和步长为2进行池化  
pool = nn.AvgPool2d(2, 2)  
  
# 对图像Tensor应用平均池化层,然后移除批次维度(squeeze(0)),使其变回[H', W']形状  
img = pool(img).squeeze(0)  
  
# 将Tensor转换回PIL图像以便显示  
img = to_pil(img)  
  
# 再次使用PIL的show方法显示经过池化处理的图像  
img.show()

其他层

除了卷积层和池化层,深度学习中还将常用到以下几个层:

  • Linear:全连接层;
  • BatchNorm:批标准化层,分为1D、2D和3D。除了标准的BatchNorm之外,还有在风格迁移中常用到的InstanceNorm层;
  • Dropout:Dropout层,用来防止过拟合,同样分为1D、2D和3D。

3、初始化策略

在深度学习中参数的初始化十分重要,良好的初始化能让模型更快地收敛,并达到更高水平,而糟糕的初始化则可能使得模型迅速崩溃。PyTorch中nn.Module的模块参数都采取了较为合理的初始化策略,因此一般不用我们考虑。当然我们也可以用自定义初始化来代替系统的默认初始化。而当我们在使用Parameter时,自定义初始化则尤为重要,这是因为torch.Tensor()返回的是内存中的随机数,很可能会有极大值,这在实际训练网络中会造成溢出或者梯度消失。PyTorch中nn.init模块就是专门为初始化而设计的一个模块,其中实现了常用的初始化策略。如果某种初始化策略nn.init不提供,用户也可以自己直接初始化。

import torch  
from torch.nn import init  
from torch import nn  
  
# 创建一个线性层,其权重和偏置会被随机初始化(与torch.manual_seed无关,因为这是在调用torch.manual_seed之前发生的)  
linear = nn.Linear(3, 4)  
  
# 打印层创建时默认初始化的权重  
print("默认初始化的权重:")  
print(linear.weight)  
  
# 设置随机数生成的种子,以确保接下来的随机数生成是可重复的  
torch.manual_seed(2021)  
  
# 使用Xavier正态分布重新初始化权重  
# 这个初始化是受torch.manual_seed(2021)影响的  
init.xavier_normal_(linear.weight)  
  
# 打印重新初始化后的权重  
print("Xavier正态分布初始化后的权重:")  
print(linear.weight)

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

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

相关文章

可视化学习:如何用WebGL绘制3D物体

在之前的文章中,我们使用WebGL绘制了很多二维的图形和图像,在学习2D绘图的时候,我们提过很多次关于GPU的高效渲染,但是2D图形的绘制只展示了WebGL部分的能力,WebGL更强大的地方在于,它可以绘制各种3D图形&a…

一行命令快速导出、导入Python的依赖环境(Python)

文章目录 一、pip1、导出2、导入 二、Conda(简)1、导出1、导入 一、pip 1、导出 在Pycharm的Terminal窗口输入如下命令,即可将环境导出至文件requirements.txt。 pip freeze > C:\Users\sdl\Deskto\requirements.txt也可以在DOS界面执行…

python:sympy 求解一元五次方程式

pip install sympy 或者 本人用的 anaconda 3 自带 sympy 在北大数学训练营,韦东奕 用卡丹公式 巧妙 求解一元五次方程式: \latex $x^510*x^320*x-4 0$ from sympy import *x symbols(x) expr x**5 10*x**3 20*x -4# 用卡丹公式 尝试化简 a sym…

【操作系统】进程管理——用信号量机制解决问题,以生产者-消费者问题为例(个人笔记)

学习日期:2024.7.10 内容摘要:利用信号量机制解决几个经典问题模型 目录 引言 问题模型 生产者-消费者问题(经典) 多生产者-多消费者问题 吸烟者问题 读者写者问题(难点) 哲学家进餐问题&#xff0…

如何在vue的项目中导入阿里巴巴图标库

阿里巴巴矢量图标库官网:iconfont-阿里巴巴矢量图标库 选择你喜欢的图标,添加入库 点击添加至项目,并新建文件夹,点击确定 选择font-class,点击生成代码 代码生成后,在网站上打开 全选复制到style 点击复制…

Agents 要点

一、Agents概念 人类是这个星球上最强大的 Agent。Agent是一个能感知并自主地采取行动的实体,这里的自主性极其关键,Agent要能够实现设定的目标,其中包括具备学习和获取知识的能力以提高自身性能。 关键点:感知环境、自主决策、具…

SpringBoot新手快速入门系列教程十一:基于Docker Compose部署一个最简单分部署服务项目

如果您还对于Docker或者Docker Compose不甚了解,可以劳烦移步到我之前的教程: SpringBoot新手快速入门系列教程九:基于docker容器,部署一个简单的项目 SpringBoot新手快速入门系列教程十:基于Docker Compose&#xf…

CSS特效:pointer-events: none;的一种特殊应用

一、需求描述 今天看到一个设计需求:需要在弹框中显示如下界面,其中有两个效果: 1.顶部点击项目,下面的内容能相应滚动定位,同时滚动的时候顶部项目也能相应激活显示 2.顶部右侧有一个模糊渐变效果,并且要…

day29--452. 用最少数量的箭引爆气球+435. 无重叠区间+763.划分字母区间

一、452. 用最少数量的箭引爆气球 题目链接:https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/ 文章讲解:https://programmercarl.com/0452.%E7%94%A8%E6%9C%80%E5%B0%91%E6%95%B0%E9%87%8F%E7%9A%84%E7%AE%AD%E5%BC%95%E7%88…

ISO/OIS的七层模型②

OSI模型是一个分层的模型,每一个部分称为一层,每一层扮演固定的角色,互不干扰。OSI有7层,从上到下分别是: 一,每层功能 7.应用层(Application layer ):应用层功能&#x…

AI克隆声音,基于函数计算部署GPT-Sovits语音生成模型

阿里云的 https://developer.aliyun.com/adc/scenario/808348a321844a62b922187d89cd5077 还是 函数计算 FC (aliyun.com) 选择 语音克隆生成 GPT-SOVITS 通过访问域名就能访问 就可以上传个人的声音,然后进行输出 。

【第29章】MyBatis-Plus之分页插件

文章目录 前言一、支持的数据库二、配置方法三、属性介绍四、自定义 Mapper 方法中使用分页五、其他注意事项六、Page 类七、实战1. 配置类2. 分页类3. 测试 总结 前言 MyBatis-Plus 的分页插件 PaginationInnerInterceptor 提供了强大的分页功能,支持多种数据库&a…

SpringBoot3+Vue3开发园区管理系统

介绍 在当今快速发展的城市化进程中,高效、智能的园区管理成为了提升居民生活品质、优化企业运营环境的关键。为此,我们精心打造了全方位、一体化的园区综合管理系统,该系统深度融合了园区管理、楼栋管理、楼层管理、房间管理以及车位管理等…

openlayers WebGL裁剪图层,双图层拼接显示

本篇介绍一下使用openlayers WebGL裁剪图层,双图层拼接显示 1 需求 WebGL裁剪图层,双图层拼接显示 2 分析 图层prerender和postrender事件的使用 WebGL scissor方法的使用 scissor方法指定了一个裁剪区域,用来将绘图区域限制在其限定的盒…

深度学习中的超参管理方法:argparse模块

在深度学习方法中我们不可避免地会遇到大量超参数如(batch_size、learning_rate等)。不同的超参数组合可以得到不同的训练/测试结果。所以在训练和测试过程中我们需要不断调整超参数获得理想的结果(炼丹),如果每一次去…

设备管理中的数据结构

一、有哪些数据结构属于设备管理数据结构 1. 设备控制表(DCT) “Device Control Table”的首字母缩写 2. 控制器控制表(COCT) “Controller Of Control Table”的首字母缩写。 3. 通道控制表(CHCT) “…

简单实现一个本地ChatGPT web服务(langchain框架)

简单实现一个本地ChatGPT 服务,用到langchain框架,fastapi,并且本地安装了ollama。 依赖安装: pip install langchain pip install langchain_community pip install langchain-cli # langchain v0.2 2024年5月最新版本 pip install bs4 pi…

基于swagger插件的方式推送接口文档至torna

目录 一、前言二、登录torna三、创建/选择空间四、创建/选择项目五、创建/选择应用六、获取应用的token七、服务推送7.1 引入maven依赖7.2 test下面按照如下方式新建文件 一、前言 Torna作为一款企业级文档管理系统,支持了很多种接口文档的推送方式。官方比较推荐的…

基于EMQX+Flask+InfluxDB+Grafana打造多协议物联网云平台:MQTT/HTTP设备接入与数据可视化流程(附代码示例)

摘要: 本文深入浅出地介绍了物联网、云平台、MQTT、HTTP、数据可视化等核心概念,并结合 EMQX、Flask、InfluxDB、Grafana 等主流工具,手把手教你搭建一个支持多协议的物联网云平台。文章结构清晰,图文并茂,代码翔实易懂&#xff0…

Linux 入门教程 by 程序员鱼皮

本文作者:程序员鱼皮 免费编程学习 - 编程导航网:https://www.code-nav.cn 大家好,我是鱼皮。 前两天我学编程的老弟小阿巴过生日,我问他想要什么礼物。 本来以为他会要什么游戏机、Q 币卡、鼠标键盘啥的,结果小阿巴…