Pytorch———(1)

续上篇Pytorch———(0)

三、张量和张量学习

        张量可以分成多箱,小的箱可以沿着行或列的维度创建,下面的例子展示了一个(4,4)张量,量,并且用到了第三个关于维度的参数,如0维或1维。

a = torch.randn(4, 4)
print(a)
torch.chunk(a,2)  # 分成两箱
tensor([[-0.5899, -1.3432, -1.0576, -0.1696],
[ 0.2623, -0.1585, 1.0178, -0.2216],
[-1.1716, -1.2771, 0.8073, -0.7717],
[ 0.1768, 0.6423, -0.3200, -0.0480]])

#分成两箱结果 默认0维
(tensor([[-0.5899, -1.3432, -1.0576, -0.1696],
[ 0.2623, -0.1585, 1.0178, -0.2216]]),
tensor([[-1.1716, -1.2771, 0.8073, -0.7717],
[ 0.1768, 0.6423, -0.3200, -0.0480]]))

torch.chunk(a,2,0)  # 沿0维 分成两箱 和上式是一样的
(tensor([[-0.5899, -1.3432, -1.0576, -0.1696], [ 0.2623, -0.1585, 1.0178, -0.2216]]), tensor([[-1.1716, -1.2771, 0.8073, -0.7717], [ 0.1768, 0.6423, -0.3200, -0.0480]]))

torch.chunk(a,2,1)  # 沿1维分成两箱,即将(4,4)张量在列方向上分成两箱;
(tensor([[-0.5899, -1.3432], [ 0.2623, -0.1585], [-1.1716, -1.2771], [ 0.1768, 0.6423]]), tensor([[-1.0576, -0.1696], [ 1.0178, -0.2216], [ 0.8073, -0.7717], [-0.3200, -0.0480]]))

聚合函数收集

     gather函数收集张量元素并按照索引参数放置到另一个张量,索引位置由LongTensor函数确定。

torch.gather(torch.Tensor([[11,12],[23,24]]), 1,torch.LongTensor([[0,0],[1,0]]))
tensor([[11., 11.], [24., 23.]])  # 上式在1维方向上按索引位置生成新张量,如[0,0]表示分量[11,12]中按0,0索引选取,因此新分量就是[11,11]。

      LongTensor函数和索引选择函数可以用来选取张量中相关元素。下面的代码显示了两种方式,按行或者按列选。如第二参数是0,则按行选,若是1则按列选。 

a = torch.randn(4, 4)
print(a)
tensor([[-0.9183, -2.3470, 1.5208, -0.1585],
[-0.6741, -0.6297, 0.2581, -1.1954],
[ 1.0443, -1.3408, 0.7863, -0.6056],
[-0.6946, -0.5963, 0.1936, -2.0625]])
indices = torch.LongTensor([0, 2])
torch.index_select(a, 0, indices) #按行选,选取第1和第3行;
tensor([[-0.9183, -2.3470, 1.5208, -0.1585], [ 1.0443, -1.3408, 0.7863, -0.6056]])
torch.index_select(a, 1, indices) 按列选,则每行选取第1、第2元素;
tensor([[-0.9183, 1.5208], [-0.6741, 0.2581], [ 1.0443, 0.7863], [-0.6946, 0.1936]])

     检测非缺失值是常见操作,在大的张量中,通常是检测非0的元素。

# 使用nonzero函数检测张量中的非0元素。

torch.nonzero(torch.tensor([10,00,23,0,0.0]))
tensor([[0], [2]])

torch.nonzero(torch.Tensor([10,00,23,0,0.0]))
tensor([[0], [2]])

      重构输入张量至小的张量,不仅可以加速运算,而且可以构建分布式计算。split函数可以将长张量变成小的张量。

 # 将张量分成小箱
      torch.split(torch.tensor([12,21,34,32,45,54,56,65]),2)
      (tensor([12, 21]), tensor([34, 32]), tensor([45, 54]), tensor([56, 65]))
  # 将张量分成小箱,余数分至最后一箱。
      torch.split(torch.tensor([12,21,34,32,45,54,56,65]),3)
      (tensor([12, 21, 34]), tensor([32, 45, 54]), tensor([56, 65]))

      torch.zeros(3,2,4)
       tensor([[[0., 0., 0., 0.], [0., 0., 0., 0.]], [[0., 0., 0., 0.], [0., 0., 0., 0.]], [[0., 0., 0., 0.], [0., 0., 0., 0.]]])

      torch.zeros(3,2,4).size()
      torch.Size([3, 2, 4])

     现在展示在给定计算复杂度下如何重整张量,有两个函数 .t 和 .transpose。

x
tensor([[-1.5343, -1.3533, -0.8621, -1.1674, -0.1114], [ 0.2790, 0.0463, 1.5364, -0.1287, 0.6379], [-0.4542, 0.5196, 0.2335, -0.5135, -0.6602], [-0.6930, 0.0541, -0.8463, -0.4498, -0.0280]])

x.t() # transpose 是改变张量的形状的一个方法;
tensor([[-1.5343, 0.2790, -0.4542, -0.6930], [-1.3533, 0.0463, 0.5196, 0.0541], [-0.8621, 1.5364, 0.2335, -0.8463], [-1.1674, -0.1287, -0.5135, -0.4498], [-0.1114, 0.6379, -0.6602, -0.0280]])

x.transpose(1,0)  # 基于行和列部分转置 如,交换0维和1维;
tensor([[-1.5343, 0.2790, -0.4542, -0.6930], [-1.3533, 0.0463, 0.5196, 0.0541], [-0.8621, 1.5364, 0.2335, -0.8463], [-1.1674, -0.1287, -0.5135, -0.4498], [-0.1114, 0.6379, -0.6602, -0.0280]])

#unbind函数用于 移除一个维度,移除行,用0,移除列用1。

torch.unbind(x,1) #dim=1 移除列维
(tensor([-1.5343, 0.2790, -0.4542, -0.6930]), tensor([-1.3533, 0.0463, 0.5196, 0.0541]), tensor([-0.8621, 1.5364, 0.2335, -0.8463]), tensor([-1.1674, -0.1287, -0.5135, -0.4498]), tensor([-0.1114, 0.6379, -0.6602, -0.0280]))


torch.unbind(x) #dim=0 移除行维
(tensor([-1.5343, -1.3533, -0.8621, -1.1674, -0.1114]), tensor([ 0.2790, 0.0463, 1.5364, -0.1287, 0.6379]), tensor([-0.4542, 0.5196, 0.2335, -0.5135, -0.6602]), tensor([-0.6930, 0.0541, -0.8463, -0.4498, -0.0280]))
x
tensor([[-1.5343, -1.3533, -0.8621, -1.1674, -0.1114], [ 0.2790, 0.0463, 1.5364, -0.1287, 0.6379], [-0.4542, 0.5196, 0.2335, -0.5135, -0.6602], [-0.6930, 0.0541, -0.8463, -0.4498, -0.0280]])

#使用基本的数学函数

torch.abs(torch.FloatTensor([-10, -23, 3.000]))  #转成FloatTensor , 再求绝对值;
tensor([10., 23., 3.])

#在Pytorch中,数学函数是实施任何算法的基础,所以以下是实施算术运算的函数。标量是单个值,1D张量是一行,像NumPy, 标量乘法和加法使用 add 和 mul 函数。下面代码展示了一个标量和张量的加法和乘法。

#标量加法,给一个张量加上一个标量值,所有元素都加上20
torch.add(x,20)

tensor([[18.4657, 18.6467, 19.1379, 18.8326, 19.8886], [20.2790, 20.0463, 21.5364, 19.8713, 20.6379], [19.5458, 20.5196, 20.2335, 19.4865, 19.3398], [19.3070, 20.0541, 19.1537, 19.5502, 19.9720]])

# 标量乘法,所有元素都乘标量
torch.mul(x,2)
tensor([[-3.0686, -2.7065, -1.7242, -2.3349, -0.2227], [ 0.5581, 0.0926, 3.0727, -0.2575, 1.2757], [-0.9084, 1.0392, 0.4670, -1.0270, -1.3203], [-1.3859, 0.1082, -1.6926, -0.8995, -0.0560]])

x  #  不改变原张量
tensor([[-1.5343, -1.3533, -0.8621, -1.1674, -0.1114], [ 0.2790, 0.0463, 1.5364, -0.1287, 0.6379], [-0.4542, 0.5196, 0.2335, -0.5135, -0.6602], [-0.6930, 0.0541, -0.8463, -0.4498, -0.0280]])

#组合数学运算,如如下的关于张量的线性方程运算。

# y = intercept + (beta * x)
intercept = torch.randn(1)
intercept
tensor([-1.1444])
x = torch.randn(2, 2)
x
tensor([[ 1.3517, -0.3991], [-0.4170, -0.1862]])  
beta = 0.7456
beta
0.7456

# 线性方程公式 ,Output = Constant + (beta * Independent),下面按此式依次计算。
torch.mul(x,beta)
tensor([[ 1.0078, -0.2976], [-0.3109, -0.1388]])
torch.add(x,beta,intercept)
tensor([[ 0.4984, -1.2524], [-1.2703, -1.0395]])

#演示乘法
torch.mul(intercept,x)
tensor([[-1.5469, 0.4568], [ 0.4773, 0.2131]])
torch.mul(x,beta)
tensor([[ 1.0078, -0.2976], [-0.3109, -0.1388]])


# y = (intercept * x)+ (beta * x) 
torch.add(torch.mul(intercept,x),torch.mul(x,beta)) # tensor y
tensor([[-0.5391, 0.1592], [ 0.1663, 0.0743]])

# 像Numpy一样,逐元素矩阵乘法也可以通过张量运算,有两种形式的矩阵运算:逐元素相乘和点积。

tensor
tensor([[[ 4, 64, 5, 4], [ 10, 20, 30, 110], [ 45, 34, 67, 40], [ 56, 67, 89, 90]]])
#逐元素相乘
tensor * tensor
tensor([[[ 16, 4096, 25, 16], [ 100, 400, 900, 12100], [ 2025, 1156, 4489, 1600], [ 3136, 4489, 7921, 8100]]])
torch.matmul(tensor, tensor) #矩阵乘法
tensor([[[ 1105, 1974, 2631, 7616], [ 7750, 9430, 12450, 13340], [ 5775, 8518, 9294, 10200], [ 9939, 13980, 16263, 19254]]])

    像NumPy 操作一样,张量值可以用ceiling 和 flooring函数取整:

#给张量值取整
torch.manual_seed(1234)
torch.randn(5,5)
tensor([[-0.1117, -0.4966, 0.1631, -0.8817, 0.0539], [ 0.6684, -0.0597, -0.4675, -0.2153, -0.7141], [-1.0831, -0.5547, 0.9717, -0.5150, 1.4255], [ 0.7987, -1.4949, 1.4778, -0.1696, -0.9919], [-1.4569, 0.2563, -0.4030, 0.4195, 0.9380]])
torch.manual_seed(1234)
torch.ceil(torch.randn(5,5))
tensor([[-0., -0., 1., -0., 1.], [ 1., -0., -0., -0., -0.], [-1., -0., 1., -0., 2.], [ 1., -1., 2., -0., -0.], [-1., 1., -0., 1., 1.]])
torch.manual_seed(1234)
torch.floor(torch.randn(5,5))
tensor([[-1., -1., 0., -1., 0.], [ 0., -1., -1., -1., -1.], [-2., -1., 0., -1., 1.], [ 0., -2., 1., -1., -1.], [-2., 0., -1., 0., 0.]])

     还可以使用min 和 max参数以及clamp函数, 对任一张量的值限制在一个范围内,clamp 函数可以用min和max 任一一个参数或两个参数。

# truncate 在 -0.3,0.4范围内截取值,即超出的取端点值,未超出的不变;
torch.manual_seed(1234)
torch.clamp(torch.floor(torch.randn(5,5)), min=-0.3, max=0.4)
tensor([[-0.3000, -0.3000, 0.0000, -0.3000, 0.0000], [ 0.0000, -0.3000, -0.3000, -0.3000, -0.3000], [-0.3000, -0.3000, 0.0000, -0.3000, 0.4000], [ 0.0000, -0.3000, 0.4000, -0.3000, -0.3000], [-0.3000, 0.0000, -0.3000, 0.0000, 0.0000]])
#truncate 只用min 截取
torch.manual_seed(1234)
torch.clamp(torch.floor(torch.randn(5,5)), min=-0.3)
tensor([[-0.3000, -0.3000, 0.0000, -0.3000, 0.0000], [ 0.0000, -0.3000, -0.3000, -0.3000, -0.3000], [-0.3000, -0.3000, 0.0000, -0.3000, 1.0000],

[ 0.0000, -0.3000, 1.0000, -0.3000, -0.3000], [-0.3000, 0.0000, -0.3000, 0.0000, 0.0000]])
#truncate 用max截取
torch.manual_seed(1234)
torch.clamp(torch.floor(torch.randn(5,5)), max=0.3)
tensor([[-1.0000, -1.0000, 0.0000, -1.0000, 0.0000], [ 0.0000, -1.0000, -1.0000, -1.0000, -1.0000], [-2.0000, -1.0000, 0.0000, -1.0000, 0.3000], [ 0.0000, -2.0000, 0.3000, -1.0000, -1.0000], [-2.0000, 0.0000, -1.0000, 0.0000, 0.0000]])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值