惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
C
Check Point Blog
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Forbes - Security
Forbes - Security
IT之家
IT之家
L
LINUX DO - 最新话题
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
雷峰网
雷峰网
N
News | PayPal Newsroom
The Last Watchdog
The Last Watchdog
V
Visual Studio Blog
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Schneier on Security
Schneier on Security
P
Privacy International News Feed
G
Google Developers Blog
博客园 - 聂微东
博客园 - 叶小钗
M
MIT News - Artificial intelligence
Apple Machine Learning Research
Apple Machine Learning Research
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
WordPress大学
WordPress大学
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Simon Willison's Weblog
Simon Willison's Weblog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
宝玉的分享
宝玉的分享
H
Hacker News: Front Page
Martin Fowler
Martin Fowler
L
Lohrmann on Cybersecurity
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
T
The Exploit Database - CXSecurity.com
S
Security @ Cisco Blogs
博客园_首页
AWS News Blog
AWS News Blog
P
Proofpoint News Feed
人人都是产品经理
人人都是产品经理
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
T
Threatpost

Shine & Website

从圆肩到挺拔:我的训练计划 V2|肩胛稳定优先 2026 最新土耳其(外区)Apple ID 注册教程:低价订阅 ChatGPT Plus 完整指南(附开启跨区 Apple 家庭共享) 我们都还在路上:在不确定中攒出自己的选择权 Claude Desktop 接入第三方模型 API:基于 ccswitch 的配置与踩坑 从圆肩到挺拔:我的训练计划 V1|我的第一份认真训练计划 一生难忘,仅此一次:傅氏傅厝井朵桥祖厝重建竣工暨祔桃庆典 At Datawahle 我在Datawahle的日常 使用 Waline 实现 iCloud 和 Gmail 邮件通知的完整配置教程 为 Astro 博客打造完美的 Waline 评论系统:从集成到深度定制的完整实践 vscode优化体验(推荐设置 & 推荐插件) YOLO V7及多线程优化和边缘端设备RK3588-RK3588S部署 YOLO V11及多线程优化和边缘端设备RK3588-RK3588S部署 用于备份和恢复 Zotero 配置的插件-蒲公英 Tara Obsidian利用Syncthing全平台同步终极方案 同步ios和PC端 新机Linux(Ubuntu)到手一般都会做如下配置 04讲 - 炼丹流程 - PyTorch深度学习快速入门教程 02讲 - 数据 - PyTorch深度学习快速入门教程 01讲 - 配置 - PyTorch深度学习快速入门教程 其他设备通过局域网内主机的代理VPN科学上网(以Jetson设备为例) Jetson系统烧入过程(以Orin - Nano为例) Jetson Orin Nano开发指南记录 以RKNN系列模型为例,训练一个yolov7的目标检测模型 常用软件配置分享 - 持续更新 瓦肯举手礼 初识MCP技术 Qwen2.5 - VL的vllm部署方案(图像分析) 部署大模型并用Chatbox连接到远程Ollama服务 关于biome代码审查 配合Cloudflare和Piclist搭建一个属于你的免费图床 代码如诗,文章如歌
03讲 - 神经网络 - PyTorch深度学习快速入门教程
2025-07-15 · via Shine & Website

讲解了神经网络的基本结构、常用层、损失函数和优化器。首先介绍了Module、卷积层、池化层、激活层等构成神经网络的基本元素,以及Sequential的使用。然后,讲解了损失函数如L1Loss、MSELoss和CrossEntropyLoss,以及反向传播和优化器(如SGD)的工作原理。最后,通过代码示例演示了如何构建、训练和优化一个简单的神经网络。

July 15, 2025  •  7 min read


第 03 讲 神经网络📝

1.1 基本骨架

1.1.1 Module

torch.nn 是非常常用的包,其中 torch.container 中的 「Module」 是所有神经网络的基类

自己定义的模型需要实现「Module」的 __init__forward 函数

前向传播

此图的 F. 是下面代码块定义的 -> import torch.nn.functional as F

nn_module.py

import torch

from torch import nn

class Tudui(nn.Module):

def __init__(self):

super().__init__() ## 习惯性添加,调用了父类 `nn.Module` 的初始化方法,及时下面过程没有使用 `nn.Module` 的高级功能

def forward(self, input): ## 当你自定义一个模型,只要继承自 `nn.Module`,就必须定义一个名为 `forward(self, …)` 的方法,用来描述模型的前向传播逻辑

output = input + 1

return output

tudui = Tudui()

x = torch.tensor([1.0])

output = tudui(x)

print(output)

# 输出tensor([2.])PyTorch 默认的张量打印格式,表示其值为 2.0

1.1.2 Layers

1.1.2.1 Ⅰ 卷积层

卷积层中最常使用 Conv2d — 因为图像为二维

卷积核的 「size」 一般是预定义好的

卷积核的 「weights」 一般是先初始化然后通过不断迭代学习而来的

以上完整输出为: 2025-07-17_10-19-29.png

nn_conv.py

import torch

import torch.nn.functional as F

input =torch.tensor([[1,2,0,3,1],

[0,1,2,3,1],

[1,2,1,0,0],

[5,2,3,1,1],

[2,1,0,1,1]])

kernel = torch.tensor([[1,2,1],

[0,1,0],

[2,1,0]])

print(input.shape)

print(kernel.shape)

#以上输出torch.Size([5,5])和torch.Size([3,3]),不满足使用条件-> - reshape 是为了让数据 shape 满足 conv2d 的要求

# 01 看shape发现不满足,修改一下shape

input = torch.reshape(input,(1,1,5,5))

kernel = torch.reshape(kernel,(1,1,3,3))

## 02 卷积 conv2d

output = F.conv2d(input,kernel,stride=1) ## 这里的stride=1代表上下左右各移动一个像素(去扫描)

print(output)

output2 = F.conv2d(input,kernel,stride=2)

print(output2)

output3 = F.conv2d(input,kernel,stride=1,padding=1) ## padding=1代表上下左右填充1个像素

print(output3)

观察以下过程

输出 channel=2,代表有两个卷积核去扫描.并且两个卷积核数值是随机的

nn_conv2d.py

以下正式讲解卷积层的使用

import torch

import torchvision

from torch import nn

from torch.nn import Conv2d

from torch.utils.data import DataLoader

from torch.utils.tensorboard import SummaryWriter

from urllib3.filepost import writer

# 准备数据集

datset = torchvision.datasets.CIFAR10("data",

train=False, ## 训练数据集太大了,就用测试数据集

transform=torchvision.transforms.ToTensor(),

download=True)

# 加载数据集

dataloader = DataLoader(datset,batch_size=64)

# 自定义神经网络

class Tudui(nn.Module):

def __init__(self):

super().__init__()

## 创建conv1,表示你的第一个卷积层,并且后续可以在`forward`方法里直接用

self.conv1 = nn.Conv2d(in_channels=3,

out_channels=6,

kernel_size=3, ##卷积核大小

stride=1,

padding=0)

def forward(self,x):

x = self.conv1(x)

return x

# 初始化这个网络

tudui = Tudui()

## print(tudui)

writer = SummaryWriter("logs")

step = 0

for data in dataloader: ## `data` 只是一个变量名 它代表每次迭代从 `dataloader` 取出的那 1 批数据

imgs, targets = data

output = tudui(imgs)

# print(imgs.shape)

# print(output.shape)

writer.add_images("input",imgs,step) # 输入的torch.Size([64, 3, 32, 32]) 在卷积层中运行后 会输出 [64, 6, 30, 30] 有6通道;TensorBoard add_images 只支持 1 或 3 通道图片,不支持 6 通道

output = torch.reshape(output,(-1,3,30,30))

## `-1` 代表自动根据其他维度推算 batch 数量, 意思就是这个-1会经过reshape后自动计算成对应的数值.比如将以上[64, 6, 30, 30]的6压缩成两组3的话,就变成[128, 3, 30, 30]

writer.add_images("output",output,step) # 输出的torch.Size([128, 3, 30, 30])

step = step + 1

writer.close()

1.1.2.2 Ⅱ 池化层

池化层中最常使用 「MaxPool2d」

其一是对卷积层所提取的信息做更一步降维, 减少计算量

其二是 加强图像特征的不变性 ,使之增加图像的偏移、旋转等方面的鲁棒性

nn_maxpool.py

import torch

import torchvision

from torch import nn

from torch.utils.data import DataLoader

from torch.utils.tensorboard import SummaryWriter

# 01 测试最大池化的实现

# input =torch.tensor([ [1,2,0,3,1],

# [0,1,2,3,1],

# [1,2,1,0,0],

# [5,2,3,1,1],

# [2,1,0,1,1] ],

# dtype=torch.float32)

## 这是因为池化操作在底层实现时,用的都是浮点计算

# input = torch.reshape(input,(-1,1,5,5))

# print(input.shape)

##输出torch.Size([1,1,5,5])

#

# class Tudui(nn.Module):

# def __init__(self):

# super().__init__()

# self.maxpool1 = nn.MaxPool2d(kernel_size=3,ceil_mode=True)

#

# def forward(self, input):

# output = self.maxpool1(input)

# return output

#

# tudui = Tudui()

# output = tudui(input)

# print(output)

# 02 针对数据集测试

dataset = torchvision.datasets.CIFAR10(root='./data',

train=False,

transform=torchvision.transforms.ToTensor(),

download=True)

dataloader = DataLoader(dataset,batch_size=64)

class Tudui(nn.Module):

def __init__(self):

super().__init__()

self.maxpool1 = nn.MaxPool2d(kernel_size=3,ceil_mode=False)

def forward(self, input):

output = self.maxpool1(input)

return output

tudui = Tudui()

writer = SummaryWriter("logs")

step = 0

for data in dataloader:

imgs, targets = data

writer.add_images("input",imgs,step)

output = tudui(imgs)

writer.add_images("output",output,step)

step = step + 1

writer.close()

1.1.2.3 Ⅲ 激活层

激活层一般采用 「非线性激活」 ,神经网络中引入非线性的特质,才能训练出符合各种特征的模型

非线性激活函数有很多,如比较常见 「ReLU」「Sigmoid」

nn_relu.py

import torch

import torchvision

from torch import nn

from torch.nn import ReLU

from torch.utils.data import DataLoader

from torch.utils.tensorboard import SummaryWriter

from nn_conv2d import dataloader

# # 01 测试ReLU

# input = torch.tensor([[1,-0.5],

# [-1,3]])

# output = torch.reshape(input,(-1,1,2,2))

## 输出( [[[[1, -0.5],

## [-1, 3]]]] )

## 如果仅仅在此测试Relu中,可以不需要reshape,但在Conv2d这样的情况下就需要

# print(output.shape)

## 输出(1,1,2,2)

# class Tudui(nn.Module):

# def __init__(self):

# super().__init__()

# self.relu1 = nn.ReLU()

# def forward(self, input):

# output = self.relu1(input)

# return output

# tudui = Tudui()

# output = tudui(input)

# print(output)

## 输出( [[[[1.,0.],

## [0., 3.]]]] )

# 02 Sigmoid

dataset = torchvision.datasets.CIFAR10(root='./data',

train=False,

transform=torchvision.transforms.ToTensor(),

download=True)

dataloader = DataLoader(dataset,batch_size=64)

class Tudui(nn.Module):

def __init__(self):

super().__init__()

self.sigmoid1 = nn.Sigmoid()

def forward(self, input):

output = self.sigmoid1(input)

return output

tudui = Tudui()

writer = SummaryWriter("logs")

step = 0

for data in dataloader:

imgs, targets = data

writer.add_images("input",imgs,step)

output = tudui(imgs)

writer.add_images("output",output,step)

step += 1

writer.close()

对于 Relu(input,inplace=True/False)

True 代表替换原来的变量

1.1.2.4 Ⅳ 其他层

「Transformer Layers」 特定的网络结构

「Sparse Layers」 特定的网络结构,其中的 Embedding 用于自然语言处理

「Linear Layers」 用的较多,即 全连接层

nn_linear.py

import torch

import torchvision

from torch import nn

from torch.nn import Linear

from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./data",

train=False,

transform=torchvision.transforms.ToTensor(),

download=True)

dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):

def __init__(self):

super().__init__()

self.linear1 = Linear(196608, 10)

def forward(self, input):

output = self.linear1(input)

return output

tudui = Tudui()

for data in dataloader:

imgs, targets = data

print(imgs.shape) # torch.Size([64, 3, 32, 32])

# flatten 展平成一行 类似于reshape(1,1,1,-1),但是维度不一样哦

# 注意, torch.flatten和下面代码中的nn.Flatten()不一样

output = torch.flatten(imgs)

print(output.shape) # torch.Size([196608]) 注意:变成一维的了

output = tudui(output)

print(output.shape)

## 输出torch.Size([10])

Note

注意点:

torch.flatten(imgs),它直接把所有图片合成了一个一维向量,丢掉了 batch 信息。模型只能输出 `torch.Size([10])

nn.Flatten(),只展平单张图片,不会丢失 batch,所以每一张图片都能独立得到 10 维预测,输出就是 torch.Size([64,10])

1.1.3 Sequential

Sequential 主要是方便代码的编写,使代码更加简洁

根据下图搭建神经网络:判断一个图的类别(最后输出为十个类别,最后进行判断)2025-07-18_15-29-47.png

nn_seq.py

未使用 sequential 2025-07-18_15-41-43.png

使用 sequential 统一管理中间层

import torch

from torch import nn

from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential

from torch.utils.tensorboard import SummaryWriter

class Tudui(nn.Module):

def __init__(self):

super(Tudui, self).__init__()

self.model1 = Sequential(

Conv2d(3, 32, 5, padding=2),##对照以上那个图

MaxPool2d(2), ##池化

Conv2d(32, 32, 5, padding=2),

MaxPool2d(2),

Conv2d(32, 64, 5, padding=2),

MaxPool2d(2),

Flatten(), ## 展平成一维

Linear(1024, 64),

Linear(64, 10)

)

def forward(self, x):

x = self.model1(x)

return x

tudui = Tudui()

print(tudui)

# 检查网络

input = torch.ones((64, 3, 32, 32))

output = tudui(input)

print(output.shape) ## 输出 torch.Size([64,10])

# tensorboard中的add_graph 查看神经网络的流程图

writer = SummaryWriter("logs")

writer.add_graph(tudui, input)

writer.close()

1.2 损失&优化

1.2.1 损失函数

损失函数(Loss Function)用于衡量模型的「预测输出」与「实际标签」之间的差异或者误差

损失越小越好,根据 loss 调整参数,以减小损失

# 计算output和target之差的「绝对值」

nn.L1Loss()

# 计算output和target之差的「均方差」

nn.MSELoss()

# 交叉熵损失函数(Cross-Entropy Loss Function)是在分类问题中经常使用的一种损失函数

# 当分类预测正确时,损失要比较小,即\`-x[class]\`相比右边的项应较大

nn.CrossEntropyLoss()

nn_loss.py

import torch

from torch.nn import L1Loss

from torch import nn

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)

targets = torch.tensor([1, 2, 5], dtype=torch.float32)

inputs = torch.reshape(inputs, (1, 1, 1, 3))

targets = torch.reshape(targets, (1, 1, 1, 3))

# 01 L1Loss

loss = L1Loss(reduction='sum') # mean or sum 选择计算方式

result = loss(inputs, targets)

print(result)

# 02 MSELoss

loss_mse = nn.MSELoss()

result_mse = loss_mse(inputs, targets)

print(result_mse)

# 03 CrossEntropyLoss

x = torch.tensor([0.1, 0.2, 0.3])

y = torch.tensor([1])

x = torch.reshape(x, (1, 3))

##`CrossEntropyLoss` 期望 x 的形状是 (1, 3)(一个样本,三个类别),y 的形状是 (1,)

## 必须将 x 的形状由 (3,) 变为 (1, 3)

loss_cross = nn.CrossEntropyLoss()

result_cross = loss_cross(x, y)

print(result_cross)

1.2.2 反向传播

前向传播:将训练集数据输入到 NN 的「输入层」,经过「隐藏层」,最后到达「输出层」并输出结果

反向传播:计算估计值与实际值之间的误差,并将误差从「输出层」向「隐藏层」反向传播,直至「输入层」

nn_loss_network.py

import torchvision

from torch import nn

from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear

from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./data",

train=False,

transform=torchvision.transforms.ToTensor(),

download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):

def __init__(self):

super(Tudui, self).__init__()

self.model1 = Sequential(

Conv2d(3, 32, 5, padding=2),

MaxPool2d(2),

Conv2d(32, 32, 5, padding=2),

MaxPool2d(2),

Conv2d(32, 64, 5, padding=2),

MaxPool2d(2),

Flatten(),

Linear(1024, 64),

Linear(64, 10)

)

def forward(self, x):

x = self.model1(x)

return x

loss = nn.CrossEntropyLoss()

tudui = Tudui()

for data in dataloader:

imgs, targets = data

outputs = tudui(imgs)

result_loss = loss(outputs, targets)

# 反向传播 计算梯度

result_loss.backward()

print("ok")

1.2.3 优化器

更新参数 减少损失

反向传播(backward)–> 计算出梯度(grad)–> 根据梯度和学习率更新参数 –> 减小 loss

优化器的种类比较多,常用的就是 SGD(随机梯度下降)

不同优化器的参数列表不同,一般设置「parameters」和 l「lr」这两个参数,其他默认

nn_optim.py

import torch

import torchvision

from torch import nn

from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear

from torch.optim.lr_scheduler import StepLR

from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("./data",

train=False,

transform=torchvision.transforms.ToTensor(),

download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):

def __init__(self):

super(Tudui, self).__init__()

self.model1 = Sequential(

Conv2d(3, 32, 5, padding=2),

MaxPool2d(2),

Conv2d(32, 32, 5, padding=2),

MaxPool2d(2),

Conv2d(32, 64, 5, padding=2),

MaxPool2d(2),

Flatten(),

Linear(1024, 64),

Linear(64, 10)

)

def forward(self, x):

x = self.model1(x)

return x

loss = nn.CrossEntropyLoss()

tudui = Tudui()

# 优化器 SGD(随机梯度下降)

optim = torch.optim.SGD(tudui.parameters(), lr=0.01) ## lr学习率,太大不稳定,太小收敛慢

##tudui.parameters() 的作用:这个方法会自动遍历 `Tudui` 网络中所有子模块(比如 `Conv2d` 和 `Linear` 层),收集这些层的所有可训练参数,返回到torch.optim.SGD

for epoch in range(20): ## 进行多轮学习

running_loss = 0.0

for data in dataloader:

imgs, targets = data

outputs = tudui(imgs)

result_loss = loss(outputs, targets)

optim.zero_grad() # 把上一步的梯度清零,否则会累加

result_loss.backward()

optim.step() # 对weight参数进行更新

running_loss = running_loss + result_loss

print(running_loss)

03讲 - 神经网络 - PyTorch深度学习快速入门教程

https://www.futseyi.com/blog/pytorch-quickstart-neural-networks/

Author
FuTseYi

Published at
July 15, 2025

Copyright
CC BY-NC-SA 4.0