Я тренирую NN в pytorch на данных MNIST. Модель хорошо запускается, совершенствуется, достигает хорошей точности как для обучения, так и для данных тестирования, стабилизируется некоторое время, а затем и тест, и точность обучения снижаются, как показано на следующем базовом графике результатов .
Что касается MNIST, я использую 60000 тренировочных образов, 10000 тестов, размер тренировочной партии 100 и скорость обучения 0,01. Нейронная сеть состоит из двух полностью связанных скрытых слоев, каждый из которых содержит 100 узлов, а узлы имеют функции активации ReLU. F.cross_entropy используется для потерь и SGD для расчета градиентов.
Это не проблема переоснащения, так как падает точность обучения и тестирования. Я подозревал, что это связано со слишком большой скоростью обучения. В базовом случае я использовал 0,01, но когда я опускаю его до 0,001, весь шаблон повторяется, чуть позже, как показано на на следующем графике (обратите внимание, изменение масштаба по оси X, шаблон происходит примерно 10 времена спустя, что интуитивно понятно). Аналогичные результаты были получены при использовании еще более низких показателей обучения.
Я пробовал модульное тестирование, проверял отдельные детали и делал модель меньше. Здесь - это результаты, когда я использую только 6 точек данных в обучающем наборе, размер партии 2. Идеальная подгонка к тренировочным данным (здесь они явно отличаются от точности теста, как и ожидалось), что неудивительно достигается, но все же падает от 100% до 1/6, так что не лучше, чем случайный выбор. Кто-нибудь может мне сказать, что должно произойти для того, чтобы сеть развернулась в идеальном положении на тренировочном наборе?
Вот структура сети (соответствующие библиотеки добавляются ранее), хотя я надеюсь, что вышеупомянутых симптомов будет достаточно, чтобы вы могли распознать, в чем проблема без нее:
class Network(nn.Module):
def __init__(self):
# call to the super class Module from nn
super(Network, self).__init__()
# fc strand for 'fully connected'
self.fc1 = nn.Linear(in_features=28*28, out_features=100)
self.fc2 = nn.Linear(in_features=100, out_features=100)
self.out = nn.Linear(in_features=100, out_features=10)
def forward(self, t):
# (1) input layer (redundant)
t = t
# (2) hidden linear layer
# As my t consists of 28*28 bit pictures, I need to flatten them:
t = t.reshape(-1, 28*28)
# Now having this reshaped input, add it to the linear layer
t = self.fc1(t)
# Again, apply ReLU as the activation function
t = F.relu(t)
# (3) hidden linear layer
# As above, but reshaping is not needed now
t = self.fc2(t)
t = F.relu(t)
# (4) output layer
t = self.out(t)
t = F.softmax(t, dim=1)
return t
Основное исполнение кода:
for b in range(epochs):
print('***** EPOCH NO. ', b+1)
# getting a batch iterator
batch_iterator = iter(batch_train_loader)
# For loop for a single epoch, based on the length of the training set and the batch size
for a in range(round(train_size/b_size)):
print(a+1)
# get one batch for the iteration
batch = next(batch_iterator)
# decomposing a batch
images, labels = batch[0].to(device), batch[1].to(device)
# to get a prediction, as with individual layers, we need to equate it to the network with the samples as input:
preds = network(images)
# with the predictions, we will use F to get the loss as cross_entropy
loss = F.cross_entropy(preds, labels)
# function for counting the number of correct predictions
get_num_correct(preds, labels))
# calculate the gradients needed for update of weights
loss.backward()
# with the known gradients, we will update the weights according to stochastic gradient descent
optimizer = optim.SGD(network.parameters(), lr=learning_rate)
# with the known weights, step in the direction of correct estimation
optimizer.step()
# check if the whole data check should be performed (for taking full training/test data checks only in evenly spaced intervals on the log scale, pre-calculated later)
if counter in X_log:
# get the result on the whole train data and record them
full_train_preds = network(full_train_images)
full_train_loss = F.cross_entropy(full_train_preds, full_train_labels)
# Record train loss
a_train_loss.append(full_train_loss.item())
# Get a proportion of correct estimates, to make them comparable between train and test data
full_train_num_correct = get_num_correct(full_train_preds, full_train_labels)/train_size
# Record train accuracy
a_train_num_correct.append(full_train_num_correct)
print('Correct predictions of the dataset:', full_train_num_correct)
# Repeat for test predictions
# get the results for the whole test data
full_test_preds = network(full_test_images)
full_test_loss = F.cross_entropy(full_test_preds, full_test_labels)
a_test_loss.append(full_test_loss.item())
full_test_num_correct = get_num_correct(full_test_preds, full_test_labels)/test_size
a_test_num_correct.append(full_test_num_correct)
# update counter
counter = counter + 1
Я гуглил и проверил здесь ответы на эти вопросы, но люди либо спрашивают о переоснащении, либо их NN вообще не повышают точность в тренировочном наборе (то есть они просто не работают), а не о поиске хорошего тренировки подходят, а затем полностью теряют его, также на тренировочном наборе. Я надеюсь, что я не опубликовал что-то очевидное, я относительно новичок в NN, но я приложил все усилия, чтобы изучить эту тему, прежде чем публиковать ее здесь, спасибо за вашу помощь и понимание!