pytorch基础:张量

1.1 张量tensor介绍

PyTorch最基本的操作对象是Tensor(张量)。张量是一个数字容器,同时也是定义张量转换来生成新张量的一组规则。

在数学中标量是只有大小没有方向的量;向量时有大小和方向的量;矩阵是由多个向量组成的。在PyTorch中标量就可以视为零阶的张量,向量可以视为一阶张量,矩阵就是二阶张量。

优点:在PyTorch中支持GPU运算和自动求梯度等功能。
 

Variable是torch .autograd中的数据类型主要用于封装Tensor,进行自动求导(0.4.0后已并入tensor,不再存在),六大属性:

  • data:被包装的Tensor

  • grad:data的梯度

  • grad_fn:创建Tensor的Function,是自动求导的关键

  • require_grad:指示是否需要梯度

  • is_leaf:指示是否是叶子结点(张量)

Tensor除了上述属性,还有以下三个属性:

  • dtype:张量的数据类型

  • shape:张量的形状

  • device:张量所在的设备,GPU/CPU,是加速的关键

1.2 Tensor创建

1.2.1 直接创建

torch.tensor(
        data,
        dtype = None,
        device = None,
        require_grad = False,
        pin_memory = False        ## 是否依赖锁页内存
)

flag = True
if flag:
    arr = np.ones([3,3])
    print('arr数据类型:', arr.dtype)
    
    t = torch.Tensor(arr, device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu'))
    print(t)

from_numpy创建张量

【注意】从torch.from_numpy创建的tensor于原ndarray共享内存,当修改其中一个的数据,另外一个也将会被改动=。

flag = True
if flag:
    arr = np.array([[1,2,3],[2,3,4]])
    t = torch.from_numpy(arr)
    print(t)
    
    arr[0][0] = 0
    print(t)       ## 数据也随之变化

1.2.2 依据数值创建

等值数列

torch.zeros(
    *size,        ## 形状
    out = None,   ## 输出的张量
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

flag = True
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.]])
2305522661552 2305522661552 True

表明 t 和 out_t有同一个存储地址,只是命名不同。

torch.zeros_like(
    input, 
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

还有torch.ones、torch.ones_like、torch.full、torch.full_like等,可以使用。

flag = True
if flag:
    t = torch.full((3,3), 10)
    print(t)

等差数列

创建等差的一维张量

torch.arange(
    start = 0,
    end,      ## 不包含end,类似np.arange函数
    step,
    out=None,
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

均分数列

创建均分的一维张量

torch.linspace(
    start = 0,
    end,      ## 包含end
    steps,    ## 数列长度
    out=None,
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

对数均分数列

创建对数均分的一维张量

torch.linspace(
    start = 0,
    end,      ## 包含end
    steps = 100,    ## 数列长度
    base=10.0,     ## 对数函数的底
    out=None,
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

对角矩阵

二维张量(默认为方阵)

torch.eye(
    n,      ## 行数
    m = None,      ## 列数
    out=None,
    dtype = None,
    layout = torch.strided,   ## 内存中的布局形式
    device = None,
    require_grad = False
)

1.2.3 依概率分布生成张量

生成正态分布张量

t = torch.normal(mean=0, std=1,size=(3,3))
​
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t_normal = torch.normal(mean, std)
t_normal

t_normal = tensor([ 1.3724, 3.6892, 0.4200, -5.6512])

均匀分布

torch.rand、torch.rand_like:生成0-1均匀分布

torch.randint、torch.randint_like:生成【low,high)之间的整数均匀分布

随机分布

torch.randperm:生成从0到n-1的随机排列

t = torch.randperm(n=5, dtype=torch.float)

t = tensor([1., 3., 2., 4., 0.])

伯努利分布(0-1分布)

t = torch.bernoulli(input=torch.linspace(0,1,10))

1.3 张量操作

1.3.1 张量的拼接与切分

torch.cat/torch.stack

torch.cat(
    tensors,
    dim = 0,    ## 拼接的维度
    out = None
)

torch.cat:将张量按维度dim进行拼接

torch.stack:在新创建的维度dim上进行拼接

t = torch.ones((2,3))
​
t_0 = torch.cat([t,t], dim=0)    ## 按行拼接
t_1 = torch.cat([t,t], dim=1)    ## 按列拼接

torch.chunk

torch.chunk(
    tensors,
    chunks,    ## 切分的分数
    dim = 0    ## 切分维度
)

torch.chunk将张量按维度dim进行平均切分

torch.chunk(t_1, chunks=3, dim=1)

切分结果:

(tensor([[1., 1.],
         [1., 1.]]),
 tensor([[1., 1.],
         [1., 1.]]),
 tensor([[1., 1.],
         [1., 1.]]))

torch.split

torch.split(
    tensors,
    split_size_or_sections,    ## 为int时,表示每一份的长度;为list时,按list元素切分
    dim = 0    ## 切分维度
)

torch.split(t_1, split_size_or_sections=[2,3,1], dim=1)

切分结果:

(tensor([[1., 1.],
         [1., 1.]]),
 tensor([[1., 1., 1.],
         [1., 1., 1.]]),
 tensor([[1.],
         [1.]]))

1.3.2 张量索引

t = torch.randint(0,9,size=(3,3))
idx = torch.tensor([0,2], dtype = torch.long)
t_select = torch.index_select(t, dim=0, index=idx)
print(t)
print(t_select)

结果:

tensor([[3, 0, 0],
        [2, 0, 3],
        [5, 6, 8]])
tensor([[3, 0, 0],
        [5, 6, 8]])

torch.masked_select

按mask中的True进行索引

t = torch.randint(0,9,size=(3,3))
mask = t.ge(5)    ## 判断元素是否大于等于5
t_select = torch.masked_select(t, mask=mask)
print(t)
print(t_select)

返回:

tensor([[0, 7, 5],
        [0, 2, 8],
        [8, 8, 0]])
tensor([7, 5, 8, 8, 8])

torch.reshape

变换张量形状

t = torch.randint(0,9,size=(3,3))
torch.reshape(t, (1,9))

1.3.3 张量变换

torch.transpose

交换张量的两个维度(矩阵的转置)

torch.transpose(input, dim0, dim1)

torch.t

2维张量转置,对矩阵而言,等价于

torch.transpose(input, 0, 1)

torch.squeeze

压缩长度为1的维度(轴)

若dim为None,移除所有长度为1的轴;若指定维度,当且仅当该轴长度为1时,可以被移除;

t = torch.randint(0,9,size=(3,3,1))
t_s = torch.squeeze(t)
print(t.shape)
print(t_s.shape)

torch.unsqueeze

依据dim扩展维度,长度为1

你可能感兴趣的:(pytorch基础,python,numpy,机器学习,pytorch)