tensor简介(基于Pytorch)

#最近开始看沐神的《动手学深度学习》,陆续记录学习笔记#

tensor是什么

tensor,n维向量,也称为张量,是机器学习的重要数据结构。

深度学习框架中通常会提供一个张量类,张量类支持自动微分,良好支持GPU加速计算。

tensor的创建

第一步:导入torch

import torch

第二步:创建,此处介绍四种创建方法

方法1:直接初始化x。张量x中包含4个元素。

data = [[1, 2], [3, 4]]
x = torch.tensor(data)

方法2:使用随机数和常数初始化。

使用arange创建一个行向量x。张量x中包含12个元素,即0-11共12个整数。

x = torch.arange(12)

使用zeros创建一个元素均为0的张量x。(2,3,4)是一个元组,表示了张量x的维度。

x = torch.zeros((2, 3, 4))

使用ones创建一个元素均为1的张量x。

x = torch.ones((2, 3, 4))

创建元素为随机数的张量x。(rand:[0,1)的均匀分布;randn:均值为0,方差为1的标准正态分布;)

x1 = torch.randn(3, 4)
x2 = torch.rand(2, 3)

tensor([[-0.0135, 0.0665, 0.0912, 0.3212],

            [ 1.4653, 0.1843, -1.6995, -0.3036],

            [ 1.7646, 1.0450, 0.2457, -0.7732]])

tensor([[0.9041, 0.7120, 0.7389],

            [0.1606, 0.3994, 0.3293]])

方法3:从Numpy数组初始化。

import numpy as np
data = [[1, 2], [3, 4]]
np_array = np.array(data)
x = torch.from_numpy(np_array)

方法4:从其他tensor中初始化。

data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)
x_ones = torch.ones_like(x_data) 
x_rand = torch.rand_like(x_data, dtype=torch.float)

tensor([[1, 1],

            [1, 1]])

tensor([[0.6941, 0.0369],

            [0.0227, 0.6394]])

tensor类 的 属性

shape:描述了tensor的形状

dtype:描述了tensor的数据类型

device:描述了存储tensor的设备

tensor = torch.rand(3,4)

print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

Shape of tensor: torch.Size([3, 4])

Datatype of tensor: torch.float32

Device tensor is stored on: cpu

tensor类的操作

常用基本操作

获取张量形状。size()

与shape属性的功能一致,size()方法也可以获得张量的形状,以及某一个维度

a = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(a.shape)
print(a.size())
print(a.shape[0])
print(a.shape[1])
print(a.size(0))
print(a.size(1))

torch.Size([2, 3])

torch.Size([2, 3])

2

3

2

3

修改张量形状。reshape()、view()、flatten()

reshape(input, shape)->Tensor

按照指定的形状修改输入的张量的形状

详细的内容可以参照官方指南:

torch.reshape — PyTorch 2.1 documentation

或如下博客:

torch.reshape用法-CSDN博客

view(*shape)->Tensor

可以根据输入的形状重构或调整张量维度。

详细的内容可以参照如下博客:

torch:)——PyTorch: view( )用法详解_torch.view-CSDN博客

flatten(input, start_dim=0, end_dim=-1)->Tensor

可以按照指定的维度范围将张量进行扁平化。

详细的内容可以参照如下博客:

PyTorch基础(15)-- torch.flatten()方法_底层研究生的博客-CSDN博客

求最大最小值。max()、min()

torch.max(input, dim, keepdim=False, *, out=None) -> (Tensor, LongTensor)

可以求输入张量的最大值元素或在指定维度上的最大值

详细的内容可以参照如下博客:

Pytorch最大值最小值函数:torch.max()、torch.min()-CSDN博客

torch.min(input, dim, keepdim=False, *, out=None) -> (Tensor, LongTensor)

可以求输入张量的最小值元素或在指定维度上的最小值

 详细的内容可以参照官方指南:

torch.min — PyTorch 2.1 documentation

或如下博客:

torch.min()的使用举例_敲代码的小风的博客-CSDN博客

运算符

Element-wise 标准运算符。对于任意具有相同形状的张量,常见的标准算术运算符(+、-、*、/和**,以及exp)都可以被升级为按元素(element-wise)运算。

x = torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y # **运算符是求幂运算
torch.exp(x)

tensor([ 3., 4., 6., 10.]),

tensor([-1., 0., 2., 6.]),

tensor([ 2., 4., 8., 16.]),

tensor([0.5000, 1.0000, 2.0000, 4.0000]),

tensor([ 1., 4., 16., 64.])
tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

张量连结(concatenate)。将两个张量按照指定的维度连结在一起。

X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)

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

            [ 4., 5., 6., 7.],

            [ 8., 9., 10., 11.],

            [ 2., 1., 4., 3.],

            [ 1., 2., 3., 4.],

            [ 4., 3., 2., 1.]]),

tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],

            [ 4., 5., 6., 7., 1., 2., 3., 4.],

            [ 8., 9., 10., 11., 4., 3., 2., 1.]])

Element-wise 逻辑运算符。对于任意具有相同形状的张量,常见的逻辑算术运算符(==、>、<、>=、<=和!=)都可以被升级为按元素(element-wise)运算。

X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
X == Y

tensor([[False, True, False, True],

            [False, False, False, False],

            [False, False, False, False]])

求和。对张量中所有元素进行求和,产生一个单元素张量。

X.sum()
tensor(66.)

广播机制(broadcasting mechanism)

在一些情况下,我们需要将形状不同的两个张量执行element-wise操作,此时就需要用到广播机制。广播机制中首先通过适当复制元素来扩展一个或两个张量,使得扩展后的两个张量具有相同的形状,然后再用扩展后的张量执行element-wise操作。

a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a + b

a和b分别是,a为3x1张量,b为1x2张量:

tensor([[0],

            [1],

            [2]]),

tensor([[0, 1]])

使用广播机制进行element-wise相加,第一步先扩展a和b,其中a复制列形成3x2张量,b复制行形成3x2张量。

tensor([[0, 0],

            [1, 1],

            [2, 2]]),

tensor([[0, 1]

            [0, 1]

            [0, 1]])

然后使用扩展后的两个张量执行element-wise相加,可得

tensor([[0, 1],

            [1, 2],

            [2, 3]]),

索引和切片

通过索引访问元素。与Python中通过索引访问数组的方法一样,张量的第一个元素索引是0,最后一个元素的索引是-1,可以通过指定范围来得到范围内的元素。

X = torch.arange(12, dtype=torch.float32).reshape((3,4))
X[-1]
X[1:3]
X[1, 2]
X[1, 2] = 9
X[0:2, :] = 12

创建张量X为:

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

            [ 4., 5., 6., 7.],

            [ 8., 9., 10., 11.]])

X[-1]表示取X第0维度(行)的最后一个元素(最后一行,即第3行)

tensor([ 8., 9., 10., 11.])

X[1 : 3]表示取X第0维度(行)的第1个和第2个元素

tensor([[ 4., 5., 6., 7.],

            [ 8., 9., 10., 11.]])

X[1, 2]表示取X第0维度的第一个元素内的对应X第1维度的第2个元素

tensor(6.)

X[1, 2] = 9 表示将指定的值写入指定的索引位置,修改后的X为

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

            [ 4., 5., 9., 7.],

            [ 8., 9., 10., 11.]])

X[0:2, :] = 12 表示为X的第0维度的第0个元素和第1个元素的内对应X第1维度的所有元素修改为值为12

tensor([[ 12., 12., 12., 12.],

            [ 12., 12., 12., 12.],

            [ 8., 9., 10., 11.]])

转换为其他Python对象

torch张量和numpy数组可以共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量

A = X.numpy()
B = torch.tensor(A)
type(A), type(B)
(numpy.ndarray, torch.Tensor)

若要将大小为1的张量转换为Python标量,可以使用item函数或Python内置函数。

a = torch.tensor([3.5])
a, a.item(), float(a), int(a)
(tensor([3.5000]), 3.5, 3.5, 3)

节省内存

在编码的过程中需要注意一些计算中的内存开销问题。设有两个张量分别为X和Y,那么当我们想要将X+Y的结果仍旧由X来表示时,可能会写成X=X+Y,这种方法下重新赋值前后的X在内存中的地址是不一样的,这意味着,X在重新赋值的过程中重新分配了内存,造成了一定的内存开销。

#使用Python中id()方法来查看X重新赋值前后的内存地址
before = id(X)
X = X + Y
id(X) == before #此时为False

原地更新张量:当我们想要原地更新一个张量时,我们可以使用如下三种方式

  • 切片表示法
before = id(X)
X[:] = X+Y
id(X) == before #此时为True
  • 使用+=、-=等类似操作符:
before = id(X)
X += Y
id(X) == before #此时为True
  • 使用中间变量:
Z = torch.zeros_like(Y)
Z[:] = X + Y

了解更多tensor类的操作,可以参考pytorch官方文档torch — PyTorch 2.1 documentation

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值