1 遇到问题报错:
RuntimeError: cudaEventSynchronize in future::wait: device-side assert triggered
一个博客的作者解释这个问题如下:
这个问题很诡异。。如果你用的是BCECriterion(),然后你的网络最后一层不是sigmoid,就会出这个错误。因为BCECriterion的期望输入是[0,1]。不加sigmoid很可能会出现输入不满足这个条件,至于为什么会是这个错误,那真不得而知。
然后我就想,能不能找一个 函数使得其功能与BCECriterion相似呢?然后我就发现了函数BCEWithLogitsLoss(),看看其能不能替代BCECriterion()函数???? 来看一下下面的BCELoss和BCEWithLogitsLoss的区别
2 BCELoss函数
BCELoss()函数的公式是:
接下来使用一个二维张量来计算一下:
#随机输入3*3的Tensor
input=torch.randn(3,3)
print("input",input)
#输出:
#('input', tensor([[ 0.0548, 0.3067, -0.4413],
[-1.3003, -0.2090, 0.3265],
[ 1.2742, -0.7444, 2.6643]]))
#使用sigmoid()函数归一化到(0,1)
m=nn.Sigmoid()
Sm=m(input) #归一化到[0,1]
print("Sm",Sm)
#输出:
#('Sm', tensor([[0.5137, 0.5761, 0.3914],
[0.2141, 0.4479, 0.5809],
[0.7815, 0.3220, 0.9349]]))
#标签
target=torch.FloatTensor([[0,1,1],[0,0,1],[1,0,1]])
#使用BCELoss来计算损失,套用公式也可以算出来
loss=nn.BCELoss()
los=loss(Sm,target)
print("los",los)
#输出:
#('los', tensor(0.4768))
3 BCEWithLogitsLoss()函数
BCEWithLogitsLoss就是把Sigmoid-BCELoss合成一步。
但是不知道,如果仅仅是利用BCELoss()来计算损失,现在使用BCEWithLogitsLoss()函数来代替的话,会不会对结果有影响???
BCEWithLogitsLoss()的例子:
#直接在上述代码后面加上下面的这一句就行了,
loss1=nn.BCEWithLogitsLoss()
los1=loss1(input,target)
print("los1",los1)
#结果:
('los', tensor(0.8345))
('los1', tensor(0.8345))
(由于每次randn的Tensor不太一样,所以与上述的结果不一样,但是使用BCELoss和使用BCEWithLogitsLoss()的结果是一样的,都是可以计算正确的)