안녕하세요. pytorch로 처음 딥러닝을 접하고 있는 학생입니다.
제가 생성한 Custom dataset과 CIFAR10의 학습에 이용된 일부 코드를 병합하는 과정에서 다음과 같은 문제가 발생하여 글을 남겨봅니다.
# ****** Import pytorch Library ******
import pandas as pd
import time
import torch
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torchvision.models as models
import torch.utils.data as data_utils
from torchsummary import summary as summary
from torch.utils.data import Dataset, DataLoader
import matplotlib.pyplot as plt
%matplotlib inline
# Device configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('Our device configuration : {}'.format(device))
# Hyperparameters
BatchSize = 10 # 4
LearingRate = 0.001
# ****** Class MyDataLoader ******
class MyDataLoader(Dataset):
def __init__(self, csv_path):
df = pd.read_csv(csv_path, header=None, index_col=False)
# input of dataset
if (csv_path == '/content/drive/MyDrive/mydataset/H_train_32.csv'):
self.input = df.iloc[:,:1024].values.reshape(350000,1,32,32)
self.ans = df.iloc[:,1024:].values
elif (csv_path == '/content/drive/MyDrive/mydataset/H_valid_32.csv'):
self.input = df.iloc[:,:1024].values.reshape(100000,1,32,32)
self.ans = df.iloc[:,1024:].values
else:
self.input = df.iloc[:,:1024].values.reshape(50000,1,32,32)
self.ans = df.iloc[:,1024:].values
# torch.FloatTensor -> torch.float32
self.input = torch.tensor(self.input, dtype = torch.float32)
# LongTensor -> torch.long or torch.int
self.ans = torch.tensor(self.ans, dtype = torch.float32)
def __len__(self):
return len(self.input)
def __getitem__(self, index):
return self.input[index], self.ans[index]
# ****** train_loader ******
train_dataset = MyDataLoader(csv_path = '/content/drive/MyDrive/mydataset/H_train_32.csv')
train_loader = DataLoader(dataset = train_dataset, batch_size = BatchSize, drop_last = True, shuffle = True, num_workers = 2)
# ****** valid_loader ******
valid_dataset = MyDataLoader(csv_path = '/content/drive/MyDrive/mydataset/H_valid_32.csv')
valid_loader = DataLoader(dataset = valid_dataset, batch_size = BatchSize, shuffle = True, num_workers = 2)
# ****** test_loader ******
test_dataset = MyDataLoader(csv_path = '/content/drive/MyDrive/mydataset/H_test_32.csv')
test_loader = DataLoader(dataset = test_dataset, batch_size = BatchSize, shuffle = True, num_workers = 2)
# CIFAR10 CNN model
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.conv2_drop = nn.Dropout2d() # 추가됨
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
# flatten all dimensions except batch
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
# net (simple torch style)
cnn = CNN()
print('*** CNN architecture *** \n')
print(cnn)
loss_func = nn.MSELoss() # mean squared error
optimizer = torch.optim.Adam(cnn.parameters(), lr=LearingRate)
# train loop
from tqdm import tqdm
cnn.train()
# loop over the dataset multiple times
for epoch in range(1):
running_loss = 0.0
for i, data in tqdm(enumerate(train_loader),total = len(train_loader)):
# get the inputs; data is a list of [inputs, labels]
inputs, labels = data
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = cnn(inputs)
loss = loss_func(outputs, labels)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.item()
# print every 100 mini-batches
if i % 5000 == 4999:
print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 5000:.3f}')
running_loss = 0.0
# ****** Save and load the model via state_dict ******
PATH = "mymodel.pt"
# Save
torch.save(cnn, PATH)
print('Finished model saving!')
print('Finished Training!')
# test (real label vs predicted label)
dataiter = iter(test_loader)
inputs, labels = dataiter.next()
cnn = CNN()
cnn = torch.load(PATH)
outputs = cnn(inputs)
_, predicted = torch.max(outputs.data, 1)
print("$$$$$$$$$$$$$$$$$$$$$$$$$$ fully labels $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
print(labels.int()[:], '\n')
print("$$$$$$$$$$$$$$$$$$$$$$$$$$ predicted $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
print(predicted.int()[:], '\n')
이때, 첨부드린 코드에서 가장 하단의 lables.int()[:], predicted.int()[:]의 값을 각각 출력하면 다음과 같은 결과를 반환합니다.
$$$$$$$$$$$$$$$$$$$$$$$$$$ labels $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
tensor([[ 2, 6, 8, 9, 13, 19, 22, 23, 28, 29],
[ 1, 4, 9, 11, 12, 19, 20, 21, 28, 30],
[ 4, 7, 15, 16, 18, 25, 26, 28, 31, 32],
[ 9, 11, 15, 16, 17, 20, 23, 24, 25, 32],
[ 3, 4, 5, 10, 14, 15, 17, 19, 25, 27],
[ 3, 5, 14, 18, 19, 20, 22, 24, 27, 29],
[ 6, 7, 13, 14, 21, 25, 26, 28, 30, 31],
[ 4, 7, 10, 14, 15, 16, 17, 23, 29, 32],
[ 6, 10, 14, 16, 17, 19, 23, 24, 25, 32],
[ 2, 9, 11, 12, 16, 19, 22, 24, 27, 30]], dtype=torch.int32)
$$$$$$$$$$$$$$$$$$$$$$$$$$ predicted $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
tensor([9, 9, 9, 9, 9, 9, 9, 9, 9, 9], dtype=torch.int32)
왜 이렇게 되는지 그리고 어떻게 처리하면 predicted 값을 labels와 동일한 형태로 출력할 수 있는지가 궁금합니다.