0

我是 Pytorch 的新手。我试图在开普勒数据集上建模一个二元分类器。以下是我的数据集类。

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]

在这里,我创建了一个自定义分类器类,该分类器类具有一个隐藏层和一个输出单元,它产生属于类 1(行星)的 sigmoid 概率。

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

然后我创建了一个train_model函数来使用 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))

但是在对 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],
        .....

为什么我的模型不能正常工作?是数据集的问题还是我在实现神经网络时做错了什么?我将链接我的 Kaggle 笔记本,因为更多上下文可能会有所帮助。请帮忙。

4

1 回答 1

2

您在第一批(第一个样本)上进行了多次优化(100 步),然后转到下一个样本。这意味着您的模型将在进入下一批之前过度拟合您的几个样本。然后,您的训练将非常不顺利,出现分歧并远离您的全局最优值。

通常,在训练循环中,您应该:

  1. 检查所有样本(这是一个时代)
  2. 打乱您的数据集以便以不同的顺序访问您的样本(相应地设置您的 pytorch 训练加载器)
  3. 返回 1. 直到达到最大时期数

此外,您不应该每次都定义优化器(也不应该定义您的标准)。

您的训练循环应如下所示:

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()
于 2020-06-16T17:30:17.020 回答