深度学习基础:PyTorch张量创建与操作详解

前言

深度学习作为人工智能领域的重要分支,在图像识别、自然语言处理、语音识别等领域取得了突破性进展。PyTorch作为目前最受欢迎的深度学习框架之一,以其动态计算图和简洁的API设计深受开发者喜爱。本文将详细介绍PyTorch中张量(Tensor)的创建与基本操作。

一、张量基础概念

张量(Tensor)是PyTorch中最基本的数据结构,可以理解为多维数组。在深度学习中,我们通常使用张量来表示:

  • 0维张量:标量(如单个数字)
  • 1维张量:向量(如特征向量)
  • 2维张量:矩阵(如权重矩阵)
  • 3维及以上:高维数组(如图像数据、序列数据等)

二、张量创建方法详解

2.1 使用tensor()创建张量

torch.tensor()是最常用的张量创建方法,支持直接传入数据:

import torch
import numpy as np

def 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,3
    data = 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,不包括end
    data = torch.arange(0, 10, 1)
    print("data-->", data)
    data = torch.arange(0, 10)  # 默认步长为1
    print("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] = 200
    print("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 * 3
    print("data1-->", data1)
    
    data2 = data.mul(3)
    print("data2-->", data2)
    
    # 矩阵点乘(需要满足广播规则)
    matrix_x = torch.tensor([[3, 3]])
    data3 = data * matrix_x
    print("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:双精度浮点,精度更高但占用内存更多

六、实践建议

  1. 优先使用torch.tensor():这是最常用和推荐的方式
  2. 注意数据类型:根据计算需求选择合适的精度
  3. 理解广播机制:这是张量运算的基础
  4. 善用随机种子:确保实验的可重现性
  5. 注意内存管理:避免不必要的数据复制

结语

本文详细介绍了PyTorch中张量的创建方法和基本操作,这些是深度学习的基础。掌握这些内容后,我们就可以开始构建更复杂的神经网络模型了。在下一篇文章中,我们将学习张量的索引操作、形状变换等更高级的操作。

希望这篇文章对您的深度学习学习有所帮助!如果您有任何问题或建议,欢迎在评论区留言讨论。


关键词: PyTorch、张量、深度学习、tensor、numpy、广播机制、数据类型转换

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐