Почему пакет torch.nn не поддерживает входные данные, представляющие собой один образец - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь понять глубокое обучение с помощью pytorch.Я прочитал учебник по pytorch: https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html, и написано:

'' torch.nn поддерживает только мини-пакеты.Весь пакет torch.nn поддерживает только входы, представляющие собой мини-серию сэмплов, а не один сэмпл.Например, nn.Conv2d будет принимать четырехмерный тензор nSamples x nChannels x Height x Width.Если у вас есть один образец, просто используйте input.unsqueeze (0), чтобы добавить поддельный размер пакета. ''

Я не уверен, что понимаю, что это значит.Действительно, я сделал простую нейронную сеть с прямой связью (см. Ниже код), в которой я использовал действительно небольшой набор данных (идея состоит в том, чтобы сначала изучить, как он работает, без мини-пакетов, а на самом деле ничего полезного не было), иследовательно, не нужно использовать мини-партии.Следовательно, я представляю непосредственно все образцы в каждую эпоху.Если я правильно понимаю, я должен добавить 'train_data = train_data.unsqueeze (0)'.Но я не уверен, где, поскольку кажется, что размер данных изменяется на 1. Кроме того, он работает без добавления этой строки, так почему я должен действительно использовать его?

Любая помощь будет высоко оценена!

import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import pandas as pd
import os
import numpy as np

# Download data
#... 

# Construct network
len_input = len(data[0])
len_output = nbr_class
print('There is %d classes used for classification'%nbr_class)

#defining a new class: Net, that extended nn.Module
#setup the “skeleton” of our network architecture
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        #creation of fully connected. A fully connected neural network layer is represented by the nn.Linear object, 
        #with the first argument in the definition being the number of nodes in layer l and the next argument being 
        #the number of nodes in layer l+1
        self.fc1 = nn.Linear(len_input, 200)
        self.fc2 = nn.Linear(200, 200)
        self.fc3 = nn.Linear(200, len_output)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return F.log_softmax(x)

# Create initial network
epochs = 3000
model = Net()
criterion = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# Train & test network
def train(data, target, epoch):
    model.train() # set the model in "training mode"
    # run the main training loop
    #no need batch size as small number of sample! like this the process is more exact
    #zero our gradients before calling .backward() which is necessary for new sum of gradients
    optimizer.zero_grad()
    target_pred = model(data)
    loss = criterion(target_pred, target)
    #Propagate the gradients back through the network
    loss.backward()
    #update the weights
    #tell our optimizer to “step”, meaning that the weights will be updated using the calculated gradients 
    #according to our rule. perform model parameter update (update weights)
    optimizer.step()
    # for graphing puposes
    loss_array.append(loss.data[0])

    if epoch in list(range(0,20000,100)):
        print('Train Epoch: {} \tLoss: {:.6f}'.format(epoch, loss.data[0]))

def test(epoch, test_data, test_target):
    #eval mode to turn Dropout and BatchNorm off
    model.eval()
    test_loss = 0
    correct = 0
    test_target_pred = model(test_data)
    criterion = nn.NLLLoss()
    # sum up batch loss
    test_loss += criterion(test_target_pred, test_target).data[0]
    pred = test_target_pred.data.max(1)[1]  # get the index of the max log-probability
    correct += pred.eq(test_target.data).sum()
    if epoch in list(range(0,20000,100)):
        print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            test_loss, correct, len(test_target), 100. * correct / len(test_target)))

if __name__ == '__main__':
    for epoch in range(epochs):
        train(data = train_data, target=train_target, epoch=epoch)
        test(epoch, test_data, test_target)
...