【发布时间】:2021-08-26 11:23:36
【问题描述】:
我是深度学习和计算机视觉的新手,在完成 CNN 上的 Courseera 课程后,我想到了复制作业,但使用 PyTorch 而不是 Tensorflow。其中一项任务涉及使用 ResNet 架构进行手势分类。
我创建了 ResNet34 和 ResNet50,以最大限度地理解论文中的描述,但是,当我训练它时,损失不会消失。已经3天了,我想不出任何修复方法。目前不确定是模型问题还是任何脚本问题。请参考github上的代码。
这是我创建模型并对其进行训练的方式。
class Block34(nn.Module):
def __init__(self,in_c,out_c):
super().__init__()
if in_c != out_c:
s = 2
self.residual = True
self.conv_s = nn.Conv2d(in_c,out_c,1,stride=s)
self.bn_s = nn.BatchNorm2d(out_c)
else:
s = 1
self.residual = False
self.conv_a = nn.Conv2d(in_c,out_c,3,stride=s,padding=1)
self.bn_a = nn.BatchNorm2d(out_c)
self.conv_b = nn.Conv2d(out_c,out_c,3,padding=1)
self.bn_b = nn.BatchNorm2d(out_c)
def forward(self,x):
shortcut=x
out = F.relu(self.bn_a(self.conv_a(x)))
out = self.bn_a(self.conv_a(x))
if self.residual:
shortcut = self.bn_s(self.conv_s(shortcut))
return F.relu(out + shortcut)
class ResNet34(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3,64,7,stride=2)
self.bn1 = nn.BatchNorm2d(64)
self.pool1 = nn.MaxPool2d(3,2)
self.conv2_1 = Block34(64,64)
self.conv2_2 = Block34(64,64)
self.conv2_3 = Block34(64,64)
self.conv3_1 = Block34(64,128)
self.conv3_2 = Block34(128,128)
self.conv3_3 = Block34(128,128)
self.conv3_4 = Block34(128,128)
self.conv4_1 = Block34(128,256)
self.conv4_2 = Block34(256,256)
self.conv4_3 = Block34(256,256)
self.conv4_4 = Block34(256,256)
self.conv4_5 = Block34(256,256)
self.conv4_6 = Block34(256,256)
self.conv5_1 = Block34(256,512)
self.conv5_2 = Block34(512,512)
self.conv5_3 = Block34(512,512)
self.pool5 = nn.AvgPool2d(2,2)
self.fc6 = nn.Linear(512,6)
def forward(self, X):
out = F.relu(self.bn1(self.conv1(X)))
out = self.pool1(out)
out = self.conv2_1(out)
out = self.conv2_2(out)
out = self.conv2_3(out)
out = self.conv3_1(out)
out = self.conv3_2(out)
out = self.conv3_3(out)
out = self.conv3_4(out)
out = self.conv4_1(out)
out = self.conv4_2(out)
out = self.conv4_3(out)
out = self.conv4_4(out)
out = self.conv4_5(out)
out = self.conv4_6(out)
out = self.conv5_1(out)
out = self.conv5_2(out)
out = self.conv5_3(out)
out = self.pool5(out)
c,h = out.shape[1], out.shape[2]
out = self.fc6(out.view(-1,c*h*h))
return F.softmax(out)
我通过分成 54 批每批 20 张图像来训练 1080 张形状 (64,64,3) 的图像。在循环中,i 用于训练 epoch,j 用于获取 minibatch 的图像。
torch.manual_seed(1)
classifier = ResNet34().to(device)
optimizer = optim.Adam(classifier.parameters(), lr=0.75)
loss_func = nn.CrossEntropyLoss()
losses = []
epochs = 10
mini_batches = int(m_train/20)
print('{} minibatches for {} epochs.'.format(mini_batches,epochs))
for i in range(10):
for j in range(mini_batches):
y_h = classifier(train_x[j*20:(j+1)*20].view(-1,c,h,w))
classifier.zero_grad()
loss = loss_func(y_h,train_y[j*20:(j+1)*20].long())
loss.backward()
optimizer.step()
losses.append(loss)
print('Epoch:{}, loss:{}'.format(i,loss))
输出:
54.0 minibatches for 10 epochs.
Epoch:0, loss:1.8435920476913452
Epoch:1, loss:1.8435920476913452
Epoch:2, loss:1.8435920476913452
Epoch:3, loss:1.8435920476913452
Epoch:4, loss:1.8435920476913452
Epoch:5, loss:1.8435920476913452
Epoch:6, loss:1.8435920476913452
Epoch:7, loss:1.8435920476913452
Epoch:8, loss:1.8435920476913452
Epoch:9, loss:1.8435920476913452
【问题讨论】:
-
你的学习率是天文数字。试试 3e-4。这只是我在您的算法中注意到的一个问题。训练深度学习模型是一个复杂的过程,需要克服许多障碍。如果您需要更多帮助,请报告此更改的结果并回来查看更多指导。
-
@yanziselman,感谢您的评论。我之前使用了 0.0001,但实现了相同的输出,但进一步下降实际上显示收敛前下降。 0.00001 在 5 个 epoch 中收敛,训练精度为 99,测试精度为 75。我计算的损失正确吗?
标签: machine-learning deep-learning computer-vision pytorch conv-neural-network