文章目录
- 前言
- 一、张量的创建
- 二、张量数值计算
- 三、张量和Numpy转换
- 四、张量拼接操作
- 五、张量索引操作
- 六、张量形状操作
- 七、张量运算函数
- 八、自动微分模块
- 九、手写线性回归模型
- 十、PyTorch 框架实现线性回归
前言
如果你是一名深度学习的开发者,正在寻找一篇能让你从 PyTorch 的基本操作入门,逐步深入到实战的文章,那么恭喜你找到了。作为目前最受欢迎的深度学习框架之一,PyTorch 的灵活性和强大的动态计算图功能,使它成为许多科研工作者和工业界工程师的首选。然而,入门 PyTorch 并不总是那么轻松——文档虽然详尽,但缺乏实战引导;教程虽多,但零散且容易遗漏关键点。
这篇文章旨在解决这些问题,它并不是“走马观花”地列出 PyTorch 的功能,而是一步步带你从基础操作到完整案例,真正学会如何用 PyTorch 做事。文章全篇超过 4 万字,涵盖 PyTorch 的方方面面,从张量创建到自动微分,从张量操作到矩阵运算,再到完整的线性回归实现,几乎囊括了 PyTorch 入门所需的一切。
这不是一篇只教你“怎么做”的文章,而是一篇教你“为什么这样做”的文章。你不仅会学到 PyTorch 的用法,还能理解它背后的逻辑和设计哲学。每一个代码示例都配有详细的讲解,输出结果一目了然,让你少走弯路。更重要的是,通过实战案例的贯穿,你能快速掌握如何将 PyTorch 应用于实际项目中。
本文共分为 10 个章节,既有对 PyTorch 基础功能的全面讲解,也包含两个完整的实战案例——从零手写线性回归,以及利用 PyTorch 框架高效实现线性回归。无论是初学者还是有经验的开发者,都能在其中找到适合自己的内容。
一、张量的创建
1.1 基本创建方式
1.1.1 常用方法
torch.tensor
:根据指定数据创建张量torch.Tensor
:根据形状创建张量,也可用于根据指定数据创建张量- 类型指定方法:
torch.IntTensor
、torch.FloatTensor
、torch.DoubleTensor
等用于创建特定数据类型的张量
1.1.2 示例代码
import torch
import numpy as np
# 1. 根据已有数据创建张量
def example01():
# 1. 创建标量张量
data = torch.tensor(25)
print(data)
# 2. 通过 numpy 数组创建张量,指定数据类型
data = np.random.randn(3, 4)
data = torch.tensor(data, dtype=torch.float64)
print(data)
# 3. 通过列表创建张量,使用默认元素类型 float32
data = [[5., 15., 25.], [35., 45., 55.]]
data = torch.tensor(data)
print(data)
# 2. 创建指定形状的张量
def example02():
# 1. 创建3行2列的张量,默认 dtype 为 float32
data = torch.Tensor(3, 2)
print(data)
# 2. 注意:传入列表会创建包含指定元素的张量
data = torch.Tensor([7])
print(data)
data = torch.Tensor([12, 22])
print(data)
# 3. 使用具体类型的张量
def example03():
# 1. 创建3行2列的 int32 张量
data = torch.IntTensor(3, 2)
print(data)
# 2. 如果元素类型不正确,会进行类型转换
data = torch.IntTensor([7.8, 8.6])
print(data)
# 3. 其他类型的张量
data = torch.ShortTensor() # int16
data = torch.LongTensor() # int64
data = torch.FloatTensor() # float32
data = torch.DoubleTensor() # float64
if __name__ == '__main__':
example01()
example02()
example03()
1.1.3 输出结果
tensor(25)
tensor([[ 0.3271, 1.1465, -0.7521, 0.6235],
[-1.0832, 0.2256, 0.4095, 0.5767],
[-0.6517, -0.7845, 1.2476, 0.2943]], dtype=torch.float64)
tensor([[ 5., 15., 25.],
[35., 45., 55.]])
tensor([[0., 0.],
[0., 0.],
[0., 0.]])
tensor([7.])
tensor([12., 22.])
tensor([[0, 0],
[0, 0],
[0, 0]], dtype=torch.int32)
tensor([7, 8], dtype=torch.int32)
1.2 创建线性和随机张量
1.2.1 常用方法
- 线性张量:使用
torch.arange
和torch.linspace
创建 - 随机张量:使用
torch.randn
创建 - 随机种子:使用
torch.random.manual_seed
设置
1.2.2 示例代码
import torch
# 1. 创建线性空间的张量
def example01():
# 1. 按指定步长生成元素 [start, end, step)
data = torch.arange(2, 20, 4)
print(data)
# 2. 按指定元素个数生成张量
data = torch.linspace(1, 10, 5)
print(data)
# 2. 创建随机张量
def example02():
# 1. 创建随机张量
data = torch.randn(4, 3) # 生成4行3列的张量
print(data)
# 2. 设置随机种子
print('随机数种子:', torch.random.initial_seed())
torch.random.manual_seed(42)
print('随机数种子:', torch.random.initial_seed())
if __name__ == '__main__':
example01()
example02()
1.2.3 输出结果
tensor([ 2, 6, 10, 14, 18])
tensor([ 1.0000, 3.2500, 5.5000, 7.7500, 10.0000])
tensor([[ 0.1278, -0.7893, 0.5731],
[-0.3411, 1.2744, -0.2339],
[-0.8966, -0.4226, 0.7237],
[ 0.5841, -0.0851, -0.2972]])
随机数种子: 4508475192273306739
随机数种子: 42
1.3 创建 0 和 1 张量
1.3.1 常用方法
- 全0张量:
torch.zeros
和torch.zeros_like
- 全1张量:
torch.ones
和torch.ones_like
- 指定值张量:
torch.full
和torch.full_like
1.3.2 示例代码
import torch
# 1. 创建全0张量
def example01():
# 1. 创建指定形状的全0张量
data = torch.zeros(3, 4)
print(data)
# 2. 根据已有张量的形状创建全0张量
data = torch.zeros_like(data)
print(data)
# 2. 创建全1张量
def example02():
# 1. 创建指定形状的全1张量
data = torch.ones(4, 3)
print(data)
# 2. 根据已有张量的形状创建全1张量
data = torch.ones_like(data)
print(data)
# 3. 创建指定值的张量
def example03():
# 1. 创建指定形状指定值的张量
data = torch.full([3, 3], 9)
print(data)
# 2. 根据已有张量的形状创建指定值的张量
data = torch.full_like(data, 15)
print(data)
if __name__ == '__main__':
example01()
example02()
example03()
1.3.3 输出结果
tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
tensor([[ 9, 9, 9],
[ 9, 9, 9],
[ 9, 9, 9]])
tensor([[15, 15, 15],
[15, 15, 15],
[15, 15, 15]])
1.4 张量元素类型转换
1.4.1 常用方法
- 方法 1:使用
tensor.type(torch.Type)
- 方法 2:使用
tensor.double()
等方法
1.4.2 示例代码
import torch
def example():
data = torch.full([2, 2], 5)
print(data.dtype)
# 方法 1:转换为 float64 类型
data = data.type(torch.DoubleTensor)
print(data.dtype)
# 方法 2:使用 double() 转换类型
data = data.double()
print(data.dtype)
if __name__ == '__main__':
example()
1.4.3 输出结果
torch.int64
torch.float64
torch.float64
1.5 小结
- 创建张量
torch.tensor
:根据数据创建张量torch.Tensor
:根据形状或数据创建张量- 类型指定方法:
torch.IntTensor
、torch.FloatTensor
等
- 线性与随机张量
torch.arange
和torch.linspace
:创建线性张量torch.randn
:创建随机张量torch.random.manual_seed
:设置随机种子
- 全0/1与指定值张量
torch.zeros
、torch.ones
、torch.full
- 类似方法:
torch.zeros_like
、torch.ones_like
、torch.full_like
- 张量类型转换
tensor.type()
和tensor.double()
等方法
二、张量数值计算
PyTorch 中的张量基本运算函数包括 add
、sub
、mul
、div
、neg
等。对于这些操作,带下划线的版本(如 add_
、sub_
等)会直接修改原张量。
2.1 张量基本运算
2.1.1 示例代码
import torch
def example01():
data = torch.randint(1, 20, [2, 3])
print("原始数据:\n", data)
print('-' * 50)
# 1. 不修改原数据
new_data = data.add(5) # 等价于 new_data = data + 5
print("加法(不修改原数据):\n", new_data)
print('-' * 50)
# 2. 修改原数据
data.add_(5) # 等价于 data += 5
print("加法(修改原数据):\n", data)
print('-' * 50)
# 3. 其他操作
print("减法:\n", data.sub(10)) # 减法
print("乘法:\n", data.mul(2)) # 乘法
print("除法:\n", data.div(3)) # 除法
print("取反:\n", data.neg()) # 取反
if __name__ == '__main__':
example01()
2.1.2 输出结果
原始数据:
tensor([[14, 7, 10],
[19, 16, 6]])
--------------------------------------------------
加法(不修改原数据):
tensor([[19, 12, 15],
[24, 21, 11]])
--------------------------------------------------
加法(修改原数据):
tensor([[19, 12, 15],
[24, 21, 11]])
--------------------------------------------------
减法:
tensor([[ 9, 2, 5],
[14, 11, 1]])
乘法:
tensor([[38, 24, 30],
[48, 42, 22]])
除法:
tensor([[6.3333, 4.0000, 5.0000],
[8.0000, 7.0000, 3.6667]])
取反:
tensor([[-19, -12, -15],
[-24, -21, -11]])
2.2 矩阵的点乘
矩阵点乘指的是对应位置元素的逐个相乘。PyTorch 提供了两种方式完成点乘:torch.mul
或使用运算符 *
。
2.2.1 示例代码
import torch
def example02():
data1 = torch.tensor([[2, 3], [4, 5]])
data2 = torch.tensor([[6, 7], [8, 9]])
# 第一种方式:torch.mul
result1 = torch.mul(data1, data2)
print("矩阵点乘(方式1):\n", result1)
print('-' * 50)
# 第二种方式:使用 *
result2 = data1 * data2
print("矩阵点乘(方式2):\n", result2)
if __name__ == '__main__':
example02()
2.2.2 输出结果
矩阵点乘(方式1):
tensor([[12, 21],
[32, 45]])
--------------------------------------------------
矩阵点乘(方式2):
tensor([[12, 21],
[32, 45]])
2.3 矩阵乘积运算
矩阵乘积运算要求第一个矩阵形状为 (n, m)
,第二个矩阵形状为 (m, p)
,结果形状为 (n, p)
。PyTorch 提供了以下操作:
- 运算符
@
:直接进行矩阵乘积运算 torch.mm
:用于二维矩阵的乘积torch.bmm
:用于三维张量的批量矩阵乘积torch.matmul
:通用矩阵乘积函数,适用于任意维度张量
2.3.1 示例代码
import torch
# 1. 矩阵乘积运算
def example03():
data1 = torch.tensor([[2, 3], [4, 5], [6, 7]])
data2 = torch.tensor([[8, 9], [10, 11]])
# 第一种方式:运算符 @
result1 = data1 @ data2
print("矩阵乘积(方式1):\n", result1)
print('-' * 50)
# 第二种方式:torch.mm
result2 = torch.mm(data1, data2)
print("矩阵乘积(方式2):\n", result2)
print('-' * 50)
# 第三种方式:torch.matmul
result3 = torch.matmul(data1, data2)
print("矩阵乘积(方式3):\n", result3)
# 2. torch.mm 和 torch.matmul 的区别
def example04():
print("torch.matmul 的更多使用:")
print("矩阵形状1:", torch.matmul(torch.randn(3, 4, 5), torch.randn(5, 6)).shape)
print("矩阵形状2:", torch.matmul(torch.randn(5, 6), torch.randn(3, 4, 5)).shape)
# 3. torch.bmm 用法
def example05():
# 批量矩阵乘积运算
data1 = torch.randn(4, 3, 2) # 4个3x2矩阵
data2 = torch.randn(4, 2, 5) # 4个2x5矩阵
result = torch.bmm(data1, data2)
print("批量矩阵乘积结果形状:", result.shape)
if __name__ == '__main__':
example03()
example04()
example05()
2.3.2 输出结果
矩阵乘积(方式1):
tensor([[46, 51],
[84, 93],
[122, 135]])
--------------------------------------------------
矩阵乘积(方式2):
tensor([[46, 51],
[84, 93],
[122, 135]])
--------------------------------------------------
矩阵乘积(方式3):
tensor([[46, 51],
[84, 93],
[122, 135]])
--------------------------------------------------
torch.matmul 的更多使用:
矩阵形状1: torch.Size([3, 4, 6])
矩阵形状2: torch.Size([3, 5, 5])
批量矩阵乘积结果形状: torch.Size([4, 3, 5])
2.4 小结
-
张量基本运算
- 基本运算函数:
add
、sub
、mul
、div
、neg
- In-place 运算函数:
add_
、sub_
、mul_
、div_
、neg_
- 基本运算函数:
-
点乘运算
- 使用
torch.mul
或*
实现矩阵点乘
- 使用
-
矩阵乘积运算
- 运算符
@
:矩阵乘积运算 torch.mm
:二维矩阵乘积torch.matmul
:任意维度矩阵乘积torch.bmm
:三维张量批量矩阵乘积
- 运算符
三、张量和Numpy转换
3.1 张量转换为 NumPy 数组
使用 Tensor.numpy
函数可以将张量转换为 ndarray
数组。默认情况下,两者共享内存,修改其中一个会影响另一个。如果不希望共享内存,可以使用深拷贝。
3.1.1 示例代码
import torch
# 1. 将张量转换为 NumPy 数组
def example01():
data_tensor = torch.tensor([5, 6, 7])
# 使用张量对象中的 numpy 函数进行转换
data_numpy = data_tensor.numpy()
print("张量类型:", type(data_tensor))
print("NumPy 类型:", type(data_numpy))
# 注意: data_tensor 和 data_numpy 共享内存
# 修改 NumPy 数组,张量也会改变
data_numpy[0] = 99
print("修改后的张量:", data_tensor)
print("修改后的 NumPy 数组:", data_numpy)
# 2. 深拷贝避免共享内存
def example02():
data_tensor = torch.tensor([8, 9, 10])
# 深拷贝,避免共享内存
data_numpy = data_tensor.numpy().copy()
print("张量类型:", type(data_tensor))
print("NumPy 类型:", type(data_numpy))
# 修改 NumPy 数组,不会影响张量
data_numpy[0] = 88
print("原张量:", data_tensor)
print("修改后的 NumPy 数组:", data_numpy)
if __name__ == '__main__':
example01()
example02()
3.1.2 输出结果
张量类型: <class 'torch.Tensor'>
NumPy 类型: <class 'numpy.ndarray'>
修改后的张量: tensor([99
标签:tensor,示例,torch,爆肝,张量,PyTorch,print,data
From: https://blog.csdn.net/Kiradzy/article/details/144952116