【pytorch-01】:张量的创建、转换和拼接

文章目录

  • [1 张量的创建](#1 张量的创建)
    • [1.1 根据已有的数据创建张量](#1.1 根据已有的数据创建张量)
    • [1.2 创建指定形状的张量](#1.2 创建指定形状的张量)
    • [1.3 创建指定类型的张量](#1.3 创建指定类型的张量)
    • [1.4 创建线性张量](#1.4 创建线性张量)
    • [1.5 创建随机张量](#1.5 创建随机张量)
    • [1.6 创建全为0的张量](#1.6 创建全为0的张量)
    • [1,7 创建全为1的张量](#1,7 创建全为1的张量)
    • [1.8 创建全为指定值的张量](#1.8 创建全为指定值的张量)
    • [1.9 张量元素类型转换](#1.9 张量元素类型转换)
  • [2 张量运算](#2 张量运算)
    • [2.1 张量的基本运算](#2.1 张量的基本运算)
    • [2.2 阿达玛积](#2.2 阿达玛积)
    • [2.3 点积运算](#2.3 点积运算)
    • [2.4 指定设备进行运算](#2.4 指定设备进行运算)
  • [3 张量与numpy数组转换](#3 张量与numpy数组转换)
    • [3.1 张量转换为numpy数组](#3.1 张量转换为numpy数组)
    • [3.2 numpy数组转换为张量](#3.2 numpy数组转换为张量)
    • [3.3 提取单值张量](#3.3 提取单值张量)
  • [4 张量的拼接](#4 张量的拼接)
    • [4.1 cat函数使用](#4.1 cat函数使用)
    • [4.2 stack函数使用](#4.2 stack函数使用)

1 张量的创建

python 复制代码
import torch
import numpy as np

1.1 根据已有的数据创建张量

  • 使用torch.tensor()方法,根据已有数据创建张量
  • 创建张量的时候,默认使用原有数据的数据类型
python 复制代码
def test01():

    # 1.1 创建标量
    data = torch.tensor(10)
    print(data)

    # 1.2 使用numpy数组来创建张量
    # 传入numpy数组,张量默认的类型是float64
    data = np.random.randn(2, 3) # float64
    data = torch.tensor(data)
    print(data)

    # 1.3 使用list列表创建张量
    # 传入列表,张量的默认的类型是float32
    data = [[10., 20., 30.], [40., 50., 60.]]
    data = torch.tensor(data)
    print(data)

1.2 创建指定形状的张量

  • torch.Tensor(),可以根据指定的形状创建张量
python 复制代码
def test02():

    # 2.1 创建2行3列的张量
    data = torch.Tensor(2, 3)
    print(data)

    # 2.2 可以创建指定值的张量
    # 注意: 传递列表
    data = torch.Tensor([2, 3])
    print(data)

    data = torch.Tensor([10])
    print(data)

1.3 创建指定类型的张量

  • tensor.IntTensor()
  • tensor.DoubleTensor()
python 复制代码
def test03():

    # 前面创建的张量都是使用默认类型或者元素类型
    # 创建一个 int32 类型的张量
    data = torch.IntTensor(2, 3)
    print(data)

    # torch.ShortTensor(2, 3)  # 表示创建的是 int16 张量
    # torch.LongTensor(2, 3)  # 表示创建的是 int32 张量
    # torch.FloatTensor(2, 3)  # 表示创建的是 float32 张量


    # 注意: 如果创建指定类型的张量,但是传递的数据不匹配,会发生类型转换
    data = torch.IntTensor([2.5, 3.5])
    print(data)

import torch

1.4 创建线性张量

python 复制代码
def test01():

    # 1.1 创建指定步长的张量
    # 第一参数: 开始值
    # 第二参数: 结束值
    # 第三参数: 步长
    data = torch.arange(0, 10, 2)  # tensor([0, 2, 4, 6, 8])
    print(data)

    # 1.2 在指定区间指定元素个数
    # 第一个参数: 开始值
    # 第二个参数: 结束值
    # 第三个参数: 创建元素的个数
    data = torch.linspace(0, 11, 10) # tensor([ 0.0000,  1.2222,  2.4444,  3.6667,  4.8889,  6.1111,  7.3333,  8.5556,
         # 9.7778, 11.0000])
    print(data)

1.5 创建随机张量

python 复制代码
def test02():

    # 固定随机数种子
    # 设置随机种子之后,就可以固定随机数
    # 下面的代码,每次执行,产生的随机数都是一样的
    torch.random.manual_seed(0)
    
    # 2.1 创建随机张量
    # torch.randn - 创建0-1之间的随机张量
    # torch.randint(start,end,(shape)) - 创建整型随机张量
    data = torch.randn(2, 3)
    print(data)

    # 2.2 希望能够固定随机数
    print('随机数种子:', torch.random.initial_seed())

1.6 创建全为0的张量

python 复制代码
def test01():

    # 1.1 创建指定形状全为0的张量
    data = torch.zeros(2, 3)
    print(data)

    # 1.2 根据其他张量的形状去创建全0张量
    data = torch.zeros_like(data)
    print(data)

1,7 创建全为1的张量

python 复制代码
def test02():

    # 2.1 创建指定形状全为1的张量
    data = torch.ones(2, 3)
    print(data)

    # 2.2 根据其他张量的形状去创建全1张量
    data = torch.ones_like(data)
    print(data)

1.8 创建全为指定值的张量

python 复制代码
def test03():

    # 3.1 创建形状为2行3列,值全部为10的张量
    data = torch.full([2, 3], 100)
    print(data)

    # 3.2 创建一个形状和data一样,但是值全部为200的张量
    data = torch.full_like(data, 200)
    print(data)

1.9 张量元素类型转换

python 复制代码
import torch


# 1. type 函数进行转换
def test01():

    data = torch.full([2, 3], 10)
    print(data.dtype)

    # 注意: 返回一个新的类型转换过的张量
    # 不会修改原来的类型,使用type函数的时候通常使用一个新的变量承接新创建的变量
    data = data.type(torch.DoubleTensor)
    print(data.dtype)


# 2. 使用具体类型函数进行转换
def test02():

    data = torch.full([2, 3], 10)
    print(data.dtype)

    # 转换成 float64 类型
    data = data.double()
    print(data.dtype)

    data = data.short()   # 将张量元素转换为 int16 类型
    data = data.int()   # 将张量转换为 int32 类型
    data = data.long()  # 将张量转换为 int64 类型
    data = data.float()  # 将张量转换为 float32

2 张量运算

2.1 张量的基本运算

python 复制代码
# 1. 不修改原数据的计算
# 函数不带下划线,计算完成之后会返回一个新的张量
def test01():

    # 产生指定形状的整型随机张量
    # 第一个参数: 开始值
    # 第二个参数: 结束值
    # 第三个参数: 形状
    data = torch.randint(0, 10, [2, 3])
    print(data)

    # 计算完成之后,会返回一个新的张量
    # 与标量数值进行计算
    data = data.add(10)
    print(data)

    # data.sub()  # 减法
    # data.mul()  # 乘法
    # data.div()  # 除法
    # data.neg()  # 取相反数

# 2. 修改原数据的计算(inplace方式的计算)
def test02():

    data = torch.randint(0, 10, [2, 3])
    print(data)

    # 带下划线的版本的函数直接修改原数据,不需要用新的变量保存
    data.add_(10)
    print(data)

    # data.sub_()  # 减法
    # data.mul_()  # 乘法
    # data.div_()  # 除法
    # data.neg_()  # 取相反数

2.2 阿达玛积

  • 对应位置的元素进行相乘
python 复制代码
import torch


# 1. 使用 mul 函数
# 阿达玛积计算:矩阵对应位置相乘
def test01():

    data1 = torch.tensor([[1, 2], [3, 4]])
    data2 = torch.tensor([[5, 6], [7, 8]])

    data = data1.mul(data2)
    print(data)


# 2. 使用 * 号运算符
def test02():

    data1 = torch.tensor([[1, 2], [3, 4]])
    data2 = torch.tensor([[5, 6], [7, 8]])

    data = data1 * data2
    print(data)

2.3 点积运算

  • 按照矩阵的运算规则进行运算
  • mm() - 必须传入两个二维张量
  • bmm() - 必须传入两个三维张量
python 复制代码
import torch

# 1. 使用 @ 运算符
# 按照矩阵运算的规则进行运算 - 点积运算
def test01():

    # 形状为: 3行2列
    data1 = torch.tensor([[1, 2],
                          [3, 4],
                          [5, 6]])
    # 形状为: 2行2列
    data2 = torch.tensor([[5, 6],
                          [7, 8]])
    data = data1 @ data2
    print(data)


# 2. 使用 mm 函数
# 两个运算的矩阵是必须是二维的
def test02():

    # 要求输入的张量形状都是二维
    # 形状为: 3行2列
    data1 = torch.tensor([[1, 2],
                          [3, 4],
                          [5, 6]])
    # 形状为: 2行2列
    data2 = torch.tensor([[5, 6],
                          [7, 8]])

    data = torch.mm(data1, data2)
    print(data)


# 3. 使用 bmm 函数
# 传入的两个矩阵必须是三维的
def test03():

    # 第一个维度: 表示批次
    # 第二个维度: 多少行
    # 第三个维度: 多少列
    data1 = torch.randn(3, 4, 5)
    data2 = torch.randn(3, 5, 8)
    
    data = torch.bmm(data1, data2)
    print(data.shape)


# 4. 使用 matmul 函数

def test04():

    # 对二维进行计算
    data1 = torch.randn(4, 5)
    data2 = torch.randn(5, 8)
    print(torch.matmul(data1, data2).shape)
    
    # 对三维进行计算
    data1 = torch.randn(3, 4, 5)
    data2 = torch.randn(3, 5, 8)
    print(torch.matmul(data1, data2).shape)

    # 也可以进行计算
    data1 = torch.randn(3, 4, 5)
    data2 = torch.randn(5, 8)
    print(torch.matmul(data1, data2).shape)

2.4 指定设备进行运算

  • 张量运算可以运行在CPU中,也可以运算在GPU当中
  • 创建张量的时候,可以通过device参数指定设备
  • 使用data.cuda()方法,指定GPU作为运算设备
  • 使用data.to(设备名称),指定运算设备
  • 在不同设备上的张量是不能进行运算的
python 复制代码
import torch

# 默认创建在CPU中的内存中
# 1. 使用 cuda 方法
def test01():

    data = torch.tensor([10, 20, 30])
    print('存储设备:', data.device)

    # 将张量移动到 GPU 设备上
    # cuda就表示GPU
    data = data.cuda()
    print('存储设备:', data.device)

    # 将张量从GPU再移动到CPU
    data = data.cpu()
    print('存储设备:', data.device)


# 2. 直接将张量创建在指定设备上
# 创建张量的时候,通过device参数指定张量创建的位置
def test02():

    data = torch.tensor([10, 20, 30], device='cuda:0')
    print('存储设备:', data.device)

    # 把张量移动到cpu设备上
    data = data.cpu()
    print('存储设备:', data.device)


# 3. 使用 to 方法
def test03():

    data = torch.tensor([10, 20, 30])
    print('存储设备:', data.device)

    # 使用 to 方法移动张量到指定设备
    data = data.to('cuda:0')
    print('存储设备:', data.device)



# 4. 注意: 存储在不同设备上的张量不能够直接运算
def test04():

    data1 = torch.tensor([10, 20, 30])
    data2 = torch.tensor([10, 20, 30], device='cuda:0')

    # RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
    # 下面代码会报错

    # 如果你的电脑上安装 pytorch 不是 gpu 版本的,或者电脑本身没有 gpu (nvidia)设备环境
    # 否则下面的调用 cuda 函数的代码会报错
    data1 = data1.cuda()

    data = data1 + data2
    print(data)

3 张量与numpy数组转换

3.1 张量转换为numpy数组

  • 使用data.numpy()函数,可以将张量转化为numpy数组,但是两者共享内存,一个变化,另外一个也发生变化
  • 如果不想让两者共享内存,可以使用copy()进行拷贝
python 复制代码
import torch


# 1. 张量转换为numpy数组
def test01():

    data_tensor = torch.tensor([2, 3, 4])
    # 将张量转换为numpy数组
    # 转化为numpy之后的得到的ndarray对象和原tensor对象共享内存
    # 如果修改了其中一个值,另外一个也会改变
    data_numpy = data_tensor.numpy()

    print(type(data_tensor))
    print(type(data_numpy))

    print(data_tensor)
    print(data_numpy)


# 2. 张量和numpy数组共享内存
def test02():

    data_tensor = torch.tensor([2, 3, 4])
    data_numpy = data_tensor.numpy()

    # 修改张量元素的值,看看numpy数组是否会发生变化?会发生变化
    # data_tensor[0] = 100
    # print(data_tensor)
    # print(data_numpy)

    # 修改numpy数组元素的值,看看张量是否会发生变化?会发生变化
    data_numpy[0] = 100
    print(data_tensor)
    print(data_numpy)


# 3. 使用copy函数实现不共享内存
def test03():

    data_tensor = torch.tensor([2, 3, 4])
    # 此处, 发生了类型转换,可以使用拷贝函数产生新的数据,避免共享内存
    data_numpy = data_tensor.numpy().copy()

    # 修改张量元素的值,看看numpy数组是否会发生变化?没有发生变化
    # data_tensor[0] = 100
    # print(data_tensor)
    # print(data_numpy)

    # 修改numpy数组元素的值,看看张量是否会发生变化?没有发生变化
    data_numpy[0] = 100
    print(data_tensor)
    print(data_numpy)

3.2 numpy数组转换为张量

  • 采用torch.from_numpy(ndarray)函数,共享内存
  • 使用torch.tensor(ndarray) - 不共享内存
python 复制代码
import torch
import numpy as np


# 1. from_numpy 函数的用法
# 默认进行的是前拷贝
def test01():

    data_numpy = np.array([2, 3, 4])
    # 张量是没有copy()函数的
    # 先将ndarray进行拷贝,转换为张量
    data_tensor = torch.from_numpy(data_numpy.copy())

    print(type(data_numpy))
    print(type(data_tensor))

    # 默认共享内存
    data_numpy[0] = 100
    # data_tensor[0] = 100
    print(data_numpy)
    print(data_tensor)


# 2. torch.tensor 函数的用法
# 默认情况下是不进行共享内存的
# 默认情况下进行深拷贝
def test02():

    data_numpy = np.array([2, 3, 4])
    data_tensor = torch.tensor(data_numpy)

    # 默认不共享内存
    # data_numpy[0] = 100
    data_tensor[0] = 100
    print(data_numpy)
    print(data_tensor)

3.3 提取单值张量

  • 单值张量虽然只有一个值,但是仍然为张量类型
python 复制代码
import torch


def test():

    t1 = torch.tensor(30)
    t2 = torch.tensor([30])
    t3 = torch.tensor([[30]])

    print(t1.shape)
    print(t2.shape)
    print(t3.shape)

    print(t1.item())
    print(t2.item())
    print(t3.item())

    # 注意: 张量中只有一个元素,如果有多个元素的话,使用 item 函数可能就会报错
    # ValueError: only one element tensors can be converted to Python scalars
    # t4 = torch.tensor([30, 40])
    # print(t4.item())

4 张量的拼接

4.1 cat函数使用

python 复制代码
import torch


def test():

    # 固定随机数种子
    torch.manual_seed(0)

    data1 = torch.randint(0, 10, [3, 4, 5])
    data2 = torch.randint(0, 10, [3, 4, 5])

    print(data1.shape)
    print(data2.shape)


    # 1. 按照0维度进行拼接
    new_data = torch.cat([data1, data2], dim=0)
    print(new_data.shape) # [6,4,5]

    # 2. 按照1维度进行拼接
    new_data = torch.cat([data1, data2], dim=1)
    print(new_data.shape) # [3,8,5]

    # 3. 按照2维度进行拼接
    new_data = torch.cat([data1, data2], dim=2)
    print(new_data.shape) # [3,4,10]

    # 注意: dim 必须保证是有效的
    # new_data = torch.cat([data1, data2], dim=3)
    # print(new_data.shape)

4.2 stack函数使用

  • 按照一定维度,从两个张量中各自取一个元素,组合成新的元素,形成新的张量,会改变原有张量的维度
python 复制代码
import torch


def test():

    # stack()
    # 按照一定维度,从两个张量中各自取一个元素,组合成新的元素,形成新的张量
    # 会改变原有张量的维度

    torch.manual_seed(0)
    data1 = torch.randint(0, 10, [2, 3])
    data2 = torch.randint(0, 10, [2, 3])

    print(data1)
    print(data2)
    print('-' * 30)

    # 将两个张量 stack 起来,像 cat 一样指定维度
    # 1. 按照0维度进行叠加
    # 将两个二维张量作为元素进行堆叠,变为一个三维,变为两个两行三列 (2,2,3)
    new_data = torch.stack([data1, data2], dim=0)
    print(new_data.shape)
    print(new_data)
    print('-' * 30)

    # 2. 按照1维度进行叠加
    # 将二维张量中的第一层中的元素进行拼接
    # 这里是两个一维向量进行拼接
    new_data = torch.stack([data1, data2], dim=1)
    print(new_data.shape)
    print(new_data)
    print('-' * 30)

    # 3. 按照2维度进行叠加
    # 将二维张量中,按照元素进行拼接
    new_data = torch.stack([data1, data2], dim=2)
    print(new_data.shape)
    print(new_data)
    print('-' * 30)
相关推荐
2401_873544921 分钟前
使用Python进行PDF文件的处理与操作
jvm·数据库·python
CareyWYR9 分钟前
每周AI论文速递(260323-260327)
人工智能
程序员小远17 分钟前
软件测试常见Bug清单
自动化测试·软件测试·python·功能测试·测试工具·测试用例·bug
guoji778831 分钟前
安全与对齐的深层博弈:Gemini 3.1 Pro 安全护栏与对抗测试深度拆解
人工智能·安全
实在智能RPA39 分钟前
实在 Agent 和通用大模型有什么不一样?深度拆解 AI Agent 的感知、决策与执行逻辑
人工智能·ai
独隅44 分钟前
PyTorch 模型部署的 Docker 配置与性能调优深入指南
人工智能·pytorch·docker
lihuayong1 小时前
OpenClaw 系统提示词
人工智能·prompt·提示词·openclaw
黑客说1 小时前
AI驱动剧情,解锁无限可能——AI游戏发展解析
人工智能·游戏
踩着两条虫1 小时前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava