Pytorch笔记——Tensor

Pytorch笔记——Tensor,第1张

Pytorch笔记——Tensor

Tensor

Tensors基础

基本定义Tensors与Storages数据类型 一些创建Tensor的方法相关 *** 作

基本运算改变大小从Tensor中取数据的方法与NumPy交互保存与加载TensorGPU加速

Tensors基础 基本定义

张量(Tensors)是pytorch中一种特殊的数据结构,类似于NumPy中的ndarrays,此外,Tensors可以用GPU进行计算
在高中和线性代数基本内容的学习中,我们对于标量(Scalar),向量(Vector),矩阵(Matrix)等有了比较深的认识。而张量,个人以为,其维数变化更加自由。
下面一张图来自于《Deep Learning with Pytorch》
PyTorch中的Tensor与NumPy中的arrays非常相似,但由于PyTorch可以在GPU上或CPU上并行运算,并记录跟踪计算过程,

在Python中,常常用List来处理向量。下面是List与Tensor的对比

print("下面是对List的 *** 作")
a = [1.0,1.0,1.0]
print(a[0])
a[2] = 3.0
print(a)

print("下面是对Tensor的 *** 作")
b = torch.ones(3)
print(b)
print(b[1])
print(float(b[1]))
b[2] = 2.0
print(b)

输出结果如下

看起来,这两者区别不大
但在底层实现上,这两种方法却有明显的区别
Python中List和Tuple里,每个元素是一个Python对象,在内存中松散排列(下图中左部),相较之下,Tensor和Arrays中,使用了一个连续的内存块,每个元素为C数据类型,而非Python对象。


至于面对高维向量,List固然也能表示,但比较繁琐。相对而言,还是Tensor更香。下面用Tensor表示一个三角形

points = torch.tensor([[1.0,4.0],[2.0,1.0],[3.0,5.0]])
print(points)
print("points.shape:",points.shape)

下图是输出

TIPS

可以先用Zeros填充每个元素,创造一个shape符合我们要求的张量,然后再改相应的值torch.Size([3,2])是一个元组,所以torch.Size([3,2])支持左右的元组 *** 作。 Tensors与Storages

上文提过,Tensor使用了一个连续的内存块。事实上,一块连续的内存(storage),可以对应多个不同的Tensor,而每一个Tensor,就是对这一块内存的一种view方法,就好像对于一串汉字,用不同的断句方式会产生不同的意思。
从而,view方法成了改变Tensor的shape的一种很好的方法。在之后的 *** 作部分会有介绍。

关于指向storage的方法,有几个量可以进行描述:size(shape),storage offset,strides

size:是一个tuple,表示每个维度有多少个元素storate offset:表示在storage中,跳过几个元素再开始读(偏移量)。也可以认为是数据在storage中的索引stride:步长,也是一个tuple。storage中对应于tensor的相邻维度间第一个索引的跨度

转置 *** 作是非常常见的,那么在Tensor中,就是把stride的两个数调换位置

数据类型

这些数据类型在之后的Tensor创建中都可以使用。

一些创建Tensor的方法
import torch
x = torch.empty(5,3)   #这是构建了一个未初始化的5*3矩阵
print(x)

输出见下图
如果要初始化,则应为x=torch.rand(5,3)
定义矩阵中每个元素的数据类型,就需要加上dtype=torch.
x = torch.zeros(5,3,dtype=torch.long)
现在有了张量X,就可以根据已有的张量创建新的张量

x = x.new_ones(5, 3, dtype=torch.double)
x = torch.randn_like(x, dtype=torch.float)
相关 *** 作 基本运算
x = torch.rand(5, 3)
y = torch.rand(5, 3)
x + y #直接使用+号
torch.add(x, y)
torch.add(x, y, out=result)#提供了一个输出张量作为参数
y.add_(x) #这一句是把x加到y上

#获得只有一个元素的Tensor的值
x = torch.randn(1)
x.item()
改变大小
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)
从Tensor中取数据的方法
points[1:] #只去掉第一行
points[1:, :] 
points[1:, 0]#只去第一行,只取第一列
与NumPy交互
points = torch.ones(3, 4)
points_np = points.numpy()

如果这个Tensor在GPU上,在转到NumPy后,会分到CPU上

保存与加载Tensor
#save
torch.save(points, '../data/p1ch3/ourpoints.t')

#或者

with open('../data/p1ch3/ourpoints.t','wb') as f:
torch.save(points, f)

#load
points = torch.load('../data/p1ch3/ourpoints.t')

#或者

with open('../data/p1ch3/ourpoints.t','rb') as f:
points = torch.load(f)
GPU加速
points_gpu = torch.tensor([[1.0,4.0],[2.0,1.0],[3.0,5.0]],device='cuda') #这里用device='cuda'
points_gpu = points_gpu+4
print(points_gpu)

ngpu= 1
# Decide which device we want to run on
device = torch.device("cuda:0" if (torch.cuda.is_available() and ngpu > 0) else "cpu")
print(device)
print(torch.cuda.get_device_name(0))
print(torch.rand(3,3).cuda()) #使用.cuda()更为快捷,也可以用.cuda(0)或.cuda(1)来指定设备

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5711497.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存