我在CIFAR-10数据集上训练了一个简单的全连接网络:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(3*32*32, 300, bias=False)
self.fc2 = nn.Linear(300, 10, bias=False)
def forward(self, x):
x = x.reshape(250, -1)
self.x2 = F.relu(self.fc1(x))
x = self.fc2(self.x2)
return x
def train():
# The output of torchvision datasets are PILImage images of range [0, 1].
transform = transforms.Compose([transforms.ToTensor()])
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=250, shuffle=True, num_workers=4)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=args.bs, shuffle=False, num_workers=4)
net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.02, momentum=0.9, weight_decay=0.0001)
for epoch in range(20):
correct = 0
total = 0
for data in trainloader:
inputs, labels = data
outputs = net(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100. * correct / total
在20个时期后,该网络在指定参数的情况下达到~50%的测试精度。请注意,我没有对输入进行任何白化(没有每个通道的均值减法)
接下来,我将模型输入放大了255倍,用outputs = net(inputs*255)
替换了outputs = net(inputs)
。在此更改之后,网络将不再收敛。我查看了梯度,它们似乎在几次迭代后呈爆炸性增长,导致所有模型输出为零。我想知道为什么会发生这样的事情。
此外,我还尝试将学习率降低了255。这很有帮助,但网络只能达到~43%的准确率。再说一次,我不明白为什么这会有帮助,更重要的是,为什么与原始设置相比,准确性仍然下降。
编辑:忘了提一下,我在这个网络中不使用偏见。
EDIT2:如果我将两层中的初始权重都缩小255 (除了缩小学习率之外),我可以恢复原始的精度。我还试图仅在第一层中缩小初始权重,但网络在学习方面遇到了问题(即使我确实缩小了两层的学习率)。然后我试着只在第一层降低学习率-这也没有帮助。最后,我尝试进一步降低两层的学习率( 255*255),这突然起作用了。这对我来说是没有意义的-按相同的因子缩小初始权重,输入应该已经完全消除了与原始网络的任何差异,第二层的输入是相同的。在这一点上,学习率应该只在第一层缩小,但在实践中,两层都需要明显较低的学习率……
发布于 2020-04-27 06:38:40
由于以下几个观察结果,放大输入将导致梯度爆炸:
像素的值范围是0到255,因此将数据缩放255将确保所有输入都在0和1之间,因此更平滑地收敛,因为所有梯度相对于学习率将是均匀的。但在这里,您缩放了学习率,它调整了上面提到的一些问题,但不如缩放数据本身那么有效。这降低了学习率,从而使收敛时间更长,这可能是它在20个时期达到43%的原因,也许它需要更多的时期。
此外: CIFAR-10比MNIST数据集是一个重要的进步,因此,完全连接的神经网络没有准确预测这些图像所需的表示能力。对于MNIST之外的任何图像分类任务,CNN都是可行的。不幸的是,使用完全连接的神经网络,~50%的准确率是最高的。
发布于 2020-04-27 18:23:23
可能会将学习率降低1/255 ...只是个猜测
https://stackoverflow.com/questions/61451662
复制相似问题