Machine learning PyTorch ConvNet随机学习单个标签并卡住
我尝试对两种类型的图像进行分类(即2个标签)。我有超过30k的图片作为我的训练数据集,并且建立了CNN,如下所述 这是奇怪的部分-我已经训练这个网络超过20次了,我得到了两种完全不同的行为-Machine learning PyTorch ConvNet随机学习单个标签并卡住,machine-learning,deep-learning,neural-network,pytorch,conv-neural-network,Machine Learning,Deep Learning,Neural Network,Pytorch,Conv Neural Network,我尝试对两种类型的图像进行分类(即2个标签)。我有超过30k的图片作为我的训练数据集,并且建立了CNN,如下所述 这是奇怪的部分-我已经训练这个网络超过20次了,我得到了两种完全不同的行为- 1. 事实上,网络将“学习”,损失将减少,在大约10个时期后,我将正确分类大约80%的测试数据集。 2.在看到~1k张图片(甚至不是一个历元)后,网络将“决定”始终将图像分类为其中一个标签损失被卡住了,什么也没发生 奇怪的是,这是一段完全相同的代码!没有什么变化。 我试着调试了这么多小时,到了一个地步
1. 事实上,网络将“学习”,损失将减少,在大约10个时期后,我将正确分类大约80%的测试数据集。
2.在看到~1k张图片(甚至不是一个历元)后,网络将“决定”始终将图像分类为其中一个标签损失被卡住了,什么也没发生
奇怪的是,这是一段完全相同的代码!没有什么变化。 我试着调试了这么多小时,到了一个地步,我不知道发生了什么。
我注意到的唯一一件事是,当网络无法学习时,网络的初始输出(不执行一次backprop迭代)类似于-
model = MyNetwork()
images, labels = iter(train_dataset_loader).next()
fw_pass_output = model(images)
print(fw_pass_output[:5])
---
tensor([[9.4696e-09, 1.0000e+00],
[2.8105e-08, 1.0000e+00],
[7.4285e-09, 1.0000e+00],
[4.3701e-09, 1.0000e+00],
[4.4942e-08, 1.0000e+00]], grad_fn=<SliceBackward>)
当优化器陷入局部最小值时,就会发生这种情况。你可以尝试低学习率——这有时会有帮助。你也可以考虑让一个预先训练过的CNN适应你的问题。请看一个例子来说明我的意思。但这也发生在乐观主义者有机会做某事之前!有一些网络初始化,在我优化任何东西之前,所有东西都被分类为一个标签!这就是为什么我认为这是代表我的某种软件缺陷…现在试着关闭体重衰减。0.1的值非常大。更正常的做法是使用类似1e-6到1e-4的内容。您正在使用的是log softmax,但在此之前您也使用常规softmax。这可能会导致一些稳定性问题。您应该从模型中删除
F.softmax(x,dim=1)
,并且仅在希望查看概率时应用它。当优化器陷入局部最小值时,可能会发生这种情况。你可以尝试低学习率——这有时会有帮助。你也可以考虑让一个预先训练过的CNN适应你的问题。请看一个例子来说明我的意思。但这也发生在乐观主义者有机会做某事之前!有一些网络初始化,在我优化任何东西之前,所有东西都被分类为一个标签!这就是为什么我认为这是代表我的某种软件缺陷…现在试着关闭体重衰减。0.1的值非常大。更正常的做法是使用类似1e-6到1e-4的内容。您正在使用的是log softmax,但在此之前您也使用常规softmax。这可能会导致一些稳定性问题。您应该从模型中删除F.softmax(x,dim=1)
,并且仅在希望查看概率时应用它。
tensor([[0.4982, 0.5018],
[0.4353, 0.5647],
[0.3051, 0.6949],
[0.4823, 0.5177],
[0.4342, 0.5658]], grad_fn=<SliceBackward>)
class MyNetwork(nn.Module):
def __init__(self):
super(MyNetwork, self).__init__()
self.conv1_layer = nn.Conv2d(3, 32, 5)
self.conv2_layer = nn.Conv2d(32, 16, 3)
self.conv3_layer = nn.Conv2d(16, 8, 2)
self.layer_size_after_convs = 8 * 5 * 5
TOTAL_NUM_OF_CLASSES = 2
self.fc1 = nn.Linear(self.layer_size_after_convs, TOTAL_NUM_OF_CLASSES)
def forward(self, x):
"""
Perform a forward pass on the network
"""
x = F.relu(self.conv1_layer(x))
x = F.max_pool2d(x, (3, 3))
x = F.relu(self.conv2_layer(x))
x = F.max_pool2d(x, (2, 2))
x = F.relu(self.conv3_layer(x))
x = F.max_pool2d(x, (2, 2))
x = x.view(-1, self.layer_size_after_convs)
x = self.fc1(x)
x = F.softmax(x, dim=1)
return x
model = MyNetwork()
loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, weight_decay=0.1)
total_steps = len(train_dataset_loader)
epochs = 100
for epoch_num in range(epochs):
for i, (img_batch, labels) in enumerate(train_dataset_loader):
optimizer.zero_grad()
fw_pass_output = model(img_batch)
loss_values = loss_func(fw_pass_output, labels)
loss_values.backward()
optimizer.step()
print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch_num+1, epochs, i+1, total_steps, loss_values.item()))