简体   繁体   English

为什么前馈神经网络中的简单二元分类会失败?

[英]Why is a simple Binary classification failing in a feedforward neural network?

I am new to Pytorch.我是 Pytorch 的新手。 I was trying to model a binary classifier on the Kepler dataset.我试图 model 开普勒数据集上的二进制分类器。 The following was my dataset class.以下是我的数据集 class。

class KeplerDataset(Dataset):
    def __init__(self, test=False):
        self.dataframe_orig = pd.read_csv(koi_cumm_path)

        if (test == False):
            self.data = df_numeric[( df_numeric.koi_disposition == 1 ) | ( df_numeric.koi_disposition == 0 )].values
        else:
            self.data = df_numeric[~(( df_numeric.koi_disposition == 1 ) | ( df_numeric.koi_disposition == 0 ))].values

        self.X_data = torch.FloatTensor(self.data[:, 1:])
        self.y_data = torch.FloatTensor(self.data[:, 0])

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

    def __getitem__(self, index):
        return self.X_data[index], self.y_data[index]

Here, I created a custom classifier class with one hidden layer and a single output unit that produces sigmoidal probability of being in class 1 (planet).在这里,我创建了一个自定义分类器 class,它具有一个隐藏层和一个 output 单元,该单元产生在 class 1(行星)中的 S 形概率。

class KOIClassifier(nn.Module):
    def __init__(self, input_dim, out_dim):
        super(KOIClassifier, self).__init__()
        self.linear1 = nn.Linear(input_dim, 32)

        self.linear2 = nn.Linear(32, 32)

        self.linear3 = nn.Linear(32, out_dim)


    def forward(self, xb):
        out = self.linear1(xb)
        out = F.relu(out)
        out = self.linear2(out)
        out = F.relu(out)
        out = self.linear3(out)
        out = torch.sigmoid(out)

        return out

I then created a train_model function to optimize the loss using SGD.然后我创建了一个train_model function 以使用 SGD 优化损失。

def train_model(X, y):
    criterion = nn.BCELoss()

    optim = torch.optim.SGD(model.parameters(), lr=0.001)

    n_epochs = 100
    losses = []

    for epoch in range(n_epochs):
        y_pred = model.forward(X)
        loss = criterion(y_pred, y)
        losses.append(loss.item())
        optim.zero_grad()
        loss.backward()
        optim.step()

losses = []
for X, y in train_loader:
    losses.append(train_model(X, y))

But after performing the optimization over the train_loader, When I try predicting on the trainn_loader itself, the prediction values are so much worse.但是在对 train_loader 执行优化之后,当我尝试对 trainn_loader 本身进行预测时,预测值要差得多。

for features, y in train_loader:
    y_pred = model.predict(features)
    break

y_pred


> tensor([[4.5436e-02],
        [1.5024e-02],
        [2.2579e-01],
        [4.2279e-01],
        [6.0811e-02],
        .....

Why is my model not working properly?为什么我的 model 不能正常工作? Is it the problem with the dataset or am I doing something wrong with implementing the Neural net?是数据集的问题还是我在实现神经网络时做错了什么? I will link my Kaggle notebook because more context might be helpful.我将链接我的 Kaggle 笔记本,因为更多上下文可能会有所帮助。 Please help.请帮忙。

You are optimizing many times (100 steps) on the first batch (first samples), then moving to the next samples.您在第一批(第一个样本)上进行了多次优化(100 步),然后转到下一个样本。 It means that your model will overfit your few samples before going to the next batch.这意味着您的 model 将在进入下一批之前过度拟合您的几个样本。 Then, your training will be very non smooth, diverge and go far from your global optimum.然后,您的训练将非常不顺畅、发散并且 go 远离您的全局最优值。

Usually, in a training loop you should:通常,在训练循环中,您应该:

  1. go over all samples (this is one epoch) go 所有样本(这是一个时期)
  2. shuffle your dataset in order to visit your samples in a different order (set your pytorch training loader accordingly)打乱您的数据集以便以不同的顺序访问您的样本(相应地设置您的 pytorch 训练加载器)
  3. go back to 1. until you reach the max number of epochs go 回到 1。直到达到最大时期数

Also you should not define your optimizer each time (nor your criterion).此外,您不应该每次都定义优化器(也不应该定义您的标准)。

Your training loop should look like this:您的训练循环应如下所示:

criterion = nn.BCELoss()
optim = torch.optim.SGD(model.parameters(), lr=0.001)
n_epochs = 100

def train_model():
    for X, y in train_loader:
        optim.zero_grad()
        y_pred = model.forward(X)
        loss = criterion(y_pred, y)
        loss.backward()
        optim.step()

for epoch in range(n_epochs):
    train_model()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM