Optimization & Training
https://github.com/pytorch/examples/tree/master/mnist
Load Packages
1 2 3 4 5 6 7 import torchimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimfrom torchvision import datasets, transformsimport numpy as np
1 2 3 4 5 6 7 no_cuda = False use_cuda = not no_cuda and torch.cuda.is_available() device = torch.device("cuda" if use_cuda else "cpu" ) => device(type='cuda')
Preprocess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 seed = 1 batch_size = 64 test_batch_size = 64 torch.manual_seed(seed) train_loader = torch.utils.data.DataLoader( datasets.MNIST('dataset' , train=True , download=True , transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307 ,), (0.3081 ,)) ])), batch_size=batch_size, shuffle=True ) test_loader = torch.utils.data.DataLoader( datasets.MNIST('dataset' , train=False , transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307 ,), (0.3081 ,)) ])), batch_size=test_batch_size, shuffle=True )
Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Net (nn.Module) : def __init__ (self) : super(Net, self).__init__() self.conv1 = nn.Conv2d(1 , 20 , 5 , 1 ) self.conv2 = nn.Conv2d(20 , 50 , 5 , 1 ) self.fc1 = nn.Linear(4 * 4 * 50 , 500 ) self.fc2 = nn.Linear(500 , 10 ) def forward (self, x) : x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2 , 2 ) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2 , 2 ) x = x.view(-1 , 4 * 4 * 50 ) x = F.relu(self.fc1(x)) x = self.fc2(x) return F.log_softmax(x, dim=1 )
Optimization
Model과 Optimization를 설정한다.
SGD 사용
확률적 경사 하강법(Stochastic Gradient Descent, SGD) 옵티마이저
Lr(learning Rate) : 0 보다 크거나 같은 float 값. 학습률
momentum: 0 보다 크거나 같은 float 값. SGD를 적절한 방향으로 가속화하며, 흔들림(진동)을 줄여주는 매개변수
1 2 model = Net().to(device) optimizer = optim.SGD(model.parameters(), lr=0.001 , momentum=0.5 )
parameters를 확인합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 params = list(model.parameters()) for i in range(8 ): print(params[i].size()) torch.Size([20 , 1 , 5 , 5 ]) torch.Size([20 ]) torch.Size([50 , 20 , 5 , 5 ]) torch.Size([50 ]) torch.Size([500 , 800 ]) torch.Size([500 ]) torch.Size([10 , 500 ]) torch.Size([10 ])
Before Training
학습하기 전에 Model이 Train할 수 있도록 Train Mode로 변환한다.
Convolution 또는 Linear 뿐만 아니라, DropOut과 Batch Normalization과 같이 parameter를 가진 Layer들도 학습하기 위해 준비한다.
1 2 3 4 5 6 7 8 9 10 model.train() Net( (conv1): Conv2d(1 , 20 , kernel_size=(5 , 5 ), stride=(1 , 1 )) (conv2): Conv2d(20 , 50 , kernel_size=(5 , 5 ), stride=(1 , 1 )) (fc1): Linear(in_features=800 , out_features=500 , bias=True ) (fc2): Linear(in_features=500 , out_features=10 , bias=True ) )
모델에 넣기 위한 첫 Batch 데이터를 추출하고 cpu 또는 gpu device에 컴파일한다.
1 2 3 4 5 data, target = next(iter(train_loader)) data, target = data.to(device), target.to(device) data.shape, target.shape => (torch.Size([64, 1, 28, 28]), torch.Size([64]))
기울기(gradients)를 clear해서 새로운 최적화 값을 찾기 위해 준비한다. 그리고 준비한 데이터를 model에 넣어 output을 얻습니다. Model에서 예측한 결과를 Loss Function에 넣는다.
1 2 3 4 5 optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target)
Back Propagation을 통해 기울기를 계산한다. 계산된 기울기는 Parameter에 업데이트를 한다.
1 2 3 4 loss.backward() optimizer.step()
Start Training
위의 최적화 과정을 반복하여 학습을 시작한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 epochs = 1 log_interval = 100 for epoch in range(1 , epochs + 1 ): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = F.nll_loss(output, target) loss.backward() optimizer.step() if batch_idx % log_interval == 0 : print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}' .format( epoch, batch_idx * len(data), len(train_loader.dataset), 100 * batch_idx / len(train_loader), loss.item() )) Train Epoch: 1 [0 /60000 (0 %)] Loss: 2.290735 Train Epoch: 1 [6400 /60000 (11 %)] Loss: 2.228956 Train Epoch: 1 [12800 /60000 (21 %)] Loss: 2.121080 Train Epoch: 1 [19200 /60000 (32 %)] Loss: 1.893549 Train Epoch: 1 [25600 /60000 (43 %)] Loss: 1.570034 Train Epoch: 1 [32000 /60000 (53 %)] Loss: 1.213198 Train Epoch: 1 [38400 /60000 (64 %)] Loss: 0.993993 Train Epoch: 1 [44800 /60000 (75 %)] Loss: 0.778737 Train Epoch: 1 [51200 /60000 (85 %)] Loss: 0.732925 Train Epoch: 1 [57600 /60000 (96 %)] Loss: 0.624502