张量的数据类型

张量的数据类型和numpy.array基本一一对应,但是不支持str类型。
包括:

torch.float64(torch.double), torch.float32(torch.float), torch.float16, torch.int64(torch.long), torch.int32(torch.int), torch.int16, torch.int8, torch.uint8, torch.bool

一般神经网络建模使用的都是torch.float32类型。

  1. import numpy as np
  2. import torch
  3. # 自动推断数据类型
  4. i = torch.tensor(1)
  5. print(i,i.dtype)
  6. x = torch.tensor(2.0)
  7. print(x,x.dtype)
  8. b = torch.tensor(True)
  9. print(b,b.dtype)

image.png
指定数据类型

  1. i = torch.tensor(1,dtype = torch.int32)
  2. print(i,i.dtype)
  3. x = torch.tensor(2.0,dtype = torch.double)
  4. print(x,x.dtype)

image.png
使用特定类型构造函数

  1. i = torch.IntTensor(1)
  2. print(i,i.dtype)
  3. x = torch.Tensor(np.array(2.0))
  4. print(x,x.dtype) #等价于torch.FloatTensor
  5. b = torch.BoolTensor(np.array([1,0,2,0]))
  6. print(b,b.dtype)

image.png

  1. i = torch.tensor(1)
  2. print(i,i.dtype)
  3. x = i.float()
  4. print(x,x.dtype) #调用 float方法转换成浮点类型
  5. y = i.type(torch.float)
  6. print(y,y.dtype) #使用type函数转换成浮点类型
  7. z = i.type_as(x)
  8. print(z,z.dtype) #使用type_as方法转换成某个Tensor相同类型

image.png


张量的维度

不同类型的数据可以用不同维度(dimension)的张量来表示。
标量为0维张量,向量为1维张量,矩阵为2维张量。
彩色图像有rgb三个通道,可以表示为3维张量。
视频还有时间维,可以表示为4维张量。
可以简单地总结为:有几层中括号,就是多少维的张量。

  1. scalar = torch.tensor(True)
  2. print(scalar)
  3. print(scalar.dim()) # 标量,0维张量

image.png

  1. vector = torch.tensor([1.0,2.0,3.0,4.0]) #向量,1维张量
  2. print(vector)
  3. print(vector.dim())

image.png

  1. matrix = torch.tensor([[1.0,2.0],[3.0,4.0]]) #矩阵, 2维张量
  2. print(matrix)
  3. print(matrix.dim())

image.png

  1. tensor3 = torch.tensor([[[1.0,2.0],[3.0,4.0]],[[5.0,6.0],[7.0,8.0]]]) # 3维张量
  2. print(tensor3)
  3. print(tensor3.dim())

image.png

  1. tensor4 = torch.tensor([[[[1.0,1.0],[2.0,2.0]],[[3.0,3.0],[4.0,4.0]]],
  2. [[[5.0,5.0],[6.0,6.0]],[[7.0,7.0],[8.0,8.0]]]]) # 4维张量
  3. print(tensor4)
  4. print(tensor4.dim())

image.png


张量的尺寸

可以使用shape属性或者 size()方法查看张量在每一维的长度。
可以使用view方法改变张量的尺寸。
如果view方法改变尺寸失败,可以使用reshape方法.

  1. scalar = torch.tensor(True)
  2. print(scalar.size())
  3. print(vector.shape)

image.png

  1. vector = torch.tensor([1.0,2.0,3.0,4.0])
  2. print(vector.size())
  3. print(vector.shape)

image.png

  1. matrix = torch.tensor([[1.0,2.0],[3.0,4.0]])
  2. print(matrix.size())

image.png

  1. # 使用view可以改变张量尺寸
  2. vector = torch.arange(0,12)
  3. print(vector)
  4. print(vector.shape)
  5. matrix34 = vector.view(3,4)
  6. print(matrix34)
  7. print(matrix34.shape)
  8. matrix43 = vector.view(4,-1) #-1表示该位置长度由程序自动推断
  9. print(matrix43)
  10. print(matrix43.shape)

image.png

  1. # 有些操作会让张量存储结构扭曲,直接使用view会失败,可以用reshape方法
  2. matrix26 = torch.arange(0,12).view(2,6)
  3. print(matrix26)
  4. print(matrix26.shape)
  5. # 转置操作让张量存储结构扭曲
  6. matrix62 = matrix26.t()
  7. print(matrix62)
  8. print(matrix62.is_contiguous()) #Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致。
  9. # 直接使用view方法会失败,可以使用reshape方法
  10. #matrix34 = matrix62.view(3,4) #error!
  11. matrix34 = matrix62.reshape(3,4) #等价于matrix34 = matrix62.contiguous().view(3,4)
  12. print(matrix34)

image.png


张量和numpy数组

可以用numpy方法从Tensor得到numpy数组,也可以用torch.from_numpy从numpy数组得到Tensor。
这两种方法关联的Tensor和numpy数组是共享数据内存的。如果改变其中一个,另外一个的值也会发生改变。如果有需要,可以用张量的clone方法拷贝张量,中断这种关联。
此外,还可以使用item方法从标量张量得到对应的Python数值。
使用tolist方法从张量得到对应的Python数值列表。

  1. #torch.from_numpy函数从numpy数组得到Tensor
  2. arr = np.zeros(3)
  3. tensor = torch.from_numpy(arr)
  4. print("before add 1:")
  5. print(arr)
  6. print(tensor)
  7. print("\nafter add 1:")
  8. np.add(arr,1, out = arr) #给 arr增加1,tensor也随之改变。“out”参数指定结果存储的位置。
  9. print(arr)
  10. print(tensor)

image.png

  1. # numpy方法从Tensor得到numpy数组
  2. tensor = torch.zeros(3)
  3. arr = tensor.numpy()
  4. print("before add 1:")
  5. print(tensor)
  6. print(arr)
  7. print("\nafter add 1:")
  8. #使用带下划线的方法表示计算结果会返回给调用 张量
  9. tensor.add_(1) #给 tensor增加1,arr也随之改变
  10. #或: torch.add(tensor,1,out = tensor)
  11. print(tensor)
  12. print(arr)

image.png

  1. # 可以用clone() 方法拷贝张量,中断这种关联
  2. tensor = torch.zeros(3)
  3. #使用clone方法拷贝张量, 拷贝后的张量和原始张量内存独立
  4. arr = tensor.clone().numpy() # 也可以使用tensor.data.numpy()
  5. print("before add 1:")
  6. print(tensor)
  7. print(arr)
  8. print("\nafter add 1:")
  9. #使用 带下划线的方法表示计算结果会返回给调用 张量
  10. tensor.add_(1) #给 tensor增加1,arr不再随之改变
  11. print(tensor)
  12. print(arr)

image.png

  1. # item方法和tolist方法可以将张量转换成Python数值和数值列表
  2. scalar = torch.tensor(1.0)
  3. s = scalar.item()
  4. print(s)
  5. print(type(s))
  6. tensor = torch.rand(2,2)
  7. t = tensor.tolist()
  8. print(t)
  9. print(type(t))

image.png