创建全 0 或全 1 的张量
创建元素值为全 0 或全 1 的张量是非常常见的初始化手段,通过 torch.zeros() 和 torch.ones() 函数即可创建任意形状,且元素值全为 0 或全为 1 的张量。
torch.zeros(*size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False) 和 torch.ones(*size, out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False) 两个函数的参数相同,这里简单介绍一下这些参数:
- *size: 定义输出张量形状的整数序列,这个整数序列可以是列表和数组之类的集合也可以是整数的 torch.Size(执行 tensor.size() 获取 tensor 形状的结果为 torch.Size);
- out = None(可选参数): 指定输出的张量。比如执行
torch.zeros([2, 2], out = tensor_a)
,相当于执行tensor_a = torch.zeros([2, 2])
; - dtype = None(可选参数):指定返回张量的数据类型,默认(dtype = None)使用全局默认的数据类型,我们可以使用 torch.get_default_tensor_type() 获取全局默认的数据类型,同时可以通过 torch.set_default_tensor_type(torch.XXXTensor) 更改全局默认的数据类型为 torch.XXXTensor;
- layout = torch.strided(可选参数): 定义张量在物理设备中的存储结构,torch.layout 可选的参数值有 torch.strided(默认)或 torch.sparse_coo,分别对应顺序存储和离散存储。「通常情况下,如果张量中的元素值 0 比较少为稠密张量,则指定 layout = torch.strided。如果张量中的元素值中 0 比较多为稀疏张量,则指定 layout = torch.sparse_coo」;
- device = None(可选参数): 指定张量所在的计算设备是 CPU 还是 GPU;
- requires_grad=False(可选参数): 指定此张量是否需要记录梯度;
torch.zeros() 和 torch.ones() 两个函数中只有 *size 参数为必须指定的参数,其余参数都是可选参数,因此接下来只关注指定 *size 参数的 torch.zeros(*size) 和 torch.ones(*size)。
代码语言:javascript复制 In[1]: import torch
# 创建全为0或1的0D张量(标量)
scalar_zero = torch.zeros([])
scalar_one = torch.ones([])
print("张量的维度:{},张量的值:{}".
format(scalar_zero.dim(), scalar_zero))
print("张量的维度:{},张量的值:{}".
format(scalar_one.dim(), scalar_one))
Out[1]: 张量的维度:0,张量的值:0.0
张量的维度:0,张量的值:1.0
In[2]: # 创建全为0或1的1D张量(向量)
vec_zero = torch.zeros([3])
vec_one = torch.ones([3])
print("张量的维度:{},张量的值:{}".
format(vec_zero.dim(), vec_zero))
print("张量的维度:{},张量的值:{}".
format(vec_one.dim(), vec_one))
Out[2]: 张量的维度:1,张量的值:tensor([0., 0., 0.])
张量的维度:1,张量的值:tensor([1., 1., 1.])
In[3]: # 创建全为0或1的2D张量(矩阵)
mat_zero = torch.zeros([2, 2])
mat_one = torch.ones([2, 2])
print("张量的维度:{},张量的值:{}".
format(mat_zero.dim(), mat_zero))
print("张量的维度:{},张量的值:{}".
format(mat_one.dim(), mat_one))
Out[3]: 张量的维度:2,张量的值:tensor([[0., 0.],
[0., 0.]])
张量的维度:2,张量的值:tensor([[1., 1.],
[1., 1.]])
通过 torch.zeros(*size) 和 torch.ones(*size) 函数创建了元素值全为 0 和全为 1 的 0D 张量、1D 张量和 2D 张量,创建 nD 张量与之类似,这里不再赘述。*size 参数指定创建张量的形状,不同维度张量的形状可以参考下表。
比如:
- 创建 0D 张量只需要指定 size = [];
- 创建 1D 张量只需要指定 size = [dim0],其中 dim0 为第 0 个维度的元素个数;
- 创建 2D 张量只需要指定 size = [dim0, dim1],其中 dim0 为第 0 个维度的元素个数,dim1 为第 1 个维度的元素个数;
- 依次类推,创建 nD 张量只需要指定 size = [dim0, dim1, ..., dimn],其中 dim0 为第 0 个维度的元素个数,dim1 为第 1 个维度的元素个数,...,dimn 为第 n 个维度的元素个数;
通过 torch.zeros_like(input) 和 torch.ones_like(input) 函数可以方便地创建与 input 张量形状一致,且元素值全为 0 或者 1 的张量,需要注意此时的 input 必须是张量。
代码语言:javascript复制 In[4]: import torch
scalar_a = torch.tensor(1.)
vec_a = torch.tensor([1., 2., 3.])
mat_a = torch.tensor([[1., 2.], [3., 4.]])
print("张量的形状:{}".format(scalar_a.size()))
print("张量的形状:{}".format(vec_a.size()))
print("张量的形状:{}".format(mat_a.size()))
Out[4]: 张量的形状:torch.Size([])
张量的形状:torch.Size([3])
张量的形状:torch.Size([2, 2])
In[5]: # 创建和张量scalar_a相同形状的全为0或1的张量
scalar_zero = torch.zeros_like(scalar_a)
scalar_one = torch.ones_like(scalar_a)
print("张量的维度:{},张量的值:{}".
format(scalar_zero.dim(), scalar_zero))
print("张量的维度:{},张量的值:{}".
format(scalar_one.dim(), scalar_one))
Out[5]: 张量的维度:0,张量的值:0.0
张量的维度:0,张量的值:1.0
In[6]: # 创建和张量scalar_a相同形状的全为0或1的张量
vec_zero = torch.zeros_like(vec_a)
vec_one = torch.ones_like(vec_a)
print("张量的维度:{},张量的值:{}".
format(vec_zero.dim(), vec_zero))
print("张量的维度:{},张量的值:{}".
format(vec_one.dim(), vec_one))
Out[6]: 张量的维度:1,张量的值:tensor([0., 0., 0.])
张量的维度:1,张量的值:tensor([1., 1., 1.])
In[7]: # 创建和张量scalar_a相同形状的全为0或1的张量
mat_zero = torch.zeros_like(mat_a)
mat_one = torch.ones_like(mat_a)
print("张量的维度:{},张量的值:{}".
format(mat_zero.dim(), mat_zero))
print("张量的维度:{},张量的值:{}".
format(mat_one.dim(), mat_one))
Out[7]: 张量的维度:2,张量的值:tensor([[0., 0.],
[0., 0.]])
张量的维度:2,张量的值:tensor([[1., 1.],
[1., 1.]])
创建自定义数值张量
除了将张量的元素值初始化全为 0 或全为 1 的张量依然,有时候也需要全部初始化为某个自定义数值的张量。通过 torch.full(*size, fill_value, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) 可以创建全为自定义数值 fill_value 的张量,形状由 size 参数指定。
torch.full() 函数中除了 size 和 fill_value 参数外,其余都是可选参数且和 torch.zeros() 和 torch.ones() 两个函数的参数一致,同样不再赘述。
- size: 定义输出张量形状的整数序列,这个整数序列可以是列表和数组之类的集合也可以是整数的 torch.Size(执行 tensor.size() 获取 tensor 形状的结果为 torch.Size);
- fill_value: 填充到张量中的元素值,必须为标量值;
In[8]: import torch
# 创建0D且元素值为5的张量
scalar_a = torch.full([], 5)
# 创建1D且元素值为5的张量
vec_a = torch.full([3], 5)
# 创建2D且元素值为5的张量
mat_a = torch.full([2, 2], 5)
print("张量的维度:{},张量的值:{}".
format(scalar_a.dim(), scalar_a))
print("张量的维度:{},张量的值:{}".
format(vec_a.dim(), vec_a))
print("张量的维度:{},张量的值:{}".
format(mat_a.dim(), mat_a))
Out[8]: 张量的维度:0,张量的值:5.0
张量的维度:1,张量的值:tensor([5., 5., 5.])
张量的维度:2,张量的值:tensor([[5., 5.],
[5., 5.]])
「通过 torch.full_like(input, fill_value) 函数来创建全为自定义数值 fill_value 的张量,形状由参数 input 的形状指定,input 必须是张量。」