1:张量是什么,下图可以一目了然,张量其实就是一个多维数组,在进行图像处理的时候,特别是彩色图像,含有RGB三个通道,那就必须要用三维张量才能进行表示。
在pytorch中张量可不仅仅是多维数组,也是自动求导的关键,(在pytorch0.4.0之前Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行自动求导。)
讲一下Variable
data:被包装的Tensor
grad:data的梯度
grad_fn:创建Tensor的Function,是自动求导的关键
require_grad:指示是否需要梯度
is_leaf:指示是否是叶子结点(张量)
但是在pytorch0.4.0版本开始,Variable并入Tensor(多了三个属性dtype,shape,device)
dtype:表示张量的数据类型,比如 torch.FloatTensor
shape:张量的形状,如(64,3,,512,512)
device:张量所在设备,有GPU和CPU,这是加速的关键
1. 1 torch.tensor()
从data创建tensor
下面来用代码尝试一下,创建一个py文件,输入下面代码。
import numpy as np
import torch
arr = np.ones((4,4))
print("arr的数据类型:",arr.dtype)
t = torch.tensor(arr)
print(t)
运行,可以看到tensor是4*4的二维tensor,而且数据类型也是和输入的arr一样都是float64.
当然如果你要把张量放在gpu上,可以修改一下,在后面加上device=cuda"
t = torch.tensor(arr,device="cuda")
运行后会发现一个现象,先出现arr的数据类型,然后再输出tensor,这是因为tensor从CPU转到GPU是要一定时间的。
1.2 另一个方法:torch.from_numpy(ndarray)
作用:从numpy创建tensor(用这个方法创建的tensor于原来的ndarray共享内存,当修改其中一个的数据,另一个也会被改动)
输入以下代码:
arr = np.array([[1, 2, 3],[4, 5, 6]])
t = torch.from_numpy(arr)
print("numpy array:",arr)
print("tensor:",t)
运行,发现是相同的
然后改变arr,看tensor是否会随之改变
arr = np.array([[0, 2, 3],[4, 5, 6]])
运行,发现都变化了,变成[0,2,3]
同理,变化tensor观察arr是否发生改变,添加代码
t[0,0]=-2
运行发现也都改变了
2.1 torch.zeros()
作用:依size创建全0张量
同样代码实现一下
out_t = torch.tensor([1])
t = torch.zeros((3, 3), out=out_t)
print(t, "\n",out_t)
print(id(t),id(out_t),id(t)==id(out_t))
运行发现t和out_t是一样的,id地址也是一样的
2.2 还可以用torch.zeros_like()创建全0张量
作用:依据input形状创建全0张量
2.3 除了全0张量创建还有全1张量的创建,只需要把zeros改成ones就行
torch.ones()
torch.ones_like()
2.4 当然如果你要填充你想要的值也行,可以使用torch.full()或者torch.full_like()
作用:依据input的形状创建全(设定的值)张量
用代码实现一下,创建一个全5的3*3张量
t = torch.full((3, 3),5)
print(t)
运行
2.5 创建等差的1维张量torch.arange()
注意:数值区间为[start, end)——这里是取不到end的
代码示例:
t = torch.arange(1,10,1)
print(t)
运行
2.6 创建均分的1维张量torch.linspace()
注意:数值区间为[start, end]——这里是可以取到end的
代码示例(用两个例子展示一下):
t1 = torch.linspace(2,10,5)
t2 = torch.linspace(2,10,6)
print(t1,t2)
运行
可以发现张量的步长是=(end-start)/(step-1)
2.7 创建一个单位对角矩阵(默认为方阵 )torch.eye()
代码
t = torch.eye(4)
print(t)
运行
3.1 torch.normal()
作用:生成正态分布(高斯分布)
根据mean和std可能为张量或标量这个方法有四种模式
代码示例:
#1:mean为张量,std为张量
mean1 = torch.arange(1,4,dtype=torch.float)
std1 = torch.arange(1,4,dtype=torch.float)
t1_normal = torch.normal(mean1,std1)
print(mean1,std1,t1_normal)
#2:mean为张量,std为标量
mean2 = torch.arange(1,4,dtype=torch.float)
std2 = 1
t2_normal = torch.normal(mean2,std2)
print(mean2,std2,t2_normal)
#3:mean为标量,std为张量
mean3 = 1
std3 = torch.arange(1,4,dtype=torch.float)
t3_normal = torch.normal(mean3,std3)
print(mean3,std3,t3_normal)
#4:mean为标量,std为标量
t4_normal = torch.normal(1,1,size=(3,))
print(t4_normal)
运行
解释一下,第一种情况输出的正态分布张量中0.4995是在mean=1,std=1的分布中采样的,3.8502是在mean=2,std=2的分布中采样的,同理依次对应。
第二种情况输出的1.6317是在mean=1,std=1的分布中才采样的,1.2950在mean=2,std=1的分布中采样的,同理依次对应。
后面的两中情况也差不多,对应输出。(注意全是标量的情况下要加上size)
3.2 创建mean=0,std=1的标准正态分布torch.randn()或torch.randn_like()
要加上size(张量的形状)
3.3 创建均匀分布torch.rand()或torch.rand_like()
3.4 创建整数均匀分布torch.randint()或torch.randint_like()
3.5 生成从0到n-1的随机排列 torch.randperm(),通常用创建索引
n:张量的长度
3.6 生成以input为概率,生成伯努利分布(0-1分布,两点分布)torch.bernoulli()