为什么我在进行任何优化之前得到的错误率很低?
Why am I getting a low error before I did any optimization?
我正在使用我为玩具示例构建的模型训练程序,并尝试在另一个示例中使用它。
唯一的区别是这个模型用于回归,因此我使用 MSE 作为错误标准,现在它用于二进制分类,因此我使用 BCEWithLogitsLoss。
模型很简单:
class Model(nn.Module):
def __init__(self, input_size, output_size):
super(Model, self).__init__()
self.fc1 = nn.Sequential(
nn.Linear(input_size, 8*input_size),
nn.PReLU() #parametric relu - same as leaky relu except the slope is learned
)
self.fc2 = nn.Sequential(
nn.Linear(8*input_size, 80*input_size),
nn.PReLU()
)
self.fc3 = nn.Sequential(
nn.Linear(80*input_size, 32*input_size),
nn.PReLU()
)
self.fc4 = nn.Sequential(
nn.Linear(32*input_size, 4*input_size),
nn.PReLU()
)
self.fc = nn.Sequential(
nn.Linear(4*input_size, output_size),
nn.PReLU()
)
def forward(self, x, dropout=dropout, batchnorm=batchnorm):
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
x = self.fc4(x)
x = self.fc(x)
return x
这就是我 运行 的地方:
model = Model(input_size, output_size)
if (loss == 'MSE'):
criterion = nn.MSELoss()
if (loss == 'BCELoss'):
criterion = nn.BCEWithLogitsLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = lr)
model.train()
for epoch in range(num_epochs):
# Forward pass and loss
train_predictions = model(train_features)
print(train_predictions)
print(train_targets)
loss = criterion(train_predictions, train_targets)
# Backward pass and update
loss.backward()
optimizer.step()
# zero grad before new step
optimizer.zero_grad()
train_size = len(train_features)
train_loss = criterion(train_predictions, train_targets).item()
pred = train_predictions.max(1, keepdim=True)[1]
correct = pred.eq(train_targets.view_as(pred)).sum().item()
#train_loss /= train_size
accuracy = correct / train_size
print('\nTrain set: Loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
train_loss, correct, train_size,
100. * accuracy))
但是,当我打印损失时,出于某种原因,在我进行任何向后传递之前,损失已经开始非常低(大约 0.6)!它在随后的所有时期都保持这种低水平。
然而,预测向量看起来像随机垃圾...
tensor([[-0.0447],
[-0.0640],
[-0.0564],
...,
[-0.0924],
[-0.0113],
[-0.0774]], grad_fn=<PreluBackward>)
tensor([[0.],
[0.],
[0.],
...,
[0.],
[0.],
[1.]])
epoch: 1, loss = 0.6842
我不知道为什么要这样做,希望能提供任何帮助。
谢谢!
编辑:
如果他们可以帮助任何人解决这个问题,我添加了参数:
if (dataset == 'adult_train.csv'):
input_size=9
print_every = 1
output_size = 1
lr = 0.001
num_epochs = 10
loss='BCELoss'
EDIT2:在中间块中添加了精度计算
BCELoss 不是错误。
p=0.5 的伯努利分布的熵为 -ln(0.5) = 0.693。如果
,这是您预期的损失
- 您的数据分布均匀
- 您的网络正在随机猜测
或
- 您的网络始终预测均匀分布
你的模型属于第二种情况。该网络目前正在为每个预测猜测略微负的对数。这些将被解释为 0 class 个预测。由于您的数据似乎对 0 个标签不平衡,因此您的准确性将与始终预测 0 的模型相同。这只是随机权重初始化的产物。如果你不断地重新初始化你的模型,你会发现有时它也会总是预测 1。
我正在使用我为玩具示例构建的模型训练程序,并尝试在另一个示例中使用它。 唯一的区别是这个模型用于回归,因此我使用 MSE 作为错误标准,现在它用于二进制分类,因此我使用 BCEWithLogitsLoss。
模型很简单:
class Model(nn.Module):
def __init__(self, input_size, output_size):
super(Model, self).__init__()
self.fc1 = nn.Sequential(
nn.Linear(input_size, 8*input_size),
nn.PReLU() #parametric relu - same as leaky relu except the slope is learned
)
self.fc2 = nn.Sequential(
nn.Linear(8*input_size, 80*input_size),
nn.PReLU()
)
self.fc3 = nn.Sequential(
nn.Linear(80*input_size, 32*input_size),
nn.PReLU()
)
self.fc4 = nn.Sequential(
nn.Linear(32*input_size, 4*input_size),
nn.PReLU()
)
self.fc = nn.Sequential(
nn.Linear(4*input_size, output_size),
nn.PReLU()
)
def forward(self, x, dropout=dropout, batchnorm=batchnorm):
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
x = self.fc4(x)
x = self.fc(x)
return x
这就是我 运行 的地方:
model = Model(input_size, output_size)
if (loss == 'MSE'):
criterion = nn.MSELoss()
if (loss == 'BCELoss'):
criterion = nn.BCEWithLogitsLoss()
optimizer = torch.optim.SGD(model.parameters(), lr = lr)
model.train()
for epoch in range(num_epochs):
# Forward pass and loss
train_predictions = model(train_features)
print(train_predictions)
print(train_targets)
loss = criterion(train_predictions, train_targets)
# Backward pass and update
loss.backward()
optimizer.step()
# zero grad before new step
optimizer.zero_grad()
train_size = len(train_features)
train_loss = criterion(train_predictions, train_targets).item()
pred = train_predictions.max(1, keepdim=True)[1]
correct = pred.eq(train_targets.view_as(pred)).sum().item()
#train_loss /= train_size
accuracy = correct / train_size
print('\nTrain set: Loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
train_loss, correct, train_size,
100. * accuracy))
但是,当我打印损失时,出于某种原因,在我进行任何向后传递之前,损失已经开始非常低(大约 0.6)!它在随后的所有时期都保持这种低水平。 然而,预测向量看起来像随机垃圾...
tensor([[-0.0447],
[-0.0640],
[-0.0564],
...,
[-0.0924],
[-0.0113],
[-0.0774]], grad_fn=<PreluBackward>)
tensor([[0.],
[0.],
[0.],
...,
[0.],
[0.],
[1.]])
epoch: 1, loss = 0.6842
我不知道为什么要这样做,希望能提供任何帮助。 谢谢!
编辑: 如果他们可以帮助任何人解决这个问题,我添加了参数:
if (dataset == 'adult_train.csv'):
input_size=9
print_every = 1
output_size = 1
lr = 0.001
num_epochs = 10
loss='BCELoss'
EDIT2:在中间块中添加了精度计算
BCELoss 不是错误。
p=0.5 的伯努利分布的熵为 -ln(0.5) = 0.693。如果
,这是您预期的损失- 您的数据分布均匀
- 您的网络正在随机猜测
或
- 您的网络始终预测均匀分布
你的模型属于第二种情况。该网络目前正在为每个预测猜测略微负的对数。这些将被解释为 0 class 个预测。由于您的数据似乎对 0 个标签不平衡,因此您的准确性将与始终预测 0 的模型相同。这只是随机权重初始化的产物。如果你不断地重新初始化你的模型,你会发现有时它也会总是预测 1。