回归损失函数不正确
Regression loss functions incorrect
我正在尝试一个基本的平均示例,但验证和损失不匹配,如果我增加训练时间,网络将无法收敛。我正在训练一个具有 2 个隐藏层的网络,每个隐藏层在 [0,9] 范围内的三个整数上有 500 个单位宽,学习率为 1e-1,Adam,批次大小为 1,并退出 3000 次迭代并验证每个100 次迭代。如果标签和假设的绝对差值小于一个阈值,这里我把阈值设置为1,我认为是正确的。有人可以让我知道这是损失函数选择的问题、Pytorch 的问题还是我正在做的事情。以下是一些情节:
val_diff = 1
acc_diff = torch.FloatTensor([val_diff]).expand(self.batch_size)
在验证期间循环 100 次:
num_correct += torch.sum(torch.abs(val_h - val_y) < acc_diff)
在每个验证阶段后追加:
validate.append(num_correct / total_val)
以下是(假设和标签)的一些示例:
[...(-0.7043088674545288, 6.0), (-0.15691305696964264, 2.6666667461395264),
(0.2827358841896057, 3.3333332538604736)]
我尝试了 API 中通常用于回归的六个损失函数:
torch.nn.L1Loss(size_average=False)
torch.nn.L1Loss()
torch.nn.MSELoss(size_average=False)
torch.nn.MSELoss()
torch.nn.SmoothL1Loss(size_average=False)
torch.nn.SmoothL1Loss()
谢谢。
网络代码:
class Feedforward(nn.Module):
def __init__(self, topology):
super(Feedforward, self).__init__()
self.input_dim = topology['features']
self.num_hidden = topology['hidden_layers']
self.hidden_dim = topology['hidden_dim']
self.output_dim = topology['output_dim']
self.input_layer = nn.Linear(self.input_dim, self.hidden_dim)
self.hidden_layer = nn.Linear(self.hidden_dim, self.hidden_dim)
self.output_layer = nn.Linear(self.hidden_dim, self.output_dim)
self.dropout_layer = nn.Dropout(p=0.2)
def forward(self, x):
batch_size = x.size()[0]
feat_size = x.size()[1]
input_size = batch_size * feat_size
self.input_layer = nn.Linear(input_size, self.hidden_dim).cuda()
hidden = self.input_layer(x.view(1, input_size)).clamp(min=0)
for _ in range(self.num_hidden):
hidden = self.dropout_layer(F.relu(self.hidden_layer(hidden)))
output_size = batch_size * self.output_dim
self.output_layer = nn.Linear(self.hidden_dim, output_size).cuda()
return self.output_layer(hidden).view(output_size)
训练代码:
def train(self):
if self.cuda:
self.network.cuda()
dh = DataHandler(self.data)
# loss_fn = nn.L1Loss(size_average=False)
# loss_fn = nn.L1Loss()
# loss_fn = nn.SmoothL1Loss(size_average=False)
# loss_fn = nn.SmoothL1Loss()
# loss_fn = nn.MSELoss(size_average=False)
loss_fn = torch.nn.MSELoss()
losses = []
validate = []
hypos = []
labels = []
val_size = 100
val_diff = 1
total_val = float(val_size * self.batch_size)
for i in range(self.iterations):
x, y = dh.get_batch(self.batch_size)
x = self.tensor_to_Variable(x)
y = self.tensor_to_Variable(y)
self.optimizer.zero_grad()
loss = loss_fn(self.network(x), y)
loss.backward()
self.optimizer.step()
看来您误解了 pytorch 中层的工作原理,这里有一些提示:
在您的转发中,当您执行 nn.Linear(...)
时,您正在定义 新层 而不是使用您在网络中预定义的层 __init__
.因此,它无法学习任何东西,因为权重会不断重新初始化。
您不需要在 net.forward(...)
中调用 .cuda()
,因为您已经通过调用 [=16] 在 train
的 gpu 上复制了网络=]
理想情况下,net.forward(...)
输入应该直接具有第一层的形状,这样您就不必修改它。在这里你应该有 x.size() <=> Linear -- > (Batch_size, Features)
.
你的前锋看起来应该接近于此:
def forward(self, x):
x = F.relu(self.input_layer(x))
x = F.dropout(F.relu(self.hidden_layer(x)),training=self.training)
x = self.output_layer(x)
return x
我正在尝试一个基本的平均示例,但验证和损失不匹配,如果我增加训练时间,网络将无法收敛。我正在训练一个具有 2 个隐藏层的网络,每个隐藏层在 [0,9] 范围内的三个整数上有 500 个单位宽,学习率为 1e-1,Adam,批次大小为 1,并退出 3000 次迭代并验证每个100 次迭代。如果标签和假设的绝对差值小于一个阈值,这里我把阈值设置为1,我认为是正确的。有人可以让我知道这是损失函数选择的问题、Pytorch 的问题还是我正在做的事情。以下是一些情节:
val_diff = 1
acc_diff = torch.FloatTensor([val_diff]).expand(self.batch_size)
在验证期间循环 100 次:
num_correct += torch.sum(torch.abs(val_h - val_y) < acc_diff)
在每个验证阶段后追加:
validate.append(num_correct / total_val)
以下是(假设和标签)的一些示例:
[...(-0.7043088674545288, 6.0), (-0.15691305696964264, 2.6666667461395264),
(0.2827358841896057, 3.3333332538604736)]
我尝试了 API 中通常用于回归的六个损失函数:
torch.nn.L1Loss(size_average=False)
torch.nn.L1Loss()
torch.nn.MSELoss(size_average=False)
torch.nn.MSELoss()
torch.nn.SmoothL1Loss(size_average=False)
torch.nn.SmoothL1Loss()
谢谢。
网络代码:
class Feedforward(nn.Module):
def __init__(self, topology):
super(Feedforward, self).__init__()
self.input_dim = topology['features']
self.num_hidden = topology['hidden_layers']
self.hidden_dim = topology['hidden_dim']
self.output_dim = topology['output_dim']
self.input_layer = nn.Linear(self.input_dim, self.hidden_dim)
self.hidden_layer = nn.Linear(self.hidden_dim, self.hidden_dim)
self.output_layer = nn.Linear(self.hidden_dim, self.output_dim)
self.dropout_layer = nn.Dropout(p=0.2)
def forward(self, x):
batch_size = x.size()[0]
feat_size = x.size()[1]
input_size = batch_size * feat_size
self.input_layer = nn.Linear(input_size, self.hidden_dim).cuda()
hidden = self.input_layer(x.view(1, input_size)).clamp(min=0)
for _ in range(self.num_hidden):
hidden = self.dropout_layer(F.relu(self.hidden_layer(hidden)))
output_size = batch_size * self.output_dim
self.output_layer = nn.Linear(self.hidden_dim, output_size).cuda()
return self.output_layer(hidden).view(output_size)
训练代码:
def train(self):
if self.cuda:
self.network.cuda()
dh = DataHandler(self.data)
# loss_fn = nn.L1Loss(size_average=False)
# loss_fn = nn.L1Loss()
# loss_fn = nn.SmoothL1Loss(size_average=False)
# loss_fn = nn.SmoothL1Loss()
# loss_fn = nn.MSELoss(size_average=False)
loss_fn = torch.nn.MSELoss()
losses = []
validate = []
hypos = []
labels = []
val_size = 100
val_diff = 1
total_val = float(val_size * self.batch_size)
for i in range(self.iterations):
x, y = dh.get_batch(self.batch_size)
x = self.tensor_to_Variable(x)
y = self.tensor_to_Variable(y)
self.optimizer.zero_grad()
loss = loss_fn(self.network(x), y)
loss.backward()
self.optimizer.step()
看来您误解了 pytorch 中层的工作原理,这里有一些提示:
在您的转发中,当您执行
nn.Linear(...)
时,您正在定义 新层 而不是使用您在网络中预定义的层__init__
.因此,它无法学习任何东西,因为权重会不断重新初始化。您不需要在
net.forward(...)
中调用.cuda()
,因为您已经通过调用 [=16] 在train
的 gpu 上复制了网络=]理想情况下,
net.forward(...)
输入应该直接具有第一层的形状,这样您就不必修改它。在这里你应该有x.size() <=> Linear -- > (Batch_size, Features)
.
你的前锋看起来应该接近于此:
def forward(self, x):
x = F.relu(self.input_layer(x))
x = F.dropout(F.relu(self.hidden_layer(x)),training=self.training)
x = self.output_layer(x)
return x