python - 使用 CNN 的 IRIS 数据集精度极低
问题描述
作为初学者,我试图在 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]))
解决方案
错误就在这里
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 的文档,并看到它说“通过在网络的最后一层添加 LogSoftmax 层可以轻松实现神经网络中的对数概率。如果您不想添加额外的一层。” 因此,您可以添加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()
推荐阅读
- c# - ASP.Net Core如何添加ajax分页?
- javascript - javascript数组错误拼接映射函数
- objective-c - UIScrollView 与可绘制视图作为子视图
- c++ - 确定如何破坏给定类型的对象
- c# - 如何正确更新字典而不会出现参考问题?
- python - 有谁了解这个顺序以及如何将其应用于 4 个退货
- xpath - 从网站中提取价格信息的 XPath 表达式
- python - 设置环境变量时的混乱-python烧瓶
- ruby-on-rails-5 - 如何在 Ruby on rails 中将部分视图加载为模态?
- mysql - Magento 2 Mysql查询taxvat到vat_id