Pytorch最最适合研究生的入门教程,Q1 Tensor的初认识

Pytorch最最适合研究生的入门教程

Q1 Tensor初认识

1.1 认识张量Tensor

Tensor是Pytorch中数据单元的最小形式,本质上可以理解为多维矩阵数组
以下为一个简单tensor的创建

import torch

tensor_a = torch.Tensor([1, 2, 3])
tensor_b = torch.tensor([1, 2, 3])
print(tensor_a)
print(tensor_b)

tensor([1., 2., 3.])
tensor([1, 2, 3])

torch.Tensor(类创建): 最常用的创建张量的方式,可以将任意可迭代对象转换为张量
torch.tensor(API创建): 也是创建张量的方式,但用得不多
而Tensor还有个最本质的属性,Shape(形状)

print(tensor_a.shape)
print(tensor_b.shape)

torch.Size([3])
torch.Size([3])

Tensor的形状将以torch.Size数组的形式给出
我们可以通过索引去获取某个维度的长度,如获取第0维tensor_a[0]
相同的,我们也可以通过索引去获取Tensor中指定索引的数据/张量

形状含义
[16, 128]一组16个128维度的向量
[8, 16, 128]一组8个序列,每个序列有16个时间步,每个时间步为128维
[8, 3, 64, 64]一组8个三通道64x64大小的图像

常用张量大多以以上形式出现,且张量的第0维一般是批大小,batch

work

任意方式创建一个张量,分别尝试使用以下数据创建,看看会发生什么

a = [1, 5, 10, 15, 20]
b = range(10)
d = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
e = [[1, 2, 3], [1, 2, 3], [1, 2]]

1.2 Tensor的可操作性

在某种意义上,Tensor与Numpy数组是同一概念,所以基本的操作Tensor都支持

import torch

# torch.rand函数用于产生执行形状的张量,且每个元素为0-1
tensor_a = torch.rand(10, 6)
tensor_b = torch.rand(10, 6)
print(tensor_a.shape, tensor_b.shape)

# 加法操作,同理减法、乘法(对应元素相乘那种)、除法(对应元素相除那种)
tensor_c = tensor_a + tensor_b  # 运算符操作
tensor_c = torch.add(tensor_a, tensor_b)  # 函数操作
print(tensor_c.shape)

torch.Size([10, 6]) torch.Size([10, 6])
torch.Size([10, 6])

同样的常使用以下函数来生成特殊张量

API含义
torch.rand生成指定形状的随机张量
torch.zeros生成指定形状的0张量
torch.ones生成指定形状的1张量
torch.rand_like生成与给定张量相同形状的随机张量
torch.zeros_like生成与给定张量相同形状的0张量
torch.ones_like生成与给定张量相同形状的1张量
work

使用rand创建一个3x3的张量,再创建一个6x6的张量,尝试将它们相加


1.3 张量乘法与广播机制

张量就是一个矩阵,索引矩阵乘法就是张量的乘法
以下为3x4维度张量·4x8维度张量

import torch

tensor_a = torch.rand(3, 4)
tensor_b = torch.rand(4, 8)
tensor_c = torch.matmul(tensor_a, tensor_b)  # API操作
tensor_c = tensor_a.matmul(tensor_b)  # 类方法操作
print(tensor_a.shape, tensor_b.shape, tensor_c.shape)

torch.Size([3, 4]) torch.Size([4, 8]) torch.Size([3, 8])

同样的,有两个API都能达到同样的效果
dot:常用于向量运算,若1维张量与1维张量运算时,为计算内积,否则与matmul计算结果相同
matmul:矩阵与矩阵的计算

广播机制(了解)

1.如果两个张量的维度数量不同,则将较小的那个张量的形状前面补1,直到两个张量的维度数量相同。
2.如果两个张量在某个维度上的大小不一致,但其中一个张量在该维度上的大小是1,则可以在该维度上进行广播。
3.如果两个张量在任何维度上的大小既不相等也不为1,则无法进行广播。
4.广播后的张量形状是每个维度上大小的最大值。

import torch

# 示例 1: 形状不同的张量相加
a = torch.tensor([[1, 2, 3], [4, 5, 6]])
b = torch.tensor([1, 2, 3])
# b 会被广播成 [[1, 2, 3], [1, 2, 3]]
result = a + b
print(result)
# 输出:
# tensor([[ 2,  4,  6],
#         [ 5,  7,  9]])

# 示例 2: 形状不同的张量相乘
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = torch.tensor([1, 2])
# b 会被广播成 [[1, 2], [1, 2], [1, 2]]
result = a * b
print(result)
# 输出:
# tensor([[ 1,  4],
#         [ 3,  8],
#         [ 5, 12]])

# 示例 3: 形状不同的张量相加
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1], [2], [3]])
# a 会被广播成 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
# b 会被广播成 [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
result = a + b
print(result)
# 输出:
# tensor([[2, 3, 4],
#         [3, 4, 5],
#         [4, 5, 6]])
work

探究多维张量乘法


1.4 其他常用函数

1.4.1 reshape,view

reshape、view操作可以改变张量的形状

import torch

data = torch.rand(10, 10)  # 随机生成10x10张量
data1 = data.reshape(50, 2)  # 使用reshape将张量变为50x2
data2 = data.view(25, 4)  # 使用view将张量变为25x4
data3 = data.reshape(-1, 4, 25)  #使用reshape将张量变为(自动计算,4,25)
print(data3)

torch.Size([1, 4, 25])

从上述例子可以看出,reshape,view都可以改变张量的形状
当改变形状中含有1个-1时将自动计算该维度的大小
而reshape和view的不同在于
①view方法返回的是一个新的视图(view)对象,它共享原始Tensor的内存,这意味着任何对视图所做的修改都会反映到原始Tensor上
②reshape方法也会返回一个新的视图对象,和view一样,它不会创建新的数据,因此也不会增加内存占用
人话版:reshape会创建一个原张量的复制,后续操作不会反映到原张量,view则相反
例子

import torch

# 创建一个3x3的Tensor
x = torch.randn(3, 3)

# 使用view
y = x.view(9)  # 将3x3的Tensor重塑为1x9
y[0] = 1  # 修改y,也会修改x

# 使用reshape
z = x.reshape(1, 9)  # 将3x3的Tensor重塑为1x9
z[0, 0] = 2  # 修改z,不会修改x
1.4.2 max,min

在使用pytorch中常使用max,min函数进行筛选数据
有以下表数据datasets/p1.csv

姓名语文数学英语
小李867956
小何979860
小王765843
小吴667559
小陈595959
import pandas as pd
import torch

p1 = pd.read_csv('./datasets/p1.csv', index_col=None).to_numpy()
p1 = p1[:, 1:].astype(float)  # 筛选第1列到最后一列(因为姓名列用不上)
p1 = torch.from_numpy(p1)  # 将numpy数组直接转换为Tensor张量
print(p1.shape)
print(f'max default dim result {p1.max()}')

torch.Size([5, 3])
max default dim result 98.0

当dim=None(默认)的时候,默认返回当前张量中最大/最小的值
当dim!=None,返回当前维度的最大/最小的值和该值位于维度上的索引
比如对于以下数据

120305010
56789
546822168
597510

当dim=0时,按列搜索

搜索数列最大值索引
[1,5,54,5]542
[20,6,68,9]682
[30,7,2,75]753
[50,8,21,1]500
[10,9,68,0]682
所以运行结果为

torch.return_types.max(
values=tensor([54.,68.,75.,50.,68.], dtype=torch.float64),
indices=tensor([2,2,3,0,2]))

当dim=1时,按行搜索

搜索数列最大值索引
[5,6,7,8,9]94
[54,68,2,21,68]681
[5,9,75,1,0]752
所以运行结果为

torch.return_types.max(
values=tensor([9.,68.,75.], dtype=torch.float64),
indices=tensor([4,1,2]))

获取最大值结果、最大值索引使用成员运算符即可

values = p1.max(dim=0).values
indices = p1.max(dim=0).indices

min函数用法与max相同

1.4.3 argmax,argmin

argmax、argmin与max、min函数类似,可等价于以下公式
data.argmax(dim=n) == data.max(dim=n).indices
即返回数据dim维中最大的值的索引位置

1.4.4 切片操作与组合操作(cat)

张量的切片操作类似于数组的切片操作,与numpy的切片操作一致
1、分割向量的部分特征

import torch

data = torch.rand(100, 10)  # 模拟生成100条10个特征的向量
part1 = data[:, 5: 8]  # 将100条数据中每条数据的第6、7个特征分割出来
part2 = data[51: 98, :]  #将100条数据中第52条到97条分割出来

2、组合向量
在更多时候,我们需要将向量组合起来
①组合两组向量(扩大样本数量)

import torch

data1 = torch.rand(100, 10)  # 模拟生成100条10个特征的向量
data2 = torch.rand(50, 10)  # 模拟生成50条10个特征的向量
data3 = torch.cat([data1, data2], dim=0)  # 将data1与data2的0维连接起来(其他维度要保证形状一致)
print(data3.shape)

torch.Size([150, 10])

②组合两组向量的特征(扩大样本的特征数量)

import torch

data1 = torch.rand(100, 10)  # 模拟生成100条10个特征的向量
data2 = torch.rand(100, 15)  # 模拟生成100条15个特征的向量
data3 = torch.cat([data1, data2], dim=1)  # 将data1与data2的1维连接起来(其他维度要保证形状一致)
print(data3.shape)

torch.Size([100, 25])

work

尝试连接以下张量并获取连接后向量1维度的最大值和最大值索引

import torch

a = torch.rand(10, 23)
b = torch.rand(10, 23, 1)
import torch

a = torch.rand(10)
b = torch.rand(10, 23)
import torch

a = torch.rand(10, 3, 23, 1)
b = torch.rand(10, 23)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纸墨青鸢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值