我试图在PyTorch中编写一个用于二进制分类的神经网络,我对损失函数感到困惑。
我看到BCELoss是专门用于二进制分类的通用功能。我还看到,对于N个可能的类,N个输出的输出层是常规分类的标准。但是,对于二进制分类,似乎可能是1个或2个输出。
因此,我应该有2个输出(每个标签1个),然后将我的0/1训练标签转换为[1,0]和[0,1]数组,或者对单个变量使用Sigmoid之类的东西输出?
以下是相关的代码段,因此您可以看到:
self.outputs = nn.Linear(NETWORK_WIDTH, 2) # 1 or 2 dimensions?
def forward(self, x):
# other layers omitted
x = self.outputs(x)
return F.log_softmax(x) # <<< softmax over multiple vars, sigmoid over one, or other?
criterion = nn.BCELoss() # <<< Is this the right function?
net_out = net(data)
loss = criterion(net_out, target) # <<< Should target be an integer label or 1-hot vector?
谢谢。
答案 0 :(得分:2)
对于二进制输出,可以使用 1 输出单位,因此:
self.outputs = nn.Linear(NETWORK_WIDTH, 1)
然后使用sigmoid
激活将输出单位的值映射到 0 和 1 (当然,您也需要以这种方式安排您的训练数据):
def forward(self, x):
# other layers omitted
x = self.outputs(x)
return F.sigmoid(x)
最后,您可以使用torch.nn.BCELoss
:
criterion = nn.BCELoss()
net_out = net(data)
loss = criterion(net_out, target)
这应该对您来说很好。
您还可以使用torch.nn.BCEWithLogitsLoss
,此丢失功能已经包含sigmoid
功能,因此您可以将其保留在前进位置。
如果由于某种原因要使用 2 输出单位,这也是可能的。但是随后您需要使用torch.nn.CrossEntropyLoss
而不是BCELoss
。 Softmax
激活已包含在此丢失函数中。
答案 1 :(得分:0)
一些理论上的总结:
对于二进制分类(例如0类和1类),网络应该只有1个输出单元。其输出将为1(对于存在1类或不存在0类)和0(对于不存在1类或不存在0类)。
对于损耗计算,应首先将其传递给S型,然后传递给BinaryCrossEntropy(BCE)。乙状结肠将网络的输出转换为概率(介于0和1之间),然后BCE将所需输出的可能性最大化。