- 判断tensorc1和c2每个元素是否相同:
torch.all(torch.eq(c1, c2))
- 矩阵乘法:对于高维(dim>2)的Tensor,定义其矩阵乘法仅在最后的两个维度上,要求前面的维度必须保持一致(此处的一致包括自动broadcasting后的一致),就像矩阵的索引一样。
torch.matmul(c,d)
- 近似值操作:
a.floor(), a.ceil(), a.trunc(), a.frac()) # 取下,取上,取整数,取小数 c.round()) # 四舍五入
- 裁剪:即对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
- 求范数:很多操作都是可以指定维度的
# 求L1范数(所有元素绝对值求和) print(a.norm(1) # 求L2范数(所有元素的平方和再开根号) print(a.norm(2) # 在b的1号维度上求L1范数 print(b.norm(1, dim=1))
- 累积:
tensor.prod()
- 最小最大值索引:
print(b.argmax(), b.argmin())
- 在维度上求最值索引:
c.argmax(dim=1))
- 直接使用max和min配合dim参数也可以获得最值索引,同时得到最值的具体值(在上面的这种语境下就是置信度了):
print(c.max(dim=1)) # 运行结果:(tensor([0.9589, 1.7394, 1.3448, 2.2079]), tensor([2, 2, 5, 7]))
- 使用keepdim=True可以保持应有的dim,即仅仅是将求最值的那个dim的size变成了1,返回的结果是符合原Tensor语义的:
print(c.argmax(dim=1, keepdim=True)) print(c.max(dim=1, keepdim=True))
- 在维度上求最值索引:
- 前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大)
- 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)
- 因为进行Softmax操作涉及到组内的其它结点的值,所以要特别注意dim的设置:
p = F.softmax(y, dim=0)
- 自动求导:
# 计算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]))
- 注意MSE和L2范数相比,L2范数是做了开平方操作的,所以如果要使用它来求MSE,最后只要.pow(2)平方一下就可以了。
- 交叉熵损失既可以用于二分类,也适用于多分类,并且往往和Softmax激活函数搭配使用
- 使用pytorch求导:
- 使用自动求导:
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)
- 自动向图的反向搜索,求出相对于这个MSE的导数来:
mse.backward() #注意,这个API会将之前的梯度信息覆盖掉,所以多次调用这个LOSS对象的.backward()方法时会报错,如果要再次调用以生成新的梯度信息,要给它一个参数:mse.backward(retain_graph=True)
- 使用自动求导:
- @符号相当于矩阵乘积
- 多层感知机:只要设置多组w,即为w这个Tensor前面添加一个"组"的维度即可。
# 这里有两组w,也就输出到了2个结点上 w = torch.randn(2, 10, requires_grad=True) # 对输出用sigmoid激活 o = torch.sigmoid(x @ w.t())
- 网络反向传播:
# 当网络参量进行反馈时,梯度是被积累的而不是被替换掉,这里即每次将梯度设置为0: optimizer.zero_grad() # 生成当前所在点函数值相关的梯度信息,这里即优化目标的梯度信息 pred.backward() # 使用梯度信息更新优化目标的值,即更新x[0]和x[1] optimizer.step()
- 回归和分类本质的区别:
- 对于回归问题,目标是让预测值和真实值的差距d i s t ( p r e d − y ) dist(pred-y)dist(pred−y)最小,可以直接对其进行minimize。
- 而对于分类问题,目标是优化那些分类指标,比如accuracy、F1-score或者AUC等。
- 预测的是连续的还是离散的值,导致了回归和分类的本质区别。
- 两者最本质的区别在于分类问题并不能直接去对目标进行最优化,而回归问题可以直接对LOSS进行minimize来求解。要对分类问题的目标优化,可以用分布去拟合样本的分布,然后对分布的参数进行调整。
- 可以将Entropy理解为uncertainty,Entropy越高则信息量越小
- KL Divergence(KL散度),用来衡量两个分布(P和Q)之间的不相似性。
- 在测试集上的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]
pytorch基础学习(2)
猜你喜欢
转载自blog.csdn.net/weixin_45647721/article/details/128161199
今日推荐
周排行