Sigmoid和Softmax在二分类中使用的区别与实现

对于二分类有三种实现方式:

1. nn.Linear(input, 1) + sigmoid + BCELoss

全连接输出维度为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)

2. nn.Linear(input, 1) + BCEWithLogitsLoss

全连接输出维度为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在一起的时候,训练过程会更加稳定。

3. nn.Linear(input, 1) + CrossEntropyLoss

输出维度为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 or Softmax?

此处可以参考文章:
二分类问题,应该选择sigmoid还是softmax?
文章讲解很详细,这里简单总结:
Sigmoid和Softmax在二分类中使用的区别与实现_第1张图片
两者理论上是等效的,对训练准确率没有影响,但是具体到不同框架下的网络可能会存在一些差异。

Sigmoid函数,我们可以当作成它是对一个类别的“建模”,将该类别建模完成得到p,另一个相对的类别就直接为1-p。而softmax函数,是对两个类别建模,同样的,得到两个类别的概率之和是1。
经验:
对于NLP而言,这两者之间确实有差别,Softmax的处理方式有时候会比Sigmoid的处理方式好一点。
对于CV而言,这两者之间也是有差别的,Sigmoid的处理方式有时候会比Softmax的处理方式好一点。

如果是多分类问题,建议直接使用softmax,因为Softmax在使用时类别之间是互斥的,而对于Sigmoid虽然可以多分类,但是其类别之间不是互斥的。

本文参考链接:
二分类问题,应该选择sigmoid还是softmax?
PyTorch二分类时BCELoss,CrossEntropyLoss,Sigmoid等的选择和使用

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