续上篇 Pytorch———(1)
三、张量和张量学习
如何计算张量的指数部分,如何计算浮点类型且有小数位的张量的小数部分,以下代码展示计算过程:
#标量除法
torch.div(x,0.10)
tensor([[13.5168, -3.9914], [-4.1705, -1.8621]])
#计算张量的指数
torch.exp(x)
tensor([[3.8639, 0.6709], [0.6590, 0.8301]])
np.exp(x)
tensor([[3.8639, 0.6709], [0.6590, 0.8301]])
#获取每个张量的小数部分
torch.add(x,10)
tensor([[11.3517, 9.6009], [ 9.5830, 9.8138]])
torch.frac(torch.add(x,10))
tensor([[0.3517, 0.6009], [0.5830, 0.8138]])
下面的代码展示了张量取对数, 负数值取对数转为Nan。幂函数power计算张量值的幂
# 计算对数结果
x
tensor([[ 1.3517, -0.3991], [-0.4170, -0.1862]])
torch.log(x) # 负数值的对数为nan
tensor([[0.3013, nan], [ nan, nan]])
# 通过幂函数,将value转为正数;
torch.pow(x,2)
tensor([[1.8270, 0.1593], [0.1739, 0.0347]])
# 通过round up四舍五入取整;
x
tensor([[ 1.3517, -0.3991], [-0.4170, -0.1862]])
np.round(x)
tensor([[1., -0.], [-0., -0.]])
torch.round(x)
tensor([[1., -0.], [-0., -0.]])
# 上面展示了既可以通过torch.round(),也可以通过np.round() 取整
为了计算转换函数(例如,sigmoid、Htan,径向基函数RBF等在深度学习中常用的函数),先构建张量,下面展示了如何创建一个sigmoid函数并应用到一个张量:
# 计算输入的sigmoid值
x
tensor([[ 1.3517, -0.3991], [-0.4170, -0.1862]])
torch.sigmoid(x)
tensor([[0.7944, 0.4015], [0.3972, 0.4536]])
#计算输入值的二次方根
x
tensor([[ 1.3517, -0.3991], [-0.4170, -0.1862]])
torch.sqrt(x)
tensor([[1.1626, nan], [ nan, nan]])
#创建一个张量,10至10000,150步长
x = torch.arange(10, 10000, 150)
x tensor([ 10, 160, 310, 460, 610, 760, 910, 1060, 1210, 1360, 1510, 1660, 1810, 1960, 2110, 2260, 2410, 2560, 2710, 2860, 3010, 3160, 3310, 3460, 3610, 3760, 3910, 4060, 4210, 4360, 4510, 4660, 4810, 4960, 5110, 5260, 5410, 5560, 5710, 5860, 6010, 6160, 6310, 6460, 6610, 6760, 6910, 7060, 7210, 7360, 7510, 7660, 7810, 7960, 8110, 8260, 8410, 8560, 8710, 8860, 9010, 9160, 9310, 9460, 9610, 9760, 9910])
print(f"Minimum: {x.min()}")
print(f"Maximum: {x.max()}")
# print(f"Mean: {x.mean()}") #这会出错
print(f"Mean: {x.type(torch.float32).mean()}") # 转换成 float type 后 才能计算均值
print(f"Sum: {x.sum()}")
Minimum: 10
Maximum: 9910
Mean: 4960.0
Sum: 332320
torch.argmax(x),torch.argmin(x) # 求最值的下标
(tnsor(66), tensor(0))
torch.max(x),torch.min(x) # 求最值
(tensor(9910), tensor(10))
# 改变数据类型。
y = torch.tensor([[39,339.63],
[36,667.20],
[33,978.07],
[31,897.13],
[29,178.19],
[26,442.25],
[24,314.22],
[21,547.88],
[18,764.25],
[16,588.23],
[13,773.61]],dtype=torch.float32)
# 改成float16类型的张量。
tensor_float16 = y.type(torch.float16)
tensor_float16
tensor([[ 39.0000, 339.7500], [ 36.0000, 667.0000], [ 33.0000, 978.0000], [ 31.0000, 897.0000], [ 29.0000, 178.2500], [ 26.0000, 442.2500], [ 24.0000, 314.2500], [ 21.0000, 548.0000], [ 18.0000, 764.0000], [ 16.0000, 588.0000], [ 13.0000, 773.5000]], dtype=torch.float16)
# 改成 int8型 张量。
tensor_int8 = y.type(torch.int8)
tensor_int8
tensor([[ 39, 83], [ 36, -101], [ 33, -46], [ 31, -127], [ 29, -78], [ 26, -70], [ 24, 58], [ 21, 35], [ 18, -4], [ 16, 76], [ 13, 5]], dtype=torch.int8)
# 改变视图,数据保持但是视图改变,由(11,2)——>(2,11)。
y.view(2,11)
tensor([[ 39.0000, 339.6300, 36.0000, 667.2000, 33.0000, 978.0700, 31.0000, 897.1300, 29.0000, 178.1900, 26.0000], [442.2500, 24.0000, 314.2200, 21.0000, 547.8800, 18.0000, 764.2500, 16.0000, 588.2300, 13.0000, 773.6100]])
# 堆置张量,可以按照不同的维度,0维方向,首先视A、B为(1,8)的两个张量,然后在(0维,)维度上堆置(本例就是整行堆置),因此变为(2,8)张量。1维方向,在(,1维)维度上(就是每个分量(整行)上的每列)堆叠,因此变成(8,2)张量。3维或3维以上依此类推。
A = torch.arange(10,50,5)
B = torch.arange(20,60,5)
torch.stack([A,B],dim=0)
tensor([[10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55]])
torch.stack([A,B],dim=1)
tensor([[10, 20], [15, 25], [20, 30], [25, 35], [30, 40], [35, 45], [40, 50], [45, 55]])
torch.stack([A,B])
tensor([[10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55]])
# 张量的索引。
y = torch.stack([A,B,A,B,A,B,A,B])
y
tensor([[10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55], [10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55], [10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55], [10, 15, 20, 25, 30, 35, 40, 45], [20, 25, 30, 35, 40, 45, 50, 55]])
# 获取0维和1维 第二分量对应的值。
y[:, 1]
tensor([15, 25, 15, 25, 15, 25, 15, 25])
D = torch.tensor([[[12,13,14],
[15,16,17],
[18,19,20]]])
# D 是一个(1,3,3)张量,获取0、1维所有和2维第二分量的值。
D[:, :, 1]
tensor([[13, 16, 19]])
# 获取0维 和1维2分量、2维2分量的值,因此只有一个值。
D[:, 1, 1]
tensor([16])
# 获取 0 维第1分量 、1维第1分量 和所有第2维的值。
D[0, 0, :] #等价于 D[0][0]
tensor([12, 13, 14])
D[0][0]
tensor([12, 13, 14])
# 检验GPU是否可用。
import torch
torch.cuda.is_available()
False
# 设置设备类型。
device = "cuda" if torch.cuda.is_available() else "cpu"
device
cpu
根据CUDA语义,PyTorch可以配置为GPU,https://pytorch.org/docs/stable/notes/cuda.html。
# 计算设备数量。
torch.cuda.device_count()
0
# x = torch.randn(2, 2, device='cpu') #on cpu 配置为CPU。
# x = torch.randn(2, 2, device='gpu') #on gpu 配置为GPU。
# x = torch.randn(2, 2, device=device) # 配置为变量所指类型。
# 生成随机数字是设备透明的,所以CPU和GPU都适用。
# 像Numpy数组一样展开张量。
D.flatten()
tensor([12, 13, 14, 15, 16, 17, 18, 19, 20])
# 沿着0维拼接,将0维元素逐个拼接,A,B在本例中只有1个维度--0维。
cat_rows = torch.cat((A, B), dim=0)
cat_rows
tensor([10, 15, 20, 25, 30, 35, 40, 45, 20, 25, 30, 35, 40, 45, 50, 55])
#沿着1维列方向(1维方向上每个拼接张量的元素是一个(2,1)分量)拼接,因此依(2,4)cat (2,4) 变成 (2,8)张量。
#如果(2,4)cat (2,4) 沿 0维(0维方向上每个拼接张量的元素是一个(1,4)分量)拼接,因此变成(4,4)张量。
cat_cols = torch.cat((A.reshape(2,4), B.reshape(2,4)), dim=1)
cat_cols
tensor([[10, 15, 20, 25, 20, 25, 30, 35], [30, 35, 40, 45, 40, 45, 50, 55]])
cat_rows = torch.cat((A.reshape(2,4), B.reshape(2,4)), dim=0)
cat_rows
tensor([[10, 15, 20, 25], [30, 35, 40, 45], [20, 25, 30, 35], [40, 45, 50, 55]])