【问题标题】:Extremely low accuracy for IRIS dataset using CNN使用 CNN 的 IRIS 数据集精度极低
【发布时间】:2021-08-13 04:31:28
【问题描述】:

作为初学者,我正在尝试在 IRIS 数据集上实现我的 CNN,只考虑了 2 个标签:

  • 鸢尾花:0
  • 鸢尾花:1

我使用 90% 的数据进行训练,使用 10% 的数据进行测试,使用 1D CNN 和 Adam 优化以及 0.001 的学习率。达到的准确度约为 40-50%,这也随着每次执行而变化。请建议应该做什么。

数据加载到数据加载器:

#Training data
class IrisDataset(T.utils.data.Dataset):

  def __init__(self, Iris):    
    sc = StandardScaler()    
    X_tr = sc.fit_transform(trainX)
    Y_tr = trainY     
    self.X_tr = torch.tensor(X_tr, dtype = torch.float32)
    self.Y_tr = torch.tensor(Y_tr, dtype = torch.float32)

  def __len__(self):
    return len(self.Y_tr)

  def __getitem__(self, idx):        
    return self.X_tr[idx], self.Y_tr[idx]

train_ds = IrisDataset(Iris)

bat_size = 1
# Leaving only labels 0 and 1 
idx = np.append(np.where(train_ds.Y_tr == 0)[0], 
                np.where(train_ds.Y_tr == 1)[0])
train_ds.X_tr = train_ds.X_tr[idx]
train_ds.Y_tr = train_ds.Y_tr[idx]

#len(train_ds)
train_ldr = T.utils.data.DataLoader(train_ds,
    batch_size=bat_size, shuffle=True)
batch = next(iter(train_ldr))

# and in the same way test data
#NETWORK CLASS

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv1d(1, 6, kernel_size=1)
        self.conv2 = nn.Conv1d(6, 16, kernel_size=1)
        self.dropout = nn.Dropout2d()
        self.fc1 = nn.Linear(64, 16)
        self.fc2 = nn.Linear(16, 1)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = self.dropout(x)
        x = x.view(x.size(0), -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return T.cat((x, 1 - x), -1)
# MODEL TRAINING 
model = Net()
optimizer = optim.Adam(model.parameters(), lr=0.001)
loss_func = nn.NLLLoss()
epochs = 2
loss_list = []

model.train()

for epoch in range(epochs):
    total_loss = []
    
    for X_tr, Y_tr in train_ldr:
       X_tr = X_tr.unsqueeze(0)
       optimizer.zero_grad()
 
       output = model(X_tr)
       pred = output.argmax(dim=1, keepdim=True)
       Y_tr = torch.tensor(Y_tr, dtype=torch.long)
       loss = loss_func(output, Y_tr.squeeze(1))
        # Backward pass
       loss.backward()
        # Optimize the weights
       optimizer.step()
        
       total_loss.append(loss.item())

    loss_list.append(sum(total_loss)/len(total_loss))
    print('Training [{:.0f}%]\tLoss: {:.4f}'.format(
         100. * (epoch + 1) / epochs, loss_list[-1]))

【问题讨论】:

    标签: python deep-learning pytorch conv-neural-network


    【解决方案1】:

    错误就在这里

    def forward(self, x):
       x = F.relu(self.conv1(x))
       .
       .
       x = self.fc2(x)
       return T.cat((x, 1 - x), -1)
    '''
    The thing is that the output from the dense layer is not the probability and hence
    you subtracting it form 1 also don't make any sense. It will become probability if 
    you use sigmoid activation after it.
    '''
    def forward(self, x):
       x = F.relu(self.conv1(x))
       .
       .
       x = self.fc2(x) 
       x = torch.nn.functional.sigmoid(x)
       return T.cat((x, 1 - x), -1)
    

    但我建议您将损失函数更改为 BCE,如下所示。这不太容易出错,并且在结果方面与上述相同。您还可以阅读 NLL 的 docs 并看到它说“通过在网络的最后一层添加 LogSoftmax 层可以轻松实现神经网络中的对数概率。如果您不想这样做,您可以改用 CrossEntropyLoss添加一个额外的层。”因此,您可以添加LogSoftmax 或使用CrossEntropy

    # LogSoftmax
    def forward(self, x):
       x = F.relu(self.conv1(x))
       .
       .
       x = self.fc2(x) 
       x = torch.nn.functional.log_softmax(x, dim=1)
       return x
    
    loss_func = nn.NLLLoss()
    
    
    # BCE
    def forward(self, x):
       x = F.relu(self.conv1(x))
       .
       .
       x = self.fc2(x) 
       return x
    
    loss_func = torch.nn.BCEWithLogitsLoss()
    

    【讨论】:

    • (x)和BCEWithLogitsLoss的修正错误提高了准确率。非常感谢。
    • 上述错误消失了,但是当我尝试比较和打印(Label,predicted_label)时,所有预测的标签都是0并且模型没有预测任何标签为1,两者都在训练和测试数据。请建议我在 IRIS 数据集上训练模型时可能出错的地方。
    • 分享您的代码。如果可能,请分享 colab 链接。
    • 链接:colab.research.google.com/drive/…。我只采集了 IRIS 数据集的前 100 个样本,其中前 50 个(标签 0)和后 50 个(标签 1)在我的数据集文件中手动转换。提前感谢您的帮助。
    • 我已经分享了代码的链接。如果可能,请告诉我错误在哪里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    相关资源
    最近更新 更多