이예지님은 적은 데이터셋에서 효과적인 Transfer learning을 구현하셨다는 점에서 아주 높은 점수를 드렸습니다. 미리 학습된 MNIST Weight로 초기화 후 학습을 진행하셨는데 해당 데이터셋이 다른 나라 언어의 숫자라는 점을 감안했을 때 아주 적절한 접근법이 아니었나 생각합니다. 또 Multi GPU를 사용하셨던 점도 아주 멋있었습니다.
In [1]:
import numpy as npimport pandas as pdimport torchfrom torch.autograd import Variable as Variableimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimimport torch.utils.model_zoo as model_zoofrom torch.optim import lr_schedulerfrom collections import OrderedDictimport torchvisionfrom torch.utils.data import DataLoader, Datasetfrom torchvision import datasets, models, transformsimport matplotlib.pyplot as pltimport timeimport copyimport osplt.ion()
In [2]:
In [3]:
Out[3]:
In [4]:
In [5]:
Out[5]:
Unnamed: 0
pixel0
pixel1
pixel2
pixel3
pixel4
pixel5
pixel6
pixel7
pixel8
...
pixel774
pixel775
pixel776
pixel777
pixel778
pixel779
pixel780
pixel781
pixel782
pixel783
0
57808
0
0
0
0
0
0
0
0
0
...
0
0
0
0
0
0
0
0
0
0
1
4960
0
0
0
0
0
0
0
0
0
...
0
0
0
0
0
0
0
0
0
0
2
35755
0
0
0
0
0
0
0
0
0
...
0
0
0
0
0
0
0
0
0
0
3
15543
0
0
0
0
0
0
0
0
0
...
0
0
0
0
0
0
0
0
0
0
4
48968
0
0
0
0
0
0
0
0
0
...
0
0
0
0
0
0
0
0
0
0
5 rows × 785 columnsIn [6]:
Out[6]:
In [7]:
In [8]:
In [10]:
In [11]:
In [12]:
In [13]:
In [14]:
In [15]:
In [16]:
In [17]:
모델 설명
MINIST로 학습된 pretrained 모델을 불러와서 fine tunning을 해보자.
MLP로 구축된 모델로, MINIST에서 약 98%의 정확도를 보여줌.
def expand_user(path):
return os.path.abspath(os.path.expanduser(path))
def model_snapshot(model, new_file, old_file=None, verbose = True):
if isinstance(model, torch.nn.DataParallel):
model = model.module
if old_file and os.path.exists(expand_user(old_file)):
print("Removing old model {}".format(expand_user(old_file)))
os.remove(expand_user(old_file))
if verbose:
print("Saving model to {}".format(expand_user(new_file)))
state_dict = OrderedDict()
for k, v in model.state_dict().items():
if v.is_cuda:
v = v.cpu()
state_dict[k] = v
torch.save(state_dict, expand_user(new_file))
best_acc = 0.0
old_file = None
for epoch in range(10):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
indx_target = target.clone()
data, target = data.cuda(), target.cuda()
data, target = Variable(data), Variable(target)
optimizer.zero_grad()
output = model(data)
# output = nn.Softmax(output)
# loss = F.mse_loss(output, target)
loss=F.cross_entropy(output, target)
loss.backward()
optimizer.step()
if batch_idx % 10 ==0 and batch_idx > 0:
pred = output.data.max(1)[1] # get the index of the max log-probability
correct = pred.cpu().eq(indx_target).sum()
acc = correct * 1.0 / len(data)
print('Train Epoch: {} [{}/{}] Loss: {:.6f} Acc: {:.4f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
loss, acc))
model.eval()
test_loss = 0
correct = 0
for data, target in test_loader:
indx_target = target.clone()
data, target = data.cuda(), target.cuda()
data, target = Variable(data, volatile=True), Variable(target)
output = model(data)
test_loss += F.cross_entropy(output, target)
pred = output.data.max(1)[1]
correct += pred.cpu().eq(indx_target).sum()
test_loss = test_loss / len(test_loader)
acc = 100. * correct / float(len(test_loader.dataset))
print('\tTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format(
test_loss, correct, len(test_loader.dataset), acc))
if acc > best_acc:
new_file = os.path.join('./', 'best-{}.pth'.format(epoch))
model_snapshot(model, new_file, old_file=old_file)
best_acc = acc
old_file = new_file
C:\Users\fdal\Miniconda3\envs\torch\lib\site-packages\torch\cuda\nccl.py:24: UserWarning: PyTorch is not compiled with NCCL support
warnings.warn('PyTorch is not compiled with NCCL support')
C:\Users\fdal\AppData\Roaming\Python\Python37\site-packages\ipykernel_launcher.py:30: UserWarning: volatile was removed and now has no effect. Use `with torch.no_grad():` instead.
C:\Users\fdal\AppData\Roaming\Python\Python37\site-packages\ipykernel_launcher.py:30: UserWarning: volatile was removed and now has no effect. Use `with torch.no_grad():` instead.