全连接输出维度为1,使用sigmoid将输出映射到0,1之间
self.outputs = nn.Linear(input, 1)
def forward(self, x):
# other layers omitted
x = self.outputs(x)
return torch.sigmoid(x)
那么在这种情况下,我们使用torch.nn.BCELoss作为loss function:
criterion = nn.BCELoss()
net_out = net(data)
loss = criterion(net_out, target)
全连接输出维度为1,BCEWithLogitsLoss损失已经包含了sigmoid激活函数,不需再单独使用sigmoid
self.outputs = nn.Linear(input, 1)
def forward(self, x):
# other layers omitted
x = self.outputs(x)
return x
criterion = nn.BCEWithLogitsLoss()
net_out = net(data)
loss = criterion(net_out, target)
以上两种其实差别不大,都是使用Sigmoid的方式实现,最后输出维度为1,用于判断是或不是,后者激活函数与loss在一起的时候,训练过程会更加稳定。
输出维度为2,并使用Softmax,但是CrossEntropyLoss损失包含Softmax激活函数
self.outputs = nn.Linear(input, 2)
def forward(self, x):
# other layers omitted
x = self.outputs(x)
return x
criterion = nn.CrossEntropysLoss()
net_out = net(data)
loss = criterion(net_out, target)
训练时不用Softmax层,但是验证测试时建议使用
# Prediction.
score = net(X)
_, prediction = torch.max(F.softmax(score.data), 1)
num_total += y.size(0)
num_correct += torch.sum(prediction == y)
此处可以参考文章:
二分类问题,应该选择sigmoid还是softmax?
文章讲解很详细,这里简单总结:
两者理论上是等效的,对训练准确率没有影响,但是具体到不同框架下的网络可能会存在一些差异。
Sigmoid函数,我们可以当作成它是对一个类别的“建模”,将该类别建模完成得到p,另一个相对的类别就直接为1-p。而softmax函数,是对两个类别建模,同样的,得到两个类别的概率之和是1。
经验:
对于NLP而言,这两者之间确实有差别,Softmax的处理方式有时候会比Sigmoid的处理方式好一点。
对于CV而言,这两者之间也是有差别的,Sigmoid的处理方式有时候会比Softmax的处理方式好一点。
如果是多分类问题,建议直接使用softmax,因为Softmax在使用时类别之间是互斥的,而对于Sigmoid虽然可以多分类,但是其类别之间不是互斥的。
本文参考链接:
二分类问题,应该选择sigmoid还是softmax?
PyTorch二分类时BCELoss,CrossEntropyLoss,Sigmoid等的选择和使用