深度学习 学习笔记

什么是深度学习

深度学习是机器学习的一个分支 ,核心是用多层人工神经网络从数据中自动学习特征和规律。传统机器学习往往需要人工设计特征,而深度学习可以端到端地从原始数据(如图像像素、文本词向量、声音波形)中逐层提取特征,从低级特征到高级语义。

"深度"通常指神经网络有很多层,通过多层非线性变换,模型能表达非常复杂的函数。

深度学习的特点

  • 层次化特征学习:浅层学边缘、纹理,深层学物体、语义。

  • 端到端训练:输入到输出整体优化,减少人工特征工程。

  • 数据驱动:依赖大量标注或非标注数据。

  • 依赖算力:通常需要 GPU/TPU 加速。

  • 可扩展性强:模型和数据越大,性能往往还能提升。

  • 通用性强:同一套方法可用于图像、文本、语音、图结构等。

  • 黑箱与可解释性差:尤其大模型,内部决策难以解释。

  • 容易过拟合、对超参数敏感:需要正则化、调参和大量实验。

常见的深度学习模型

  • MLP / 全连接网络:最基础的前馈网络。

  • CNN 卷积神经网络:擅长图像、视频,如 LeNet、AlexNet、VGG、ResNet。

  • RNN / LSTM / GRU:处理序列数据,如文本、语音、时间序列。

  • Transformer:基于自注意力,是现代 NLP 和大模型的基础,如 BERT、GPT。

  • Autoencoder / VAE:用于降维、表征学习、生成。

  • GAN 生成对抗网络:生成图像、视频等。

  • Diffusion 扩散模型:如 Stable Diffusion,当前主流生成模型之一。

  • GNN 图神经网络:处理社交网络、分子结构、知识图谱。

  • 深度强化学习:如 DQN、PPO,用于游戏、机器人控制。

  • 多模态大模型:同时处理文本、图像、音频、视频,如 GPT-4V、CLIP。

深度学习的应用场景

  • 计算机视觉:图像分类、目标检测、分割、人脸识别、医学影像。

  • 自然语言处理:翻译、摘要、问答、聊天机器人、搜索。

  • 语音:语音识别、语音合成、声纹识别。

  • 推荐与广告:点击率预测、个性化推荐。

  • 自动驾驶:感知、车道检测、障碍物识别、决策规划。

  • 机器人与控制:抓取、导航、运动控制。

  • 医疗与生物:疾病诊断、药物发现、蛋白质结构预测,如 AlphaFold。

  • 生成式 AI:文生图、文生视频、代码生成、写作助手。

  • 科学计算:气象预测、物理模拟、材料设计。

  • 金融风控:欺诈检测、信用评分。

深度学习的发展史

  • 1943:McCulloch-Pitts 神经元模型。

  • 1958:Rosenblatt 提出感知机。

  • 1969:Minsky 和 Papert 指出感知机不能解决 XOR,神经网络进入低谷。

  • 1986:反向传播算法推广,神经网络重新受到关注。

  • 1989/1998:LeCun 提出 CNN 和 LeNet-5,用于手写数字识别。

  • 2006:Hinton 提出深度信念网络,深度学习开始复兴。

  • 2012:AlexNet 在 ImageNet 夺冠,深度学习爆发。

  • 2014:GAN、Seq2Seq、VGG 等出现。

  • 2015:ResNet 提出残差连接,训练超深网络成为可能。

  • 2017:Transformer 提出,注意力机制成为主流。

  • 2018:BERT、GPT 出现,预训练大模型兴起。

  • 2020:GPT-3 展示大模型少样本能力。

  • 2021---2022:CLIP、扩散模型、ChatGPT、Stable Diffusion 推动生成式 AI 普及。

  • 2023 至今:GPT-4、多模态大模型、开源大模型快速发展。

PyTorch框架介绍

PyTorch 是由 Meta 开源的主流深度学习框架,以灵活、易调试、Python 优先著称,广泛用于研究和工业界。

核心概念:

  • Tensor 张量:类似 NumPy 数组,但支持 GPU 加速。

  • Autograd 自动求导:自动计算梯度,支持反向传播。

  • 动态计算图:运行时构建计算图,调试直观。

  • nn.Module:定义网络层和模型。

  • Optim 优化器:如 SGD、Adam。

  • DataLoader:批量加载和打乱数据。

  • GPU/分布式训练:支持 CUDA、多卡 DDP、FSDP。

生态工具:

  • torchvision:图像模型、数据集、变换。

  • torchaudio:音频处理。

  • torchtext:文本处理。

  • TorchScript / TorchServe:模型导出与部署。

  • Hugging Face Transformers:大量预训练模型。

什么是张量

张量(Tensor)是 PyTorch 中最核心的数据结构,可以理解为多维数组

  • 0 维张量:标量,如 torch.tensor(3.14)

  • 1 维张量:向量,如 torch.tensor([1, 2, 3])

  • 2 维张量:矩阵,如 torch.tensor([[1, 2], [3, 4]])

  • 3 维及以上:高维张量,如图像 (C, H, W)、批量图像 (N, C, H, W)

它和 NumPy 数组很像,但多了几个关键能力:

  • 可在 GPU 上计算

  • 支持自动微分

  • 支持广播、原地操作等

  • 是神经网络参数和梯度的载体

常用属性:

复制代码
import torch

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

print(x.shape)          # torch.Size([2, 2])
print(x.dtype)          # torch.float32
print(x.device)         # cpu
print(x.requires_grad)  # False
print(x.grad)           # None
print(x.grad_fn)        # None
print(x.is_leaf)        # True

2. 张量的创建

常见创建方式:

复制代码
import torch
import numpy as np

# 从 Python 列表创建
a = torch.tensor([1, 2, 3])                 # int64
b = torch.tensor([1.0, 2.0, 3.0])           # float32
c = torch.tensor([[1, 2], [3, 4]], dtype=torch.float64)

# 创建未初始化、全 0、全 1、指定值
d = torch.empty(2, 3)
e = torch.zeros(2, 3)
f = torch.ones(2, 3, dtype=torch.float64)
g = torch.full((2, 3), 7)

# 序列
h = torch.arange(0, 10, 2)                  # tensor([0, 2, 4, 6, 8])
i = torch.linspace(0, 1, 5)                 # 0 到 1 均匀取 5 个点

# 随机
j = torch.rand(2, 3)                        # [0,1) 均匀分布
k = torch.randn(2, 3)                       # 标准正态分布
l = torch.randint(0, 10, (2, 3))            # 整数随机

# 单位矩阵
m = torch.eye(3)

# 从 NumPy 创建,共享内存
n = np.array([1, 2, 3])
o = torch.from_numpy(n)
p = torch.as_tensor(n)

# 指定设备和梯度
q = torch.tensor([1.0, 2.0], device="cpu", requires_grad=True)

注意:

  • torch.tensor(...) 通常会复制数据。

  • torch.from_numpy(...)torch.as_tensor(...) 可能共享内存。

  • torch.Tensor(2, 3) 是旧式写法,创建未初始化的 float32 张量。

  • requires_grad=True 一般只用于浮点张量。


3. 张量的类型转换

复制代码
x = torch.tensor([1, 2, 3])

# 转 dtype
x_float = x.float()          # torch.float32
x_long = x.long()            # torch.int64
x_double = x.double()        # torch.float64
x_bool = x.bool()            # torch.bool
x_half = x.half()            # torch.float16

# 通用方式
y = x.to(torch.float64)
z = x.to("cpu")
# z = x.to("cuda")           # 有 GPU 时可用

# 按另一个张量的 dtype/device 转换
other = torch.randn(3, dtype=torch.float64)
w = x.to(other)

# 旧式写法
v = x.type(torch.FloatTensor)

注意:

  • 浮点转整数会截断小数部分。

  • 整数转布尔:0 为 False,非 0 为 True

  • .to() 通常返回新张量,除非 dtype 和 device 都不变。

  • 原地转换可用 .float_().long_() 等,但慎用。


4. 张量数值计算

逐元素运算:

复制代码
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])

print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a ** 2)
print(torch.sqrt(a))
print(torch.exp(a))
print(torch.log(a))
print(torch.abs(torch.tensor([-1.0, 2.0])))
print(torch.ceil(torch.tensor([1.2, 2.8])))
print(torch.floor(torch.tensor([1.2, 2.8])))
print(torch.round(torch.tensor([1.2, 2.8])))
print(torch.clamp(a, min=1.5, max=2.5))

矩阵运算:

复制代码
A = torch.randn(2, 3)
B = torch.randn(3, 4)

print(A @ B)                 # 矩阵乘法
print(torch.mm(A, B))        # 二维矩阵乘法
print(torch.matmul(A, B))    # 支持广播的矩阵乘法

v1 = torch.tensor([1.0, 2.0])
v2 = torch.tensor([3.0, 4.0])
print(torch.dot(v1, v2))     # 点积

A3 = torch.randn(10, 2, 3)
B3 = torch.randn(10, 3, 4)
print(torch.bmm(A3, B3))     # 批量矩阵乘法

比较和条件:

复制代码
x = torch.tensor([1, 2, 3])

print(x > 1)
print(torch.eq(x, torch.tensor([1, 0, 3])))
print(torch.where(x > 1, x, torch.zeros_like(x)))
原地操作通常带下划线:

python

x = torch.tensor([1.0, 2.0])
x.add_(1)      # x 变为 [2.0, 3.0]
x.mul_(2)      # x 变为 [4.0, 6.0]

5. 张量运算函数

常见统计和聚合函数:

复制代码
x = torch.tensor([[1.0, 2.0, 3.0],
                  [4.0, 5.0, 6.0]])

print(x.sum())
print(x.sum(dim=0))              # 按列求和
print(x.sum(dim=1))              # 按行求和
print(x.sum(dim=1, keepdim=True))# 保持维度

print(x.mean())
print(x.mean(dim=0))
print(x.std())
print(x.var())

print(x.max())
print(x.max(dim=1))              # 返回 values 和 indices
print(x.argmax(dim=1))
print(x.min(dim=0))
print(x.argmin(dim=0))

print(x.prod())
print(x.cumsum(dim=1))
print(torch.norm(x))
print(torch.softmax(x, dim=-1))
print(torch.log_softmax(x, dim=-1))

注意:

  • dim 表示沿哪个维度操作。

  • keepdim=True 会保留被聚合的维度,方便广播。

  • x.max(dim=1) 返回的是命名元组 (values, indices)


6. 张量索引操作

基本索引、切片:

复制代码
x = torch.arange(12).reshape(3, 4)
# tensor([[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]])

print(x[0])          # 第一行
print(x[1, 2])       # 第 1 行第 2 列
print(x[:, 1])       # 第二列
print(x[0:2, 1:3])   # 切片
print(x[::2])        # 步长 2
print(x[..., 0])     # 省略号

布尔索引:

复制代码
mask = x > 5
print(mask)
print(x[mask])
print(torch.masked_select(x, mask))

花式索引:

复制代码
idx = torch.tensor([0, 2])
print(x[idx])

print(torch.index_select(x, dim=0, index=idx))
print(torch.nonzero(x > 5))

gatherscatter

复制代码
x = torch.tensor([[1, 2],
                  [3, 4]])
index = torch.tensor([[0, 1],
                      [1, 0]])

print(torch.gather(x, dim=1, index=index))
# tensor([[1, 2],
#         [4, 3]])

out = torch.zeros(2, 2)
src = torch.tensor([[10, 20],
                    [30, 40]])
out.scatter_(dim=1, index=index, src=src)
print(out)
# tensor([[10, 20],
#         [40, 30]])

7. 张量形状操作

复制代码
x = torch.arange(12)
print(x.shape)          # torch.Size([12])

# view 和 reshape
a = x.view(3, 4)        # 要求内存连续
b = x.reshape(2, 6)     # 更灵活,必要时复制

# 增加/删除维度
c = torch.randn(3, 4)
print(c.unsqueeze(0).shape)   # (1, 3, 4)
print(c.unsqueeze(1).shape)   # (3, 1, 4)

d = torch.randn(1, 3, 1, 4)
print(d.squeeze().shape)      # (3, 4)
print(d.squeeze(0).shape)     # (3, 1, 4)

# 交换维度
e = torch.randn(3, 4)
print(e.transpose(0, 1).shape)  # (4, 3)

f = torch.randn(2, 3, 4)
print(f.permute(2, 0, 1).shape) # (4, 2, 3)

# 展平
print(f.flatten().shape)        # (24,)
print(f.flatten(start_dim=1).shape) # (2, 12)

# 扩展和重复
g = torch.randn(1, 3, 4)
print(g.expand(2, 3, 4).shape)  # (2, 3, 4)
print(g.repeat(2, 1, 1).shape)  # (2, 3, 4)

# 连续性
h = e.transpose(0, 1)
print(h.is_contiguous())        # 通常 False
h = h.contiguous()

广播示例:

复制代码
a = torch.ones(3, 4)
b = torch.ones(4)
print((a + b).shape)   # (3, 4)

8. 张量拼接操作

复制代码
a = torch.tensor([[1, 2],
                  [3, 4]])
b = torch.tensor([[5, 6],
                  [7, 8]])

# cat:沿已有维度拼接
print(torch.cat([a, b], dim=0))
# tensor([[1, 2],
#         [3, 4],
#         [5, 6],
#         [7, 8]])

print(torch.cat([a, b], dim=1))
# tensor([[1, 2, 5, 6],
#         [3, 4, 7, 8]])

# stack:沿新维度堆叠
print(torch.stack([a, b], dim=0).shape)  # (2, 2, 2)
print(torch.stack([a, b], dim=1).shape)  # (2, 2, 2)

# vstack / hstack / dstack
print(torch.vstack([a, b]).shape)  # (4, 2)
print(torch.hstack([a, b]).shape)  # (2, 4)

# split / chunk / unbind
x = torch.arange(12).reshape(3, 4)
print(torch.split(x, 1, dim=0))    # 每块 1 行
print(torch.chunk(x, 3, dim=0))    # 分成 3 块
print(torch.unbind(x, dim=0))      # 去掉第 0 维,返回元组

注意:

  • cat 要求除拼接维度外,其他维度大小一致。

  • stack 要求所有张量形状完全一致。

  • split 按块大小拆,chunk 按块数量拆。


9. 自动微分模块

PyTorch 的自动微分模块是 torch.autograd。它会记录前向传播中的操作,形成动态计算图,然后通过反向传播自动求梯度。

基本用法:

复制代码
x = torch.tensor([2.0, 3.0], requires_grad=True)

y = x ** 2 + 3 * x + 1
z = y.sum()

z.backward()

print(x.grad)
# tensor([7., 9.]),因为 dy/dx = 2x + 3

梯度会累加:

复制代码
x = torch.tensor([1.0], requires_grad=True)

for _ in range(3):
    y = x ** 2
    y.backward()
    print(x.grad)

# 每次都会累加,通常需要手动清零
x.grad.zero_()

关闭梯度:

复制代码
with torch.no_grad():
    y = x * 2
    print(y.requires_grad)  # False

detach()

复制代码
x = torch.tensor([1.0], requires_grad=True)
y = x * 2
z = y.detach()

print(y.requires_grad)  # True
print(z.requires_grad)  # False

非标量反向传播:

复制代码
x = torch.tensor([1.0, 2.0], requires_grad=True)
y = x ** 2

# y 不是标量,需要传入与 y 同形的梯度
y.backward(torch.tensor([1.0, 1.0]))
print(x.grad)  # tensor([2., 4.])

直接求梯度:

复制代码
x = torch.tensor([2.0, 3.0], requires_grad=True)
y = x ** 2
grad = torch.autograd.grad(y.sum(), x)
print(grad)  # (tensor([4., 6.]),)

简单线性回归示例:

复制代码
X = torch.randn(100, 1)
true_w = 2.0
true_b = 1.0
y = true_w * X + true_b + 0.01 * torch.randn(100, 1)

w = torch.randn(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
lr = 0.1

for epoch in range(100):
    y_pred = X * w + b
    loss = ((y_pred - y) ** 2).mean()

    loss.backward()

    with torch.no_grad():
        w -= lr * w.grad
        b -= lr * b.grad

    w.grad.zero_()
    b.grad.zero_()

print(w, b)

关键点:

  • requires_grad=True 的张量会参与计算图。

  • 叶子节点的梯度保存在 .grad

  • 反向传播后梯度默认累加,更新前通常要 zero_grad()

  • 推理或手动更新参数时用 torch.no_grad()

  • detach() 可以从计算图中分离张量。

  • 非标量调用 backward() 需要提供 gradient 参数。


总结

PyTorch 的张量操作可以概括为:

  • 创建tensorzerosonesrandnarangefrom_numpy

  • 转换.to().float().long().bool()

  • 计算:逐元素运算、矩阵乘法、广播

  • 函数summeanmaxargmaxsoftmax

  • 索引 :切片、布尔索引、gatherindex_select

  • 形状viewreshapeunsqueezetransposepermute

  • 拼接catstacksplitchunk

  • 自动微分requires_gradbackward.gradno_graddetach

相关推荐
派大_星2 小时前
基于 PyTorch 的 CNN 图片分类学习
pytorch·分类·cnn
深度学习lover3 小时前
<数据集>蚜虫识别<目标检测>
人工智能·深度学习·yolo·目标检测·计算机视觉·蚜虫识别
牧羊人.3334 小时前
动手学深度学习 03 | 卷积神经网络实现手写数字识别
人工智能·深度学习·神经网络·算法·cnn
计算机编程-吉哥5 小时前
基于YOLO11s的苹果叶片病害检测系统 | 5类病害、2万+数据集、全栈闭环【计算机毕业设计选题推荐】
深度学习·毕业设计·课程设计·计算机毕业设计选题·机器学习毕业设计·大数据毕业设计选题推荐
阳明山水5 小时前
从相关到因果:预测科学的因果转向与可识别性挑战
人工智能·深度学习·算法·机器学习·架构
运筹说5 小时前
运筹说 第160期 | 大模型如何“思考”? Transformer架构图解
人工智能·深度学习·transformer
pjj198545 小时前
深度学习-训练,评估与数据增强
人工智能·深度学习·机器学习
RobinDevNotes6 小时前
模型训练工程师必须搞懂的DDP和FSDP
人工智能·pytorch
洛阳纸贵6 小时前
AI-PyTorch(一)基础代码实操和自动求导
人工智能·pytorch·python