学习深度学习需掌握以下基础:
数据处理:涵盖存储、操作与预处理,核心技能为高效管理表格数据(样本为行,属性为列)。
线性代数:矩阵运算是处理多维数据的基础,重点理解基本原理与实现,如矩阵乘法与操作。
优化与微积分:通过调整模型参数优化性能,微积分指导参数更新方向,实用工具(如autograd
)可自动求导简化计算。
概率论:用于不确定场景下的推断与预测,提供量化不确定性的数学框架。
官方文档利用:熟练查阅框架文档以扩展知识,解决实际问题。
.
为了能够完成各种数据操作,我们需要某种方法来存储和操作数据。 通常,我们需要做两件重要的事:
(1)获取数据;
(2)将数据读入计算机后对其进行处理。
首先,我们介绍维数组,也称为张量(tensor)。张量类(在MXNet中为ndarray
, 在PyTorch和TensorFlow中为Tensor
)都与Numpy的ndarray
类似。 但深度学习框架又比Numpy的ndarray
多一些重要功能: 首先,GPU很好地支持加速计算,而NumPy仅支持CPU计算; 其次,张量类支持自动微分。
.
核心概念:
张量维度:1轴为向量,2轴为矩阵,更高维度无特定数学名称。
形状变换时元素总数不变,-1
可自动推导维度。
初始化方法(全0/1、随机)常用于模型参数初始化。
基础操作:
导入库:import torch
(注意包名为torch
,非pytorch
)。
创建张量:
x = torch.arange(12) # 创建整数行向量 [0, 1, ..., 11]
x = torch.arange(12, dtype=torch.float32) # 指定浮点类型
x.shape # 形状 → torch.Size([12])
x.numel() # 元素总数 → 12
reshape
不改变元素值与总数,支持自动维度计算(-1
):X = x.reshape(3, 4) # 显式指定形状 → 3行4列矩阵
X = x.reshape(-1, 4) # 自动计算行数 → 同(3,4)
torch.zeros((2, 3, 4)) # 形状(2,3,4)的全0张量
torch.ones((2, 3, 4)) # 形状(2,3,4)的全1张量
torch.randn(3, 4) # 形状(3,4),元素服从N(0,1)
torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
# 输出:
tensor([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])
.
核心概念:
按元素运算:要求输入张量形状相同,支持 +
, -
, *
, /
, **
及标量函数(如 exp
)。
张量连结:torch.cat
按指定轴拼接,dim=0
扩展行,dim=1
扩展列。
逻辑运算:生成布尔张量,用于条件筛选或掩码操作。
聚合操作:如 sum()
对张量所有元素求和,常用于数值计算与损失函数。
(1)按元素运算
x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2.0, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y # **运算符是求幂运算
# 输出
(tensor([ 3., 4., 6., 10.]),
tensor([-1., 0., 2., 6.]),
tensor([ 2., 4., 8., 16.]),
tensor([0.5000, 1.0000, 2.0000, 4.0000]),
tensor([ 1., 4., 16., 64.]))
torch.exp(x) # 计算 e^x
# 输出:
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])
(2)张量连结
dim=0
按行,dim=1
按列):X = torch.arange(12, dtype=torch.float32).reshape(3, 4)
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)
# dim=0 结果(6行4列)
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 1., 4., 3.],
[ 1., 2., 3., 4.],
[ 4., 3., 2., 1.]])
# dim=1 结果(3行8列)
tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],
[ 4., 5., 6., 7., 1., 2., 3., 4.],
[ 8., 9., 10., 11., 4., 3., 2., 1.]])
(3)逻辑运算
# 以X == Y为例: 对于每个位置,如果X和Y在该位置相等,则新张量中相应项的值为1。 这意味着逻辑语句X == Y在该位置处为真,否则该位置为0。
X == Y
# 输出
tensor([[False, True, False, True],
[False, False, False, False],
[False, False, False, False]])
(4)求和操作
X.sum()
# 输出:
tensor(66.)
.
原理: 允许不同形状的张量进行按元素运算,自动扩展至相同形状。
通过复制元素扩展张量,使其形状一致;
扩展通常沿长度为1的轴进行(如标量与张量运算);
示例
a = torch.arange(3).reshape((3, 1)) # 形状 (3,1)
b = torch.arange(2).reshape((1, 2)) # 形状 (1,2)
# 即:
a → tensor([[0], [1], [2]])
b → tensor([[0, 1]])
# 广播过程:
# a 沿列(轴1)复制两次 → 形状变为 (3,2)。
# b 沿行(轴0)复制三次 → 形状变为 (3,2)。
# 按元素相加结果:
a + b
# 输出:
tensor([[0, 1],
[1, 2],
[2, 3]])
.
元素访问:张量元素通过索引访问,第一个元素索引0,最后一个元素索引-1。
切片操作:使用范围索引访问多个元素,如X[-1]
获取最后一个元素,X[1:3]
获取第2到第3个元素。
修改元素:直接通过索引赋值修改张量元素,如X[1, 2] = 9
。
批量修改:通过索引组合批量修改元素,如X[0:2, :] = 12
修改前两行所有列的值。
示例代码:
X = torch.tensor([[0., 1., 2., 3.],
[4., 5., 6., 7.],
[8., 9., 10., 11.]])
# 访问最后一个元素
X[-1] → tensor([ 8., 9., 10., 11.])
# 访问第2、3行
X[1:3] → tensor([[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
# 修改单个元素
X[1, 2] = 9
# 结果:
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]])
# 批量修改前两行所有元素
X[0:2, :] = 12
# 结果:
tensor([[12., 12., 12., 12.],
[12., 12., 12., 12.],
[ 8., 9., 10., 11.]])
.
运行一些操作可能会导致为新结果分配内存。 例如,如果我们用Y = X + Y
,我们将取消引用Y
指向的张量,而是指向新分配的内存处的张量。下面介绍一些节省内存的操作:
避免不必要内存分配:使用原地操作减少内存分配,如Y[:] = X + Y
。
原地更新操作:使用X += Y
或X[:] = X + Y
进行原地更新,减少内存开销。
内存地址验证:通过id()
函数验证内存地址是否改变,如检查id(Y) == before
。
示例代码:
# 方法1:通过切片赋值
Z = torch.zeros_like(Y)
Z[:] = X + Y # 不改变Z的内存地址
# 方法2:运算符简写
X += Y # 直接原地更新X,内存地址不变
# 验证内存地址:
before = id(X)
X += Y
id(X) == before → True # 内存地址未变
.
将深度学习框架定义的张量转换为NumPy张量(ndarray
)很容易,反之也同样容易。 torch张量和numpy数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量。
A = X.numpy()
B = torch.tensor(A)
type(A), type(B)
# 输出:
(numpy.ndarray, torch.Tensor)
要将大小为1的张量转换为Python标量,我们可以调用item
函数或Python的内置函数。
a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
# 输出:
(tensor([3.5000]), 3.5, 3.5, 3)
.
深度学习存储和操作数据的主要接口是张量(维数组)。它提供了各种功能,包括基本数学运算、广播、索引、切片、内存节省和转换其他Python对象。
.
声明:资源可能存在第三方来源,若有侵权请联系删除!