Почему мой сверточный NN горелки возвращает одинаковые выходы? - PullRequest
1 голос
/ 02 мая 2020

Я работаю с учебником для сверточных нейронных сетей на pytorch и использую набор данных MNIST в качестве примера. Но я получаю одинаковые результаты для всех меток, net всегда возвращает один и тот же тензор как результат. Я решил уменьшить сложность net и уменьшить число эпох, поэтому вот мой код:

from __future__ import print_function, division
import os
import torch
import pandas as pd
from skimage import io, transform
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
# Ignore warnings
import warnings
warnings.filterwarnings("ignore")

plt.ion()   # interactive mode


class DigitsDataset(Dataset):

    def __init__(self, csv_file, transform=None):
        """
        Args:
            csv_file (string): Path to the csv file.

            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.digits_frame = pd.read_csv(csv_file)

        self.transform = transform

    def __len__(self):
        return len(self.digits_frame)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        label = digits_df.iloc[idx, 0]
        digit_pixels = digits_df.iloc[idx, 1:]
        digit_pixels = np.asarray(digit_pixels)
        digit_pixels = digit_pixels.astype('float').reshape(28, 28)
        sample = {'label' : label, 'image' : digit_pixels}
        if self.transform:
            sample['image'] = self.transform(sample['image'])

        return sample


class GrayScaleTransform:
    ''' Scale intensity from [0,255] to [0,1]'''
    def __init__(self, new_min, new_max):
        self.new_min = new_min
        self.new_max = new_max

    def __call__(self, x):
        return (x) * (self.new_max - self.new_min) / (255) + self.new_min


min_max_transform = GrayScaleTransform(new_min = 0, new_max = 1)

train_dataset = DigitsDataset(csv_file='data/train.csv', transform = min_max_transform)
test_dataset = DigitsDataset(csv_file='data/test.csv', transform = min_max_transform)

train_loader = DataLoader(train_dataset)
test_loader = DataLoader(test_dataset)

learning_rate = 0.1
num_epochs = 2

from torch import nn
class ConvNet(nn.Module): 
    def __init__(self): 
        super(ConvNet, self).__init__() 
        self.layer1 = nn.Sequential( nn.Conv2d(1, 4, kernel_size=5, stride=1, padding=2), 
        nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2)) 
        self.layer2 = nn.Sequential( nn.Conv2d(4, 8, kernel_size=5, stride=1, padding=2), 
        nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2)) 
        self.drop_out = nn.Dropout() 
        self.fc1 = nn.Linear(7 * 7 * 8, 10) 
    def forward(self, x): 
        out = self.layer1(x) 
        out = self.layer2(out) 
        out = out.reshape(out.size(0), -1) 
        out = self.drop_out(out) 
        out = self.fc1(out) 
        return out

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = ConvNet()
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

total_step = len(train_loader)
loss_list = []
acc_list = []
for epoch in range(num_epochs):
    for i, sample in enumerate(train_loader):
        # Прямой запуск
        img = sample['image'].view(-1, 1, 28, 28).float().to(device) 
        label = sample['label'].to(device)
        output = model(img)
        loss = criterion(output, label)
        loss_list.append(loss.item())

        # Обратное распространение и оптимизатор
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()


Но я все еще получаю тот же тензор, что и на выходе. Что я делаю неправильно? Почему я всегда получаю один и тот же вывод?

...