本篇为在 深度之眼 学习PyTorch笔记之一
This is one of the notes from the Deepshare
1.张量是什么
张量是一个多维数组,它是标量、向量、矩阵的高维拓展
2.Tensor与Variable
Variable是torch.autograd中的数据类型,主要用于封装Tensor (torch.autograd.Variable),进行自动求导,主要的五个属性:
- data:被包装的Tensor
- grad: data的梯度
- grad_fn:创建Tensor的Function,,是自动求导的关键;记录创建张量时所使用的运算规则
- requires_grad:指示是否需要梯度,false为不计算梯度
- is_leaf:指示是否是叶子结点(张量)
PyTorch 0.4.0版开始,Variable并入Tensor
- dtype: 张量的数据类型,如torch.FloatTensor,torch.cuda.FloatTensor(数据放在了cuda上)
- shape: 张量的形状,如(32,3,224,224)
- device: 张量所在的设备,GPU/CPU,是加速的关键
3. Tensor的创建
本节主要讲述Tensor的三种创建方式:
- 直接创建
- 数值创建
- 概率创建
3.1 直接创建
使用torch.tensor()
创建:
torch.tensor(
#功能:从data创建tensor
data, #数据,可以是list,numpy
dtype = None, #数据类型,默认与data的一致
device = None, #所在设备,cuda/cpu
requires_grad = False, #是否需要梯度
pin_memory = False #是否存于锁业内存)
实验代码一:
# 通过torch.tensor创建张量
flag = True
# flag = False
if flag:
arr = np.ones((3, 3))
print("ndarray的数据类型:", arr.dtype)
# t = torch.tensor(arr, device='cuda') #适用于有cuda的情况
t = torch.tensor(arr)
print(t)
实验结果一:
ndarray的数据类型: float64
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
使用numpy创建
torch.from_numpy(
#功能: 从numpy创建tensor
注意事项: 从torch.from_numpy创建的tensor于原ndarray共享内存,当修改其中一个的数据,另外一个也会被改动
实验代码二:
# 通过torch.from_numpy创建张量
flag = True
# flag = False
if flag:
arr = np.array([[1, 2, 3], [4, 5, 6]])
t = torch.from_numpy(arr)
# print("numpy array: ", arr)
# print("tensor : ", t)
# print("\n修改arr")
# arr[0, 0] = 0
# print("numpy array: ", arr)
# print("tensor : ", t)
print("\n修改tensor")
t[0, 0] = -1
print("numpy array: ", arr)
print("tensor : ", t)
实验结果二:
修改arr
numpy array: [[0 2 3]
[4 5 6]]
tensor : tensor([[0, 2, 3],
[4, 5, 6]])
修改tensor
numpy array: [[-1 2 3]
[ 4 5 6]]
tensor : tensor([[-1, 2, 3],
[ 4, 5, 6]])
3.2 依据数值创建
3.2.1 依据size创建全0张量
torch.zeros(
#功能: 依据size创建全0张量
size, # 张量的形状,如(3,3),(3,224,224)
out = None, # out:输出的张量
dtype = None,
layout = torch.strided, #内存的布局形式,有strided, sparse_coo等
device = None, #所在的设备,gpu/cpu
requires_grd = False #是否需要梯度)
实验代码三:
# # 通过torch.zeros创建全0张量
flag = True
#flag = False
if flag:
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))
实验结果三:
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
4743420736 4743420736 True
从结果可以分析出,t与out_t都是全0张量,并且是同一个地址。
3.2.2 依据input创建全0张量
torch.zeros_like(
#功能: 依input同形状的全0张量
input, #创建与input同形状的全0张量
dtype = None, #数据类型
layout = None, #内存中布局形式
device = none,
requires_grad = False)
同样,使用torch.ones()和torch.ones_like()创建全1张量;
3.2.3 使用torch.full( )和torch.full_like( )自定义数值创建
torch.full(
#功能: 依据full自定义创建张量
size, # 张量的形状,如(3,3),(3,224,224)
fill_value,
out = None, # out:输出的张量
dtype = None,
layout = torch.strided, #内存的布局形式,有strided, sparse_coo等
device = None, #所在的设备,gpu/cpu
requires_grd = False #是否需要梯度)
实验代码四:
# # 通过torch.full创建全1张量
flag = True
# flag = False
if flag:
t = torch.full((3, 3), 1)
print(t)
实验结果四:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
3.2.4 使用torch.arange( )等差的1维张量
torch.arange(
#功能: 依据arange创建等差为1的张量,数值区间为[start,end]
start = 0, # 数列起始值
end, # 数列“结束值”
step = 1, # 数列公差,默认为1
out = None,
dtype = None,
layout = torch.strided,
device = none,
requires_grad = False)
实验代码五:
# 通过torch.arange创建等差数列张量
flag = True
#flag = False
if flag:
t = torch.arange(2, 10, 2)
print(t)
实验结果五:
tensor([2, 4, 6, 8])
3.2.5 使用torch.linspace( )等差的1维张量
torch.linspace(
#功能: 依据linspace创建均分的1维张量,数值区间为[start,end]
start = 0, # 数列起始值
end, # 数列“结束值”
step = 100, # 数列长度
out = None,
dtype = None,
layout = torch.strided,
device = none,
requires_grad = False)
实验代码六:
# 通过torch.linspace创建均分数列张量
flag = True
#flag = False
if flag:
# t = torch.linspace(2, 10, 5)
t = torch.linspace(2, 10, 6)
print(t)
实验结果六:
tensor([ 2.0000, 3.6000, 5.2000, 6.8000, 8.4000, 10.0000])
3.2.6 使用torch.logspace( )对数均分的1维张量
torch.logspace(
#功能: 依据logspace创建对数均分的1维张量,长度为steps,底为base
start = 0, # 数列起始值
end, # 数列“结束值”
step = 100, # 数列长度
base = 10.0, # 对数函数的底,默认为10
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
3.2.7 使用torch.eye( )创建单位对角矩阵(2维张量)
torch.eye(
#功能: 依据eye创建单位对角矩阵(2维张量),m默认为方阵
n, # 矩阵行数
m = None, # 矩阵列数
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
3.3 依据概率创建
3.3.1 使用torch.normal()创建正态分布
torch.normal(
#功能: 依据正态分布(高斯分布)创建张量
mean, # 均值
std, # 标准差
size, # 控制标量或张量
out = None)
但是,torch.normal()有四种模式:
- mean为标量,std为标量;
- mean为标量,std为张量;
- mean为张量,std为标量;
- mean为张量,std为张量
实验代码七:
# 通过torch.normal创建正态分布张量
flag = True
# flag = False
if flag:
# mean:张量 std: 张量
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t_normal = torch.normal(mean, std)
print("mean:{}\nstd:{}".format(mean, std))
print(t_normal)
# mean:标量 std: 标量
t_normal = torch.normal(0., 1., size=(4,))
print("mean:{}\nstd:{}".format(mean, std))
print(t_normal)
# mean:张量 std: 标量
mean = torch.arange(1, 5, dtype=torch.float)
std = 1
t_normal = torch.normal(mean, std)
print("mean:{}\nstd:{}".format(mean, std))
print(t_normal)
实验结果七:
mean:tensor([1., 2., 3., 4.])
std:tensor([1., 2., 3., 4.])
tensor([1.6614, 2.5338, 3.1850, 6.4853])
mean:tensor([1., 2., 3., 4.])
std:tensor([1., 2., 3., 4.])
tensor([-0.4519, -0.1661, -1.5228, 0.3817])
mean:tensor([1., 2., 3., 4.])
std:1
tensor([-0.0276, 1.4369, 2.1077, 3.9417])
3.3.2 使用torch.randn()和torch.randn_like()创建标准正态分布
torch.randn(
#功能: 依据标准正态分布(高斯分布)创建张量
size,
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
3.3.3 使用torch.rand()和torch.rand_like()创建$[0,1)$
均匀分布
torch.rand(
#功能: 依据[0,1)均匀分布创建张量
size,
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
3.3.4 使用torch.randint()和torch.randint_like()创建$[low,high)$
整数均匀分布
torch.randint(
#功能: 依据[low,high)均匀整数分布创建张量
low = 0,
high,
size,
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
torch.randint_like(
#功能: 依据[0,1)均匀整数分布创建张量
low = 0,
high,
size,
out = None,
dtype = None,
layout = torch.strided,
device = None,
requires_grad = False)
3.3.5 使用torch.randperm()生成0到n-1的随机排列
torch.randperm(
#功能: 生成0到n-1的随机排列,常用来生成索引
n, #张量的长度
out = None,
dtype = torch.int64,
layout = torch.strided,
device = None,
requires_grad = False)
3.3.6 使用torch.bernoulli()生成伯努利分布
torch.bernoulli(
#功能: 以input为概率,生成伯努利分布(0-1分布,两点分布)
input, #概率值
*,
generate = None,
out = None)