神经网络中Sigmoid激活函数阈值的改变

大家好,我是机器学习的新手,我想询问一下关于改变Sigmoid函数阈值的问题。

我知道Sigmoid函数的值在[0,1]范围内,0.5被用作阈值,如果h(theta) < 0.5,我们假设其值为0,如果h(theta) >= 0.5,则其值为1。

阈值只在网络的输出层使用,且仅在分类时使用。所以,如果你要在三个类别之间进行分类,你可以为每个类别设置不同的阈值(如0.2,0.4,0.4 – 分别对应每个类别)吗?或者你可以设定一个整体不同的阈值,比如0.8?我不确定如何在下面的代码中定义这些。任何指导都会被感激。

# Hyper Parametersinput_size = 14hidden_size = 40hidden_size2 = 30num_classes = 3num_epochs = 600batch_size = 34learning_rate = 0.01class Net(torch.nn.Module):    def __init__(self, n_input, n_hidden, n_hidden2, n_output):        super(Net, self).__init__()        # define linear hidden layer output        self.hidden = torch.nn.Linear(n_input, n_hidden)        self.hidden2 = torch.nn.Linear(n_hidden, n_hidden2)        # define linear output layer output        self.out = torch.nn.Linear(n_hidden, n_output)    def forward(self, x):        """            In the forward function we define the process of performing            forward pass, that is to accept a Variable of input            data, x, and return a Variable of output data, y_pred.        """        # get hidden layer input        h_input1 = self.hidden(x)        # define activation function for hidden layer        h_output1 = torch.sigmoid(h_input1)        # get hidden layer input        h_input2 = self.hidden2(h_output1)        # define activation function for hidden layer        h_output2 = torch.sigmoid(h_input2)        # get output layer output        out = self.out(h_output2)        return outnet = Net(input_size, hidden_size, hidden_size, num_classes)criterion = nn.CrossEntropyLoss()optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)all_losses = []for epoch in range(num_epochs):    total = 0    correct = 0    total_loss = 0    for step, (batch_x, batch_y) in enumerate(train_loader):        X = batch_x        Y = batch_y.long()    # Forward + Backward + Optimize    optimizer.zero_grad()  # zero the gradient buffer    outputs = net(X)    loss = criterion(outputs, Y)    all_losses.append(loss.item())    loss.backward()    optimizer.step()    if epoch % 50 == 0:        _, predicted = torch.max(outputs, 1)        # calculate and print accuracy        total = total + predicted.size(0)        correct = correct + sum(predicted.data.numpy() == Y.data.numpy())        total_loss = total_loss + loss    if epoch % 50 == 0:        print(            "Epoch [%d/%d], Loss: %.4f, Accuracy: %.2f %%"            % (epoch + 1, num_epochs, total_loss, 100 * correct / total)        )train_input = train_data.iloc[:, :input_size]train_target = train_data.iloc[:, input_size]inputs = torch.Tensor(train_input.values).float()targets = torch.Tensor(train_target.values - 1).long()outputs = net(inputs)_, predicted = torch.max(outputs, 1)

回答:

你可以使用你认为合适的任何阈值。

众所周知,神经网络往往过于自信(例如,对50个类别中的一个应用0.95),所以在你的情况下使用不同的阈值可能会有益。

你的训练过程很好,但你应该改变预测(最后两行),并像这样使用torch.nn.softmax

outputs = net(inputs) probabilities = torch.nn.functional.softmax(outputs, 1)

如其他答案中提到,你将得到每行概率之和为1(之前你有未归一化的概率,即logits)。

现在,只需对这些概率使用你想要的阈值:

predictions = probabilities > 0.8

请注意,在某些情况下你可能会得到全零(例如,[0.2, 0.3, 0.5])。

这意味着根据你的标准,神经网络对结果不够自信,可能会减少错误的正预测数量(抽象地说,假设你正在预测一个患者是否没有三种互斥疾病中的一种。如果你没有足够的把握,最好不要做这样的预测)。

为每个类别设置不同的阈值

这也可以这样做:

thresholds = torch.tensor([0.1, 0.1, 0.8]).unsqueeze(0)predictions = probabilities > thresholds

最后的评论

请注意,在使用softmax的情况下,只有一个类别应该是答案(如另一答案中指出的),这种方法(以及提到Sigmoid)可能表明你在进行多标签分类

如果你想训练你的网络以同时预测多个类别,你应该使用sigmoid并将损失函数更改为torch.nn.BCEWithLogitsLoss

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注