深度学习基础:PyTorch张量创建与操作详解
深度学习基础:PyTorch张量创建与操作详解
前言
深度学习作为人工智能领域的重要分支,在图像识别、自然语言处理、语音识别等领域取得了突破性进展。PyTorch作为目前最受欢迎的深度学习框架之一,以其动态计算图和简洁的API设计深受开发者喜爱。本文将详细介绍PyTorch中张量(Tensor)的创建与基本操作。
一、张量基础概念
张量(Tensor)是PyTorch中最基本的数据结构,可以理解为多维数组。在深度学习中,我们通常使用张量来表示:
- 0维张量:标量(如单个数字)
- 1维张量:向量(如特征向量)
- 2维张量:矩阵(如权重矩阵)
- 3维及以上:高维数组(如图像数据、序列数据等)
二、张量创建方法详解
2.1 使用tensor()创建张量
torch.tensor()
是最常用的张量创建方法,支持直接传入数据:
import torch
import numpy as npdef dm01_create_tensor():# 创建标量张量data = torch.tensor(3) # 3:标量print('data-->', data)print('shape-->', data.shape)print('type-->', data.data.dtype)# 使用一维向量创建张量data = torch.tensor([3, 4, 1])print('data-->', data)print('shape-->', data.shape)print('type-->', data.data.dtype)# 使用二维数据创建张量data = torch.tensor([[3, 4, 1, 2],[3, 4, 1, 5]])print("data-->", data, data.shape, data.dtype)# shape->[2,4]->2行4列# 2行:2个样本# 4列:4个特征# 测试numpy转换为张量data = np.random.randn(2, 4)data = torch.tensor(data)print("data-->", data)
重要说明:
shape
属性表示张量的形状dtype
表示数据类型,如int64、float32等- 二维张量在深度学习中通常表示:行数为样本数,列数为特征数
2.2 使用Tensor()创建张量
torch.Tensor()
既支持数据创建,也支持形状创建:
def dm02_create_Tensor():# 根据形状创建张量:2,3data = torch.Tensor(2, 3)data = torch.Tensor([[3, 4]])# 根据数值来创建变量data = torch.Tensor(3) # 创建包含3个元素的张量print("data:", data)data1 = torch.Tensor(2, 3)print("data1:", data1)# 小结:tensor和Tensor的区别# tensor: 只支持数据(数值),一般就用这种方式# Tensor: 既支持数据(数值),还支持形状,了解即可
2.3 使用特定数据类型创建张量
PyTorch提供了多种数据类型创建方法:
def dm03_create_IntTensor():# 根据形状创建data = torch.IntTensor(3, 4)print("data-->", data, data.dtype)# 根据数值创建data = torch.IntTensor([3, 4])print("data-->", data, data.dtype)# 尝试小数,会舍弃掉小数部分data = torch.IntTensor([3.5, 4.6, 5.8])print("data-->", data, data.dtype)# 使用其他数据类型data = torch.FloatTensor([3.5, 4.6, 5.8])data = torch.DoubleTensor([3.5, 4.6, 5.8])print("data-->", data)
2.4 创建线性张量
arange()方法
def dm04_create_tensor_arange_linspace():# arange(start, end, step),包括start,不包括enddata = torch.arange(0, 10, 1)print("data-->", data)data = torch.arange(0, 10) # 默认步长为1print("data-->", data)data = torch.arange(0, 10, 2)print("data-->", data)
linspace()方法
# linspace(start, end, steps),包左且包右data = torch.linspace(3, 10, steps=5)data = torch.linspace(0, 10, steps=11)print("data-->", data)
区别:
arange
:指定步长,包左不包右linspace
:指定步数,包左且包右
2.5 创建随机张量
def dm05_crate_tensor_randn():# 设置随机种子,确保结果可重现torch.manual_seed(2)torch.random.manual_seed(2) # 上面两行代码等价# 创建2行3列的随机张量data = torch.randn(2, 3)print(data)# 查看随机种子print(torch.initial_seed())print(torch.random.initial_seed())
2.6 创建全0和全1张量
def dm06_create_tensor_zero_one():# 创建全1张量data = torch.ones(3, 4)print("data-->", data)print("shape-->", data.shape) # [3,4]print("size-->", data.size()) # [3,4]# 结论:在PyTorch中,shape(属性)和size(方法)是一样的# 使用ones_like创建张量,根据data的形状创建data1 = torch.ones_like(data)print("data1-->", data1)# 创建全0张量data = torch.zeros(2, 3)print("data-->", data)data1 = torch.zeros_like(data)print("data1-->", data1)
三、张量类型转换
3.1 张量数据类型转换
def dm07_type_cast():data = torch.full([2, 3], 10)print("data-->", data, data.dtype)# 方式一:type(torch.XXXTensor)data1 = data.type(torch.DoubleTensor)data1 = data.type(torch.FloatTensor)print("data1-->", data1, data1.dtype)# 方式二:xxx()方法data2 = data.double()print("data2-->", data2, data2.dtype)
3.2 张量与NumPy互转
张量转NumPy
def dm01_tensor2numpy():data_tensor = torch.tensor([2, 3, 4])print("data_tensor1-->", data_tensor)# 转换为numpy(深拷贝)data_numpy = data_tensor.numpy().copy()print("data_numpy1-->", data_numpy)# 修改numpy的值data_numpy[0] = 200print("data_numpy2-->", data_numpy)print("data_tensor2-->", data_tensor) # 原张量不受影响# 使用np.array()转换data_numpy = np.array(data_tensor)print("data_numpy-->", data_numpy)
NumPy转张量
def dm02_numpy2tensor():data_numpy = np.array([2, 3, 4])print("data_numpy1-->", data_numpy)# 方法一:使用torch.from_numpy()data_tensor = torch.from_numpy(data_numpy.copy())print("data_tensor1-->", data_tensor)# 方法二:使用torch.tensor()data_tensor = torch.tensor(data_numpy)print("data_tensor1-->", data_tensor)
3.3 标量张量转数字
def dm03_tensor2number():# 0维数组(标量张量)data = torch.tensor(3)print(data)# 1维数组(向量)data = torch.tensor([3])print(data)# 2维数组(矩阵)data = torch.tensor([[3]])print(data)# 转换为纯数字data = torch.tensor([30])print(data.item()) # 只能转换包含单个元素的张量data = torch.tensor(30)print(data.item())
四、张量基本运算
4.1 基本数学运算
def dm01_basic_calc():torch.manual_seed(2)data = torch.randint(0, 10, (3, 2))print("data-->", data)# 广播机制:要么维度相同,要么维度为1# 加法(带下划线会修改原数据)data2 = data.add_(1)print("data2-->", data2)# 其他运算print('sub-->', data.sub(1)) # 减法print('mul-->', data.mul(2)) # 乘法print('div-->', data.div(2)) # 除法print('neg-->', data.neg()) # 取负号
4.2 点乘运算
def dm02_point_mul():torch.manual_seed(2)data = torch.randint(0, 10, (3, 2))print("data-->", data)# 点乘data1 = data * 3print("data1-->", data1)data2 = data.mul(3)print("data2-->", data2)# 矩阵点乘(需要满足广播规则)matrix_x = torch.tensor([[3, 3]])data3 = data * matrix_xprint("data3-->", data3)
4.3 矩阵乘法
def dm03_matrix_mul():data1 = torch.tensor([[1, 2], [3, 4], [5, 6]])data2 = torch.tensor([[5, 6], [7, 8]])print("data1-->", data1.shape)print("data2-->", data2.shape)# 矩阵乘法print("data1 @ data2-->", data1 @ data2)print("data1 @ data2-->", data1.matmul(data2))
五、重要概念总结
5.1 广播机制
在PyTorch中,两个张量进行运算时,如果形状不同,会尝试进行广播:
- 要么维度相同
- 要么其中一个维度为1
5.2 内存管理
- 带下划线的方法(如
add_()
)会修改原张量 - 不带下划线的方法会创建新的张量
- 使用
.copy()
进行深拷贝,避免数据共享
5.3 数据类型选择
int64
:长整型,适合索引float32
:单精度浮点,常用float64
:双精度浮点,精度更高但占用内存更多
六、实践建议
- 优先使用
torch.tensor()
:这是最常用和推荐的方式 - 注意数据类型:根据计算需求选择合适的精度
- 理解广播机制:这是张量运算的基础
- 善用随机种子:确保实验的可重现性
- 注意内存管理:避免不必要的数据复制
结语
本文详细介绍了PyTorch中张量的创建方法和基本操作,这些是深度学习的基础。掌握这些内容后,我们就可以开始构建更复杂的神经网络模型了。在下一篇文章中,我们将学习张量的索引操作、形状变换等更高级的操作。
希望这篇文章对您的深度学习学习有所帮助!如果您有任何问题或建议,欢迎在评论区留言讨论。
关键词: PyTorch、张量、深度学习、tensor、numpy、广播机制、数据类型转换