Pytorch之基础知识

基本数据类型
  • torch.FloatTensor, torch.ByteTensor, torch.IntTensor
a = torch.randn(2, 3) # 随机生成2行3列的tensor, randn代表满足N(0,1)正态分布
a.type() # 'torch.FloatTensor'
isinstance(a, torch.FloatTensor) # True      参数类型检验
isinstance(a, torch.cuda.FloatTensor) # False
a = a.cuda()
isinstance(a, torch.cuda.FloatTensor) # True
创建tensor
  • 大写Tensor的参数是size随机初始化,小写tensor的参数是具体的数据

  • torch.ones(), torch.empty(), torch.rand(), torch.randn() 参数是size

  • np.array() 参数是具体的数据

# 生成0维标量
a = torch.tensor(1.3) # tensor(1.300)
a.shape / a.size() # torch.Size([])
len(a.shape) # 0

# 生成1维张量
torch.tensor([1.3]) # tensor([1.300])
torch.tensor([1.1, 1.2]) # tensor([1.100, 1.200])
torch.FloatTensor(2) # 1*2大小的随机初始化的tensor(省略1)
a = torch.ones(2) a.shape # torch.Size([2])  1*2(省略1)

# 生成2维张量
a = torch.randn(2, 3) 
torch.FloatTensor(23) # 2*3大小的随机初始化的tensor
a.shape # torch.Size([2,3])
a.shape[1] # 3
a.size(1) # 3

# 生成3维向量
a = torch.rand(1, 2, 3) # 随机生成3维的tensor,rand代表服从均匀分布
a.shape # torch.Size([1,2,3])
list(a.shape) # [1, 2, 3]
a.numel() # 6 = 1 * 2 * 3
a.dim() # 3

# import from numpy (numpy 默认double类型)
data = np.array([2, 3.3]) # array([2.0000, 3.3000])
data = np.ones(2) # array([1. ,1. ]), 1*2(省略1)
torch.from_numpy(data) # tensor([1. ,1. ], dtype=torch.float64)

# import from list
# 大写Tensor的参数是size随机初始化,小写tensor的参数是具体的数据
torch.tensor([[2., 3.2],[1., 22.3]]) 
torch.empty() # 与torch.ones()类似,参数是size,初始化为0

# torch.tensor()的默认数据类型是 'torch.FloatTensor'
# 更改默认数据类型:torch.set_default_tensor_type(torch.DoubleTensor)
索引和切片
# 索引
a = torch.rand(4,3,28,28)
a[0].shape   # torch.Size([3,28,28])
a[0,0].shape # torch.Size([28,28])
a[0,0,2,4]   # tensor(0.8082)

# 切片
a[:2].shape  			   # torch.Size([2,3,28,28]) 左侧包含右侧不包含
a[:2,-1:,:,:].shape 	   # torch.Size([2,1,28,28])
a[:,:,0:28:2,0:28:2].shape # torch.Size([4,3,14,14]) 第二个冒号后代表步长
a[:,:,::2,::2].shape	   # torch.Size([4,3,14,14]) 和上面等价
# 索引
a.index_select(0, torch.tensor([0,2])).shape # 第0维中第0张和第2张图片,torch.Size([2,3,28,28])
a.index_select(2, torch.arange(0,8)).shape # torch.Size([4,3,8,28])
a[0,...].shape # torch.Size([3,28,28]), 省略号代表省略的维度取满

使用mask索引

Pytorch之基础知识_第1张图片

维度变换
  • view():参数为size

  • unsqueeze() :插入输入的维度

  • squeeze() : 删除输入的维度

    • 如果没有输入则删除所有长度为1的维度
    • 如果删除的维度长度不为1,则删除失败
  • expand : 维度扩展,参数是扩展后的size

  • repeat : 维度扩展,参数是扩展倍数

  • transpose : 维度交换

  • permute : 维度重排

# view :大小变化
a = torch.rand(4,1,28,28)
a.view(4, 28*28) 		# torch.Size([4, 784])
a.shape 		 		# torch.Size([4,1,28,28])
# unsqueeze :插入输入的维度,维度增加
a.unsqueeze(0).shape 	# torch.Size([1,4,1,28,28])
a.unsqueeze(-4).shape   # torch.Size([4,1,1,28,28])
# squeeze : 删除输入的维度,维度减少 
a.squeeze(0).shape      # torch.Size([4,1,28,28])
a.squeeze(1).shape		# torch.Size([4,28,28])

# expand : 维度扩展,被扩张的维度长度只能是1
a = torch.rand(4,32,14,14)
b = torch.rand(1,32, 1, 1)
b.expand(4,32,14,14).shape # torch.Size([4,32,14,14])
# repeat : 维度扩展,内存复制,参数是扩展倍数
b = torch.rand(1,32,1,1)
b.repeat(4,32,1,1)         # torch.Size([4,1024,1,1])
# 转置:b.t(), 其中b只能为2维张量(即矩阵)

# transpose : 维度交换
a.shape # torch.Size([4,3,32,32])
a.transpose(1,3) # torch.Size([4,32,32,3])
a1=a.transpose(1,3).contiguous().view(4,3072).view(4,32,32,3).transpose(1,3) # 此时a1与a相等,要注意维度的对应
# permute : 一次性的维度重排
a.shape # torch.Size([4,3,28,32])
a.permute(0,2,3,1) # torch.Size([4,28,32,3])
broadcast广播
  • 在前面插入新维度,并扩张为对应的size (此过程中数值采取复制的形式)

    feature map : [4, 32, 14, 14] bias : [32,1,1] — [1,32,1,1] — [4,32,14,14]

拼接与拆分
  • cat : 拼接, 在某一维度拼接,其余维度的size必须相同
  • stack : 拼接,新增对应输入维度,该维度取0,1分别对应拼接的两个张量
  • split : 按长度拆分
  • chunk:按数量拆分
# cat
a = torch.rand(4,32,8)
b = torch.rand(5,32,8)
torch.cat([a,b],dim=0).shape     # torch.Size([9,32,8])
# stack (拼接的两个张量的size必须完全相同)
a1 = torch.rand(4,3,16,32)
a2 = torch.rand(4,3,16,32)
torch.cat([a1,a2],dim=2).shape   # torch.Size([4,3,32,32])
torch.stack([a1,a2],dim=2).shape # torch.Size([4,3,2,16,32])

# split 
c.shape 						 # torch.Size([3,32,8])
a,b = c.split([1,2],dim=0) 		 
a.shape					 		 # torch.Size([1,32,8])
b.shape							 # torch.Size([2,32,8])
# chunk
c.shape							 # torch.Size([2,32,8])
a,b = c.chunk(2,dim=0)			 # a,b : torch.Size([1,32,8])
数学运算
  • 加减乘除 : add,sub,mul,div (element-wise)
  • 矩阵相乘 : torch.matmul(a,b)
  • 幂 : pow (element-wise)
  • 开方 : sqrt (element-wise) , rsqrt (平方根后取倒数)
  • 取整
    • a.floor() : 下取整 a.ceil() :上取整
    • a.trunc() : 取整数部分 a.frac() : 取小数部分
    • a.round() : 四舍五入
# 四则运算
a = torch.rand(3,4)
b = torch.rand(4)
a+b / torch.add(a,b) # broadcast机制,b->[3,4]
# 高维张量乘法 :
# 只取最后的两维运算,前面不变(前面要求一样或者可经过broadcast变成一样)

# 幂
a = torch.full([2,2],3) # size 2*2, 值全为3
a.pow(2)     # tensor([[9.,9.],[9.,9.]])
a.sqrt()	 # tensor([[3.,3.],[3.,3.]])

a = torch.exp(torch.ones(2,2)) # [[1,1],[1,1]] -> [[e,e],[e,e]]
a = torch.log(a)               # [[e,e],[e,e]] -> [[1,1],[1,1]]

# 矩阵操作
grad = torch.rand(2,3)
grad.max() grad.min() grad.median()
grad.clamp(min,max) # 把矩阵中元素限制在min-max之间
统计属性
  • 范数 norm :
    • a.norm(2)代表对所有元素求2-范数
    • a.norm(2, dim=1)代表对1维度上的所有元素求2-范数
  • a.mean(),a.min(),a.max(),a.sum(),a.prod()累乘
  • a.argmax()最大元素的下标,a.argmax(dim=1)在维度1上求最大元素的下标,如果a是二维可以看成求每行最大元素的下标作为该行的元素。
  • torch.eq(a,b):每一位相比较,相等结果为1,不等结果为0
  • torch.equal(a,a): 返回True或者False, 代表整体是否相等
a.max(dim=1,keepdim=True)    # keepdim置True代表使得统计前后维数不变
a.topk(3,dim=1,largest=True) # 与max类似,只不过不是求最大的1个,而是最大的k个
a.kthvalue(8,dim=1)          # 找1维度上第8小的元素值
高阶操作
  • where : 三个参数,condition,x,y 表示张量每个位置的元素来自x还是y
  • gather: 三个参数,参照表,维度,原始表 该API的功能就是把原始表的对应维度,按照参照表的对应关系进行变换,形成一个新表
# where
condition     # [[0.6769,0.7271],[0.8884,0.4143]]
a             # [[0,0],[0,0]]
b			  # [[1,1],[1,1]]
torch.where(condition>0.5,a,b)  # [[0,0],[0,1]],满足条件的位置取a,反之取b
# gather
origin 		  # [[7,4,9],[7,4,9][8,1,3],[8,6,0]]
reference	  # [100,101,...,109]
torch.gather(reference.expand(4,10),dim=1,index=origin)
# [[107,104,109],[107,104,109][108,101,103],[108,106,100]]
Visdom可视化

首先开启一个监听进程:python -m visdom.server

from visdom import Visdom
viz = Visdom()
# 下面两句话完成了创建小窗口只有原点,不断地把loss.item()的点添加到图上形成曲线
# 创建小窗口,从左至右 :Y X ID 名字 
# 默认环境为 main
viz.line([0.], [0.], win='train_loss', opts=dict(title='train_loss'))
# 画线,从左至右:Y X 添加
viz.line([loss.item()],[global_step],win='train_loss',update='append')

# 多条曲线 
# Y1,Y2 X ID 名字, legend代表y1,y2的图标
viz.line([0.00.0], [0.], win='test',opts=dict(title='test loss&acc', legend=['loss','acc']))
viz.line([[test_loss,correct/len(test_loader.dataset)]],[global_step],win='test',update='append')

# 可视化 (numpy数据或图像)
viz.images(data.view(-1,1,28,28), win='x')
viz.text(str(pred.detach().cpu().numpy()),win='pred',opts=dict(title='pred'))
','acc']))
viz.line([[test_loss,correct/len(test_loader.dataset)]],[global_step],win='test',update='append')

你可能感兴趣的:(Pytorch,深度学习,pytorch)