为什么简单的二进制分类在前馈神经网络中失败?
Why is a simple Binary classification failing in a feedforward neural network?
我是 Pytorch 新手。我试图在 Kepler 数据集上对二进制 classifier 进行建模。以下是我的数据集 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]
在这里,我创建了一个自定义 classifier class,它带有一个隐藏层和一个输出单元,它产生位于 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
然后我创建了一个 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],
.....
为什么我的模型不能正常工作?是数据集的问题还是我在实施神经网络时做错了什么?我将 link 我的 Kaggle 笔记本,因为更多的上下文可能会有帮助。请帮忙。
您正在对第一批(第一个样本)进行多次优化(100 步),然后转向下一个样本。这意味着您的模型在进入下一批之前会过度拟合您的几个样本。然后,你的训练将非常不顺利,发散并且远离你的全局最优值。
通常,在训练循环中你应该:
- 遍历所有样本(这是一个纪元)
- 打乱你的数据集以便以不同的顺序访问你的样本(相应地设置你的 pytorch 训练加载器)
- 回到 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()
我是 Pytorch 新手。我试图在 Kepler 数据集上对二进制 classifier 进行建模。以下是我的数据集 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]
在这里,我创建了一个自定义 classifier class,它带有一个隐藏层和一个输出单元,它产生位于 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
然后我创建了一个 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],
.....
为什么我的模型不能正常工作?是数据集的问题还是我在实施神经网络时做错了什么?我将 link 我的 Kaggle 笔记本,因为更多的上下文可能会有帮助。请帮忙。
您正在对第一批(第一个样本)进行多次优化(100 步),然后转向下一个样本。这意味着您的模型在进入下一批之前会过度拟合您的几个样本。然后,你的训练将非常不顺利,发散并且远离你的全局最优值。
通常,在训练循环中你应该:
- 遍历所有样本(这是一个纪元)
- 打乱你的数据集以便以不同的顺序访问你的样本(相应地设置你的 pytorch 训练加载器)
- 回到 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()