【PyTorch笔记】60分钟入门PyTorch——Tensor

Tensor

官网连接:Tensor

tensor被翻译为张量,是一种与NumPy数据和矩阵十分相似的特殊数据结构
在PyTorch中,我们使用tensor给模型的输入输出以及参数进行编码
除了可以在GPUs和其他可以加速运算的硬件上运行这一特点之外,tensors和NumPy数组非常相似

1. 初始化tensor

使用数据直接初始化

import numpy as np
import torch

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

# 输出
tensor([[1, 2],
        [3, 4]])

使用NumPy arrays初始化

np_array = np.array(data)
x_np = torch.from_numpy(np_array)

#输出
tensor([[1, 2],
        [3, 4]], dtype=torch.int32)

使用另一个tensor创建

新的tensor保留了参数tensor的一些属性(形状,数据类型),除非显式覆盖

x_ones = torch.ones_like(x_data) # 保留了x_data的属性
print(f"Ones Tensor: \n {x_ones} \n")
# 显示覆盖x_data的数据类型
x_rand = torch.rand_like(x_data,dtype=torch.float)
print(f"Random Tensor: \n {x_rand} \n")

# 输出
Ones Tensor: 
 tensor([[1, 1],
        [1, 1]]) 

Random Tensor: 
 tensor([[0.5502, 0.3189],
        [0.0911, 0.7488]]) 

使用随机数或者常数创建tensor

# shape是关于tensor维度的元组,它决定输出tensor的维度
shape = (2,3,)

rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

# 输出
Random Tensor:
 tensor([[0.8012, 0.4547, 0.4156],
        [0.6645, 0.1763, 0.3860]])

Ones Tensor:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])

Zeros Tensor:
 tensor([[0., 0., 0.],
        [0., 0., 0.]])

2. tensor属性

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

3. tensor操作

tensor有超过100种操作,包括转置(transposing), 索引(indexing),切片( slicing), 数学运算(mathematical operations), 线性代数(linear algebra),随机操作( random sampling)等等。

它们都可以在GPU上运行(速度通常比CPU快),如果你使用的是Colab,通过编辑>笔记本设置来分配一个GPU

# 将tensor移到GPU上
if torch.cuda.is_available():
    tensor = tensor.to('cuda')
    print(f"Device tensor is stored on: {tensor.device}")
    
# 输出 :Device tensor is stored on: cuda:0

尝试一些操作

像NumPy一样标准的索引和切片

tensor = torch.ones(4,4)
tensor[:,1] = 0
print(tensor)
# 输出
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

连接tensor(Joining tensors)

使用torch.cat可以沿着给定的维度合并一系列tensor

torch.stack是另一个连接tensor的操作,和torch.cat有些许不同

t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
# 输出
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])

tensor相乘

元素层面的乘法操作

# tensor在元素层面的乘法操作
tensor.mul(tensor)
# 和上面等价的写法
tensor * tensor
# 输出 
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

两个tensor之间的矩阵乘法

tensor.matmul(tensor.T)
# 等价写法
tensor @ tensor.T

# 输出
tensor([[3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.],
        [3., 3., 3., 3.]])

In-place操作

带有后缀_的操作是in_place操作,例如:x.copy_(y)x.t_()将改变x

in_place操作虽然会节省很多内存空间,但是会因为即刻清除历史记录在计算导数的时候可能出现问题,所以不鼓励使用这种操作方式

print(tensor, "\n")
tensor.add_(5)
print(tensor)
# 输出
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]]) 

tensor([[6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.]])

4. 使用Numpy作为桥梁

在cpu上的tensor和NumPy数组可以共享基本的内存位置,改变一个就会改变另一个

tnsor转变成Numpy数组

t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")
# 输出
t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]

tensor中的改变会影响到NumPy数组

t.add_(1)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]

NumPy数组转变成tensor

n = np.ones(5)
t = torch.from_numpy(n)
# 在NumPy数组中的改变会影响到tensor
np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值