day22_深度学习入门与pytorch
day22_深度学习与PyTorch入门
一、深度学习概述
1. 概念
深度学习具体是什么呢?一句话概括:深度学习模仿人类大脑的运行方式,依赖算法自动提取特征,而不需要人工设计特征。
传统机器学习需要人工设计特征并手动提取,而深度学习把"提取特征"这事儿也交给了算法自己。这也是为什么深度学习经常被称为"黑盒子"——模型学到的特征是人眼难以直接理解的。
深度学习擅长处理高维数据,比如图像(每个像素都是特征)、文本(每个词都是特征)。
2. 深度学习的优缺点
优点:
- 精度高 — 性能优于其他机器学习算法,某些领域甚至超越了人类水平
- 可以近似任意非线性函数 — 随着硬件发展,深层网络的表达能力越来越强
- 生态丰富 — 有大量的框架和开源库可供调用
缺点:
- 黑箱问题 — 很难解释模型到底是怎么做出判断的
- 训练时间长 — 需要大量的计算资源(GPU、TPU等)
- 超参数多 — 网络结构复杂,需要调整的参数多
- 容易过拟合 — 在部分数据集上表现不佳,需要正则化手段
3. 深度学习发展史
深度学习并非一夜爆红,它经历了三个主要时期:
| 时期 | 时间 | 关键事件 |
|---|---|---|
| 符号主义 | 1950s-1970s | 1943年McCulloch-Pitts提出神经元模型;1956年达特茅斯会议提出"AI"概念;1957年Rosenblatt提出感知器;1962年跳棋程序战胜人类 |
| 统计主义 | 1980s-2000 | 1986年BP算法成熟,多层神经网络可训练;1997年深蓝战胜卡斯帕罗夫;1993年SVM提出 |
| 神经网络与深度学习 | 2006-至今 | 2006年Hinton提出DBN,开启深度学习复兴;2012年AlexNet大幅赢得ImageNet比赛;2016年AlphaGo战胜李世石;2017年Transformer框架出现;2018年BERT/GPT诞生;2022年ChatGPT引爆AIGC浪潮;2025年开启智能体时代 |
🔑 关键转折点:2012年AlexNet在ImageNet图像识别竞赛中以巨大优势夺冠,这是深度学习爆发的标志性事件;2017年Transformer的出现则彻底改变了NLP领域。
4. 主流算法模型
深度学习不是单一的算法,而是一族方法,下面是最主流的几种:
| 模型 | 适用场景 | 核心特点 |
|---|---|---|
| 卷积神经网络(CNN) | 图像识别、视频分析、医学影像 | 擅长处理带有空间关系的数据,通过卷积核提取局部特征 |
| 循环神经网络(RNN)/LSTM/GRU | 语音识别、音乐生成、NLP | 处理序列数据中的时间动态性,有记忆能力 |
| Transformer | 复杂语言理解与生成 | BERT、GPT系列的基础,用自注意力机制替代循环结构 |
| 自编码器(Autoencoder) | 数据降维、去噪、异常检测 | 通过编码-解码结构学习数据的压缩表示 |
| 生成对抗网络(GAN) | 图像生成、艺术创作、数据增强 | 生成器与判别器互相博弈,生成逼真数据 |
二、主流深度学习框架
1. 四大框架对比
目前最主流的深度学习框架有以下四个:
| 框架 | 出生地 | 特点 | 适合谁 |
|---|---|---|---|
| TensorFlow | 计算图架构、分布式训练强、底层C构建速度快、生态强大,但学术圈已式微 | 做工程/部署的小伙伴 | |
| PyTorch | Meta(原Facebook) | ⭐ 动态图、代码量少、入门爽、学术界霸主,几乎所有顶会论文代码都用它写 | 想做学术的绝对首选 |
| PaddlePaddle(飞桨) | 百度 | 动态图/静态图都支持、部署方便、有专门平台和工具包 | 算力有限或想用国产框架的 |
| ONNX | 多家大厂联合 | 并不是训练框架,而是一种中间格式,用于模型格式转换(Pytorch→ONNX→其他) | 不用刻意学,用到再看 |
📝 一句话总结:做学术搞研究选 PyTorch,做工程部署选 TensorFlow,搞国产生态选 PaddlePaddle,模型转换靠 ONNX。
2. PyTorch简介
PyTorch 是基于 Python 的深度学习框架,核心概念是张量(Tensor)。它提供了灵活高效的工具,用于构建、训练和部署深度学习模型。
安装极其简单:
pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple
三、PyTorch张量操作详解
1. 什么是张量
张量(Tensor)是 PyTorch 的核心数据抽象,简单理解就是多维数组。它与 NumPy 的 ndarray 非常相似,但多了一个杀手锏——支持GPU加速(CUDA)。
| 维度 | 名称 |
|---|---|
| 0维 | 标量(scalar) |
| 1维 | 向量(vector) |
| 2维 | 矩阵(matrix) |
| 3维及以上 | 张量(tensor) |
🔑 关键区别:PyTorch张量与NumPy数组类似,但通过CUDA可以在GPU上高效运行,大幅加速深度学习模型的训练。
2. 张量的创建方法
import torch
# 1. 根据指定数据创建
data = torch.tensor([[1, 2], [3, 4]])
print(data) # tensor([[1, 2], [3, 4]])
# 2. 根据形状创建(未初始化)
data = torch.Tensor(2, 3) # 2行3列
# 3. 指定类型创建
data_int = torch.IntTensor([1, 2, 3])
data_float = torch.FloatTensor([1.1, 2.2, 3.3])
# 4. 创建线性张量
arange_data = torch.arange(0, 10, 2) # [0, 2, 4, 6, 8]
linspace_data = torch.linspace(0, 1, 5) # [0, 0.25, 0.5, 0.75, 1]
# 5. 创建随机张量
torch.random.manual_seed(42) # 固定随机种子
rand_data = torch.rand(2, 3) # [0,1)均匀分布
randn_data = torch.randn(2, 3) # 标准正态分布
randint_data = torch.randint(0, 10, (2, 3)) # [0,10)随机整数
# 6. 创建全0/全1/全指定值张量
zeros_data = torch.zeros(2, 3) # 全0
ones_data = torch.ones(2, 3) # 全1
full_data = torch.full((2, 3), 7) # 全为7
# 还有 ones_like / zeros_like / full_like 可模仿形状
3. 张量类型转换
data = torch.tensor([1, 2, 3])
# 方法一:直接转换
data_float = data.float() # torch.float32
data_double = data.double() # torch.float64
data_int = data.int() # torch.int32
data_long = data.long() # torch.int64
data_half = data.half() # torch.float16
# 方法二:用 type() 方法
data_fp32 = data.type(torch.float)
data_i32 = data.type(torch.int)
4. 张量与NumPy互转
import numpy as np
# 张量 → numpy(共享内存,修改一个会影响另一个)
data_tensor = torch.tensor([1, 2, 3])
data_numpy = data_tensor.numpy() # 共享内存
data_numpy_copy = data_tensor.numpy().copy() # 不共享内存
# numpy → 张量(共享内存)
data_np = np.array([4, 5, 6])
data_tensor_shared = torch.from_numpy(data_np) # 共享内存
data_tensor_new = torch.tensor(data_np) # 不共享内存
# 标量张量 ↔ 数字
scalar = torch.tensor(3.14)
print(scalar.item()) # 3.14
⚠️ 注意:
tensor.numpy()和torch.from_numpy()是共享内存的,修改其中一个会影响另一个。如果不希望共享,用.copy()或torch.tensor()。
5. 张量基本运算
# 1. 基本算术运算
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
print(a + b) # tensor([5, 7, 9])
print(a - b) # tensor([-3, -3, -3])
print(a * b) # tensor([4, 10, 18])
print(a / b) # tensor([0.25, 0.40, 0.50])
# 函数形式(带下划线的为原地操作,会修改原张量)
torch.add(a, b) # add, sub, mul, div
a.add_(b) # 原地加法:a = a + b(注意下划线)
# 2. 矩阵乘法
matrix_a = torch.tensor([[1, 2], [3, 4]])
matrix_b = torch.tensor([[5, 6], [7, 8]])
print(matrix_a @ matrix_b) # 使用 @ 运算符
print(torch.matmul(matrix_a, matrix_b)) # 使用 matmul 函数
# 3. 常见运算函数
data = torch.tensor([1.0, 2.0, 3.0, 4.0])
print(torch.sum(data)) # 求和:10.0
print(torch.mean(data)) # 均值:2.5
print(torch.sqrt(data)) # 平方根
print(torch.pow(data, 2)) # 平方:tensor([1, 4, 9, 16])
print(torch.exp(data)) # 指数
print(torch.log(data)) # 对数
6. 张量索引操作
张量的索引和 NumPy 完全一致,非常直观:
data = torch.randint(0, 10, (3, 4))
print(data)
# 假设输出:
# tensor([[5, 1, 8, 3],
# [9, 2, 6, 0],
# [4, 7, 2, 5]])
# 格式:张量[行, 列]
# 1. 单索引
print(data[1, 2]) # 第2行第3列 → 6
# 2. 列表索引
print(data[[0, 2], :]) # 第1行和第3行的所有列
# 3. 切片索引
print(data[0:2, 1:3]) # 前两行的第2~4列
# 4. 布尔索引
mask = data > 5
print(data[mask]) # 所有大于5的元素
# 5. 多维索引
print(data[1]) # 第2行所有列
7. 张量形状操作
data = torch.arange(12) # tensor([0, 1, 2, ..., 11])
# reshape — 重塑形状(最常用)
reshaped = data.reshape(3, 4)
print(reshaped.shape) # torch.Size([3, 4])
# view — 类似reshape,但要求内存连续
viewed = data.view(3, 4) # data本身连续,所以可以
# 对于不连续的张量,先 contiguous 再 view
transposed = data.reshape(3, 4).transpose(0, 1)
# transposed 是不连续的
viewed = transposed.contiguous().view(4, 3)
# squeeze — 删除长度为1的维度
data_with_dim1 = data.reshape(1, 3, 1, 4) # shape: [1, 3, 1, 4]
squeezed = data_with_dim1.squeeze() # shape: [3, 4]
# unsqueeze — 增加长度为1的维度
data_2d = torch.tensor([[1, 2, 3], [4, 5, 6]]) # shape: [2, 3]
unsqueezed = data_2d.unsqueeze(0) # shape: [1, 2, 3]
# transpose — 交换两个维度
data_3d = torch.randn(2, 3, 4)
transposed = data_3d.transpose(1, 2) # shape: [2, 4, 3]
# permute — 任意重排所有维度
permuted = data_3d.permute(2, 0, 1) # shape: [4, 2, 3]
📝 reshape vs view:
reshape更智能,自动处理不连续的张量;view更快但要求内存连续,不连续时需配合contiguous()使用。
8. 张量拼接操作
data1 = torch.randint(0, 10, (1, 2, 3))
data2 = torch.randint(0, 10, (1, 2, 3))
print("data1:", data1)
print("data2:", data2)
# 1. cat — 沿已有维度拼接(不增加维度)
# dim=0 拼接 → shape: [2, 2, 3]
cat_dim0 = torch.cat([data1, data2], dim=0)
# dim=1 拼接 → shape: [1, 4, 3]
cat_dim1 = torch.cat([data1, data2], dim=1)
# dim=2 拼接 → shape: [1, 2, 6]
cat_dim2 = torch.cat([data1, data2], dim=2)
# 2. stack — 在新维度上堆叠(会增加一个维度)
data3 = torch.randint(0, 10, (2, 3))
data4 = torch.randint(0, 10, (2, 3))
# dim=0 → shape: [2, 2, 3](在第一个维度前插入新维度)
stack_dim0 = torch.stack([data3, data4], dim=0)
# dim=1 → shape: [2, 2, 3](在第二个维度前插入新维度)
stack_dim1 = torch.stack([data3, data4], dim=1)
# dim=2 → shape: [2, 3, 2](在第三个维度前插入新维度)
stack_dim2 = torch.stack([data3, data4], dim=2)
🔑 cat vs stack 的区别:
cat不改变张量的维度数,只在现有维度上拼接;stack会增加一个新维度,要求所有输入张量的形状完全相同。
四、实操案例:完整张量操作流水线
下面是一个综合案例,将我们学过的张量操作串起来走一遍:
import torch
import numpy as np
# ============================
# 1. 创建数据 — 模拟一个3通道2x2的"图像"
# ============================
torch.random.manual_seed(42)
image = torch.randint(0, 256, (3, 2, 2)) # shape: [3, 2, 2]
print("原始图像张量形状:", image.shape)
# ============================
# 2. 类型转换 — 转为浮点型便于计算
# ============================
image_float = image.float()
print("转换后类型:", image_float.dtype)
# ============================
# 3. 归一化 — 将像素值缩放到[0,1]
# ============================
image_norm = image_float / 255.0
print("归一化后的均值:", torch.mean(image_norm).item())
# ============================
# 4. 增加批次维度 — 模型需要4D输入
# ============================
image_batch = image_norm.unsqueeze(0) # shape: [1, 3, 2, 2]
print("增加批次维度后:", image_batch.shape)
# ============================
# 5. 展平 — 将图像变为一维向量
# ============================
image_flat = image_batch.reshape(1, -1) # shape: [1, 12]
print("展平后形状:", image_flat.shape)
# ============================
# 6. 转 NumPy 数组
# ============================
image_numpy = image_flat.numpy()
print("转换为NumPy数组, 类型:", type(image_numpy))
# ============================
# 7. 数学运算 — 模拟简单的特征变换
# ============================
weights = torch.randn(12, 4) # 随机权重
bias = torch.randn(4) # 随机偏置
output = torch.matmul(image_flat, weights) + bias
print("线性变换后输出形状:", output.shape)
# ============================
# 8. 激活函数 — 模拟ReLU
# ============================
output_activated = torch.relu(output)
print("激活后输出:", output_activated)
# ============================
# 9. 拼接多张"图像"(模拟batch处理)
# ============================
image2 = torch.rand(1, 12) # 第二张"图像"
batch = torch.cat([image_flat, image2], dim=0) # shape: [2, 12]
print("拼接batch后形状:", batch.shape)
print("\n✅ 完整流水线执行完毕!")
五、总结
| 知识点 | 一句话总结 |
|---|---|
| 深度学习 | 用深层神经网络自动提取特征,无需人工设计 |
| 深度学习 vs ML | DL是ML的子集,DL自动提取特征,ML需要人工特征工程 |
| 主流模型 | CNN处理图像、RNN处理序列、Transformer处理语言、GAN生成数据 |
| PyTorch | 学术界主流框架,动态图、上手快、生态丰富 |
| 张量(Tensor) | PyTorch的核心数据抽象,类似NumPy但支持GPU加速 |
| 张量创建 | tensor()、Tensor()、ones/zeros/full、rand/randn/randint、arange/linspace |
| 张量运算 | + - * /、@/matmul、sum/mean/sqrt/pow/exp/log |
| 形状操作 | reshape(通用)、view(连续内存)、squeeze/unsqueeze(增减维度)、transpose/permute(交换维度) |
| 拼接操作 | cat(沿现有维度拼接,不增维)、stack(新维度堆叠,增一维) |
| NumPy互转 | tensor.numpy() 和 torch.from_numpy() 共享内存,.copy() 和 torch.tensor() 不共享 |
更多推荐


所有评论(0)