Я обучил простую полностью подключенную сеть на наборе данных 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
Эта сеть достигает ~ 50% точности теста с заданными параметрами после 20 эпох. Обратите внимание, что я не делал никакого отбеливания входов (нет вычитания для каждого канала)
Затем я увеличил масштаб входов модели на 255, заменив outputs = net(inputs)
на outputs = net(inputs*255)
. После этого изменения сеть больше не сходится. Я посмотрел на градиенты, и они, кажется, быстро растут после нескольких итераций, что приводит к тому, что все результаты модели равны нулю. Я хотел бы понять, почему это происходит.
Кроме того, я попытался уменьшить скорость обучения на 255. Это помогает, но сеть получает точность до ~ 43%. Опять же, я не понимаю, почему это помогает, и, что более важно, почему точность все еще ухудшается по сравнению с исходными настройками.
РЕДАКТИРОВАТЬ: забыл упомянуть, что я не использую смещения в этой сети.
EDIT2: я могу восстановить исходную точность, если уменьшу начальные веса в обоих слоях на 255 (в дополнение к уменьшению скорости обучения). Я также пытался уменьшить начальные веса только в первом слое, но в сети возникли проблемы с обучением (даже когда я уменьшил скорость обучения в обоих слоях). Затем я попытался уменьшить скорость обучения только на первом уровне - это тоже не помогло. Наконец, я попытался уменьшить скорость обучения в обоих слоях еще больше (на 255 * 255), и это неожиданно сработало. Это не имеет смысла для меня - уменьшение начальных весов на тот же коэффициент, что и масштабирование входов, должно полностью устранить любые отличия от исходной сети, вход на второй уровень идентичен. В этот момент скорость обучения должна быть уменьшена только в первом слое, но на практике оба уровня требуют значительно более низкой скорости обучения ...