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

推荐订阅源

S
Security Archives - TechRepublic
WordPress大学
WordPress大学
量子位
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
Vercel News
Vercel News
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
有赞技术团队
有赞技术团队
Google DeepMind News
Google DeepMind News
H
Heimdal Security Blog
Microsoft Security Blog
Microsoft Security Blog
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
The Last Watchdog
The Last Watchdog
Security Latest
Security Latest
C
CXSECURITY Database RSS Feed - CXSecurity.com
PCI Perspectives
PCI Perspectives
H
Help Net Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - Franky
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
MongoDB | Blog
MongoDB | Blog
V
V2EX - 技术
Attack and Defense Labs
Attack and Defense Labs
C
Cybersecurity and Infrastructure Security Agency CISA
H
Hacker News: Front Page
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
Visual Studio Blog
T
Tor Project blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cisco Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Simon Willison's Weblog
Simon Willison's Weblog
F
Full Disclosure
博客园 - 司徒正美
L
LINUX DO - 最新话题
J
Java Code Geeks
G
GRAHAM CLULEY
The Register - Security
The Register - Security
B
Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
About on SuperTechFans
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs

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