분석시각화 대회 코드 공유 게시물은
내용 확인 후
좋아요(투표) 가능합니다.
질문드립니다!! 에러 없이 잘 수행되는데 결과가 너무 안좋네요..
안녕하세요~ 딥러닝을 시작한지 얼마 안된 초보입니다.
pytorch로 코드를 짜봤는데, train, validation loss 는 좋지는 않지만 제 예상과 비슷한 값이 나옵니다...
그런데 test만 하면 loss가 1이 넘어버리네요...
혹시 제가 어떤 부분에서 실수를 해서 test시 제대로 안되는지 여쭤보고싶습니다.
답변 부탁드려요!!!! 여유가 있으신 분이시라면 혹시 어떤 방식으로 loss를 더 줄일 수 있는지 알려주시면 감사하겠습니다~!!
import re
from copy import deepcopy
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchtext import data
batch_size = 32
embedded_size = 128
hidden_size = 150
n_classes = 5
EPOCHS = 7
TEXT = data.Field(sequential=True,
use_vocab=True,
tokenize=str.split,
lower=True,
batch_first=True,
fix_length=None)
LABEL = data.Field(sequential=False,
use_vocab=False,
is_target=True)
from torchtext.data import TabularDataset
train_data = TabularDataset(
path = './data/train.nltk.csv',
format = 'csv',
fields = [('text', TEXT), ('label', LABEL)],
skip_header = True)
test_data = TabularDataset(
path = './data/test_x.nltk.1.csv',
format = 'csv',
fields = [('text', TEXT)],
skip_header = True)
print(vars(train_data[0]))
TEXT.build_vocab(train_data, min_freq=7, max_size=20000, vectors = "fasttext.en.300d")
train_data, valid_data = train_data.split(split_ratio=0.8, stratified=True)
from torchtext.data import BucketIterator
train_loader, valid_loader = BucketIterator.splits(
(train_data, valid_data),
batch_size = batch_size,
device='cuda:0',
shuffle = True,
sort_key=lambda x:len(x.text),
sort_within_batch=True
)
test_loader = BucketIterator(
test_data,
batch_size = batch_size,
device='cuda:0',
shuffle = False,
sort_key=lambda x:len(x.text),
sort_within_batch=True
)
from tqdm import tqdm
model = LSTM(len(TEXT.vocab), embedded_size, hidden_size, n_classes).to('cuda:0')
crit = nn.NLLLoss().to('cuda:0')
optimizer = optim.Adam(model.parameters(), lr=0.001)
best_loss = 999999
best_model = None
for i in range(EPOCHS):
train_loss = 0
train_accuracy = 0
model.train()
for x, y in tqdm(train_loader):
optimizer.zero_grad()
x, y = x.to('cuda:0'), y.to('cuda:0')
y_hat = model(x)
loss = crit(y_hat, y)
loss.backward()
optimizer.step()
if isinstance(y, torch.LongTensor) or isinstance(y, torch.cuda.LongTensor):
accuracy = (torch.argmax(y_hat, dim=-1) == y).sum() / float(y.size(0))
else:
accuracy = 0
train_loss += float(loss) / len(train_loader)
train_accuracy += accuracy / len(train_loader)
valid_loss = 0
valid_accuracy = 0
with torch.no_grad():
model.eval()
for x, y in valid_loader:
x, y = x.to('cuda:0'), y.to('cuda:0')
y_hat = model(x)
loss = crit(y_hat, y)
if isinstance(y, torch.LongTensor) or isinstance(y, torch.cuda.LongTensor):
accuracy = (torch.argmax(y_hat, dim=-1) == y).sum() / float(y.size(0))
else:
accuracy = 0
valid_loss += float(loss) / len(valid_loader)
valid_accuracy += accuracy / len(valid_loader)
if valid_loss < best_loss:
best_loss = valid_loss
best_model = deepcopy(model.state_dict())
print("EPOCHS: {:2d} | train_accuracy: {:.4f} / train_loss: {:.4f} / valid_accuracy: {:.4f} / valid_loss: {:.4f} / best_loss: {:.4f}".format
(i+1, train_accuracy, train_loss, valid_accuracy, valid_loss, best_loss))
test_model = LSTM(len(TEXT.vocab), embedded_size, hidden_size, n_classes).to('cuda:0')
test_model.load_state_dict(best_model)
test_model.eval()
y_hats = []
with torch.no_grad():
for x_batch in test_loader:
x = x_batch.text.to('cuda:0')
y_hat = test_model(x).cpu()
y_hats += y_hat
y_hats = torch.stack(y_hats).exp()
test_pred = y_hats.numpy()
import pandas as pd
sub = pd.read_csv('./data/sample_submission.csv', index_col=0)
sub[sub.columns] = test_pred
sub.head()
sub.to_csv('./data/submission2.csv')
답변 감사합니다~!!
이것 저것 시도해보니까 문제를 해결했습니다!
제가 바보같이 test셋까지 shuffle해주어 결과가 다르게 나왔었네요ㅎㅎ 감사합니다~!
데이콘(주) | 대표 김국진 | 699-81-01021
통신판매업 신고번호: 제 2021-서울영등포-1704호
서울특별시 영등포구 은행로 3 익스콘벤처타워 901호
이메일 dacon@dacon.io | 전화번호: 070-4102-0545
Copyright ⓒ DACON Inc. All rights reserved
torch.save(model, PATH + 'model.pt') 사용해서 모델을 통으로 세이브/로드하는게 어떨까 싶습니다. 모델 웨이트가 업데이트가 안되는거 같네요.