pytorch基础学习(2)

  1. 判断tensorc1和c2每个元素是否相同:
    torch.all(torch.eq(c1, c2))
  2. 矩阵乘法:对于高维(dim>2)的Tensor,定义其矩阵乘法仅在最后的两个维度上,要求前面的维度必须保持一致(此处的一致包括自动broadcasting后的一致),就像矩阵的索引一样。
    torch.matmul(c,d)
  3. 近似值操作:
    a.floor(), a.ceil(), a.trunc(), a.frac())  # 取下,取上,取整数,取小数 
    c.round())  # 四舍五入
  4. 裁剪:即对Tensor中的元素进行范围过滤,不符合条件的可以把它变换到范围内部(边界)上,常用于梯度裁剪(gradient clipping),即在发生梯度离散或者梯度爆炸时对梯度的处理。
    # 实际使用时可以查看梯度的(L2范数)模来看看需不需要做处理:w.grad.norm(2)。
    grad.clamp(10))  # 最小是10,小于10的都变成10
    print(grad.clamp(3, 10))  # 最小是3,小于3的都变成3;最大是10,大于10的都变成10
  5. 求范数:很多操作都是可以指定维度的
    # 求L1范数(所有元素绝对值求和) 
    print(a.norm(1)
    
    # 求L2范数(所有元素的平方和再开根号) 
    print(a.norm(2)
    
    # 在b的1号维度上求L1范数
    print(b.norm(1, dim=1))
  6. 累积:
    tensor.prod()
  7. 最小最大值索引:
    print(b.argmax(), b.argmin())
     
    1. 在维度上求最值索引:
      c.argmax(dim=1))
    2. 直接使用max和min配合dim参数也可以获得最值索引,同时得到最值的具体值(在上面的这种语境下就是置信度了):
      print(c.max(dim=1))
      # 运行结果:(tensor([0.9589, 1.7394, 1.3448, 2.2079]), tensor([2, 2, 5, 7]))
    3. 使用keepdim=True可以保持应有的dim,即仅仅是将求最值的那个dim的size变成了1,返回的结果是符合原Tensor语义的:
      print(c.argmax(dim=1, keepdim=True))
      print(c.max(dim=1, keepdim=True))
  8.  前k大/前k小/第k小:使用topk代替max可以完成更灵活的需求,有时候不是仅仅要概率最大的那一个,而是概率最大的k个。如果不是求最大的k个,而是求最小的k个,只要使用参数largest=False:
    d = torch.randn(2, 10)  # 2个样本,分为10个类别的置信度
    print(d.topk(3, dim=1))  # 最大的3个类别
    print(d.topk(3, dim=1, largest=False))  # 最小的3个类别
    print(d.kthvalue(8, dim=1))  # 求第8小(一共10个那就是第3大)
  9. where:使用C=torch.where(condition,A,B)其中A,B,C,condition是shape相同的Tensor,C中的某些元素来自A,某些元素来自B,这由condition中相应位置的元素是1还是0来决定:
    import torch
    cond = torch.tensor([[0.6, 0.1], [0.2, 0.7]])
    a = torch.tensor([[1, 2], [3, 4]])
    b = torch.tensor([[4, 5], [6, 7]])
    c = torch.where(cond > 0.5, a, b)
  10. 因为进行Softmax操作涉及到组内的其它结点的值,所以要特别注意dim的设置:
    p = F.softmax(y, dim=0)
  11. 自动求导:
    # 计算p1对y0,y1,y2的导数
    print(torch.autograd.grad(p[1], [y], retain_graph=True))
    # 计算p2对y0,y1,y2的导数
    print(torch.autograd.grad(p[2], [y]))
  12. 注意MSE和L2范数相比,L2范数是做了开平方操作的,所以如果要使用它来求MSE,最后只要.pow(2)平方一下就可以了。
  13. 交叉熵损失既可以用于二分类,也适用于多分类,并且往往和Softmax激活函数搭配使用
  14. 使用pytorch求导:
    1. 使用自动求导:
      res = torch.autograd.grad(mse, [w])  # 让MSE对参数w自动求导
      # 注意在前面定义完w后将其设置为需要梯度信息,否则上一句会报错
      w = torch.full([1], 2)    
      w.requires_grad_()
      # 也可以在建立Tensor时用参数指明它需要梯度信息:
      w = torch.full([1], 2, requires_grad=True)
    2. 自动向图的反向搜索,求出相对于这个MSE的导数来:
      mse.backward()
      #注意,这个API会将之前的梯度信息覆盖掉,所以多次调用这个LOSS对象的.backward()方法时会报错,如果要再次调用以生成新的梯度信息,要给它一个参数:mse.backward(retain_graph=True)
  15. @符号相当于矩阵乘积
  16. 多层感知机:只要设置多组w,即为w这个Tensor前面添加一个"组"的维度即可。
    # 这里有两组w,也就输出到了2个结点上
    w = torch.randn(2, 10, requires_grad=True)
    # 对输出用sigmoid激活
    o = torch.sigmoid(x @ w.t())
  17. 网络反向传播:
    # 当网络参量进行反馈时,梯度是被积累的而不是被替换掉,这里即每次将梯度设置为0: 
    optimizer.zero_grad()
    # 生成当前所在点函数值相关的梯度信息,这里即优化目标的梯度信息
    pred.backward()
    # 使用梯度信息更新优化目标的值,即更新x[0]和x[1]
    optimizer.step()
  18. 回归和分类本质的区别:
    1. 对于回归问题,目标是让预测值和真实值的差距d i s t ( p r e d − y ) dist(pred-y)dist(pred−y)最小,可以直接对其进行minimize。
    2. 而对于分类问题,目标是优化那些分类指标,比如accuracy、F1-score或者AUC等。
    3. 预测的是连续的还是离散的值,导致了回归和分类的本质区别。
    4. 两者最本质的区别在于分类问题并不能直接去对目标进行最优化,而回归问题可以直接对LOSS进行minimize来求解。要对分类问题的目标优化,可以用分布去拟合样本的分布,然后对分布的参数进行调整。
  19. 可以将Entropy理解为uncertainty,Entropy越高则信息量越小
  20. KL Divergence(KL散度),用来衡量两个分布(P和Q)之间的不相似性。
  21. 在测试集上的loss反映了模型的表现:
    logits = forward(data)
    test_loss += CEL(logits, target).item()
    """
    得到的预测值输出是一个10个分量的概率,在第2个维度上取max
    logits.data是一个shape=[batch_size,10]的Tensor
    注意Tensor.max(dim=1)是在这个Tensor的1号维度上求最大值
    得到一个含有两个元素的元组,这两个元素都是shape=[batch_size]的Tensor
    第一个Tensor里面存的都是最大值的值,第二个Tensor里面存的是对应的索引
    这里要取索引,所以取了这个tuple的第二个元素
    print(type(logits.data), logits.data.shape,type(logits.data.max(dim=1)))
    """
    pred = logits.data.max(dim=1)[1]

猜你喜欢

转载自blog.csdn.net/weixin_45647721/article/details/128161199