Ubuntu 18.04にPyTorch 1.0をインストールし、MNISTの手書き分類を実行する

PyTorch
https://pytorch.org/

Ubuntu 18.04にインストールしてみます。

CPU:Ryzen 7
GPU:GeForce RTX 2080

CUDAはこちらの手順でインストールしました。
Ubuntu 18.04 NVIDIAドライバー、CUDAのインストール



インストール



condaを利用してのインストールが推奨されているようですが、
今回はpipでインストールしました。

OS:Linux
Package:Pip
Language:Python 3.6
CUDA:10
を選択して、インストールコマンドを確認。

975_01.png

実行します。


$ pip3 install https://download.pytorch.org/whl/cu100/torch-1.0.1.post2-cp36-cp36m-linux_x86_64.whl
$ pip3 install torchvision



インストールできたか確認します。


$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> print(torch.__version__)
1.0.1.post2
>>>






MNIST



こちらのサンプルプログラムを実行してみます。
https://github.com/pytorch/examples/blob/master/mnist/main.py


  1. from __future__ import print_function
  2. import argparse
  3. import torch
  4. import torch.nn as nn
  5. import torch.nn.functional as F
  6. import torch.optim as optim
  7. from torchvision import datasets, transforms
  8. class Net(nn.Module):
  9.     def __init__(self):
  10.         super(Net, self).__init__()
  11.         self.conv1 = nn.Conv2d(1, 20, 5, 1)
  12.         self.conv2 = nn.Conv2d(20, 50, 5, 1)
  13.         self.fc1 = nn.Linear(4*4*50, 500)
  14.         self.fc2 = nn.Linear(500, 10)
  15.     def forward(self, x):
  16.         x = F.relu(self.conv1(x))
  17.         x = F.max_pool2d(x, 2, 2)
  18.         x = F.relu(self.conv2(x))
  19.         x = F.max_pool2d(x, 2, 2)
  20.         x = x.view(-1, 4*4*50)
  21.         x = F.relu(self.fc1(x))
  22.         x = self.fc2(x)
  23.         return F.log_softmax(x, dim=1)
  24.     
  25. def train(args, model, device, train_loader, optimizer, epoch):
  26.     model.train()
  27.     for batch_idx, (data, target) in enumerate(train_loader):
  28.         data, target = data.to(device), target.to(device)
  29.         optimizer.zero_grad()
  30.         output = model(data)
  31.         loss = F.nll_loss(output, target)
  32.         loss.backward()
  33.         optimizer.step()
  34.         if batch_idx % args.log_interval == 0:
  35.             print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
  36.                 epoch, batch_idx * len(data), len(train_loader.dataset),
  37.                 100. * batch_idx / len(train_loader), loss.item()))
  38. def test(args, model, device, test_loader):
  39.     model.eval()
  40.     test_loss = 0
  41.     correct = 0
  42.     with torch.no_grad():
  43.         for data, target in test_loader:
  44.             data, target = data.to(device), target.to(device)
  45.             output = model(data)
  46.             test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss
  47.             pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability
  48.             correct += pred.eq(target.view_as(pred)).sum().item()
  49.     test_loss /= len(test_loader.dataset)
  50.     print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
  51.         test_loss, correct, len(test_loader.dataset),
  52.         100. * correct / len(test_loader.dataset)))
  53. def main():
  54.     # Training settings
  55.     parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
  56.     parser.add_argument('--batch-size', type=int, default=64, metavar='N',
  57.                         help='input batch size for training (default: 64)')
  58.     parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
  59.                         help='input batch size for testing (default: 1000)')
  60.     parser.add_argument('--epochs', type=int, default=10, metavar='N',
  61.                         help='number of epochs to train (default: 10)')
  62.     parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
  63.                         help='learning rate (default: 0.01)')
  64.     parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
  65.                         help='SGD momentum (default: 0.5)')
  66.     parser.add_argument('--no-cuda', action='store_true', default=False,
  67.                         help='disables CUDA training')
  68.     parser.add_argument('--seed', type=int, default=1, metavar='S',
  69.                         help='random seed (default: 1)')
  70.     parser.add_argument('--log-interval', type=int, default=10, metavar='N',
  71.                         help='how many batches to wait before logging training status')
  72.     
  73.     parser.add_argument('--save-model', action='store_true', default=False,
  74.                         help='For Saving the current Model')
  75.     args = parser.parse_args()
  76.     use_cuda = not args.no_cuda and torch.cuda.is_available()
  77.     torch.manual_seed(args.seed)
  78.     device = torch.device("cuda" if use_cuda else "cpu")
  79.     kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
  80.     train_loader = torch.utils.data.DataLoader(
  81.         datasets.MNIST('../data', train=True, download=True,
  82.                      transform=transforms.Compose([
  83.                          transforms.ToTensor(),
  84.                          transforms.Normalize((0.1307,), (0.3081,))
  85.                      ])),
  86.         batch_size=args.batch_size, shuffle=True, **kwargs)
  87.     test_loader = torch.utils.data.DataLoader(
  88.         datasets.MNIST('../data', train=False, transform=transforms.Compose([
  89.                          transforms.ToTensor(),
  90.                          transforms.Normalize((0.1307,), (0.3081,))
  91.                      ])),
  92.         batch_size=args.test_batch_size, shuffle=True, **kwargs)
  93.     model = Net().to(device)
  94.     optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)
  95.     for epoch in range(1, args.epochs + 1):
  96.         train(args, model, device, train_loader, optimizer, epoch)
  97.         test(args, model, device, test_loader)
  98.     if (args.save_model):
  99.         torch.save(model.state_dict(),"mnist_cnn.pt")
  100.         
  101. if __name__ == '__main__':
  102.     main()




実行


$ python3 main.py
...
Train Epoch: 10 [57600/60000 (96%)]    Loss: 0.005530
Train Epoch: 10 [58240/60000 (97%)]    Loss: 0.170552
Train Epoch: 10 [58880/60000 (98%)]    Loss: 0.004517
Train Epoch: 10 [59520/60000 (99%)]    Loss: 0.005983

Test set: Average loss: 0.0313, Accuracy: 9894/10000 (99%)



動いてくれたようです。




動作確認



解析結果を実際に目で見て確認しようと思います。
毎回解析するのは面倒なので、結果のモデルを保存。


$ python3 main.py --save-model



「mnist_cnn.pt」というファイル名で保存されました。

テスト画像を1件づつ解析しながら表示します。

・sample.py


  1. from __future__ import print_function
  2. import matplotlib.pyplot as plt
  3. import torch
  4. import torch.nn as nn
  5. import torch.nn.functional as F
  6. import torch.optim as optim
  7. from torchvision import datasets, transforms
  8. class Net(nn.Module):
  9.     def __init__(self):
  10.         super(Net, self).__init__()
  11.         self.conv1 = nn.Conv2d(1, 20, 5, 1)
  12.         self.conv2 = nn.Conv2d(20, 50, 5, 1)
  13.         self.fc1 = nn.Linear(4*4*50, 500)
  14.         self.fc2 = nn.Linear(500, 10)
  15.     def forward(self, x):
  16.         x = F.relu(self.conv1(x))
  17.         x = F.max_pool2d(x, 2, 2)
  18.         x = F.relu(self.conv2(x))
  19.         x = F.max_pool2d(x, 2, 2)
  20.         x = x.view(-1, 4*4*50)
  21.         x = F.relu(self.fc1(x))
  22.         x = self.fc2(x)
  23.         return F.log_softmax(x, dim=1)
  24.     
  25. def main():
  26.     device = torch.device('cpu')
  27.     # 保存しておいたモデルをロード
  28.     model = Net()
  29.     model.load_state_dict(torch.load('mnist_cnn.pt'))
  30.     
  31.     # 推論モードに切り替え
  32.     model.eval()
  33.     # テストデータロード
  34.     test_loader = torch.utils.data.DataLoader(
  35.         datasets.MNIST('../data', train=False, transform=transforms.Compose([
  36.                          transforms.ToTensor(),
  37.                          transforms.Normalize((0.1307,), (0.3081,))
  38.                      ])),
  39.         batch_size=1, shuffle=False)
  40.     # 最初から3件のデータを解析
  41.     count = 0
  42.     for data, target in test_loader:
  43.         output = model(data.to(device))
  44.         pred = output.argmax(dim=1, keepdim=True)
  45.         print(pred[0])
  46.         plt.imshow(data.reshape(28, 28), cmap='gray')
  47.         plt.show()
  48.         count += 1
  49.         if (count > 2):
  50.             break
  51.         
  52. if __name__ == '__main__':
  53.     main()




実行結果


$ python3 sample.py
tensor([7])
tensor([2])
tensor([1])




「7」と判定

975_02.png


「2」と判定

975_03.png


「1」と判定

975_04.png


【参考URL】

https://pytorch.org/
https://github.com/pytorch/examples
https://github.com/pytorch/examples/blob/master/mnist/main.py
CNN in MNIST with PyTorch (PyTorchの基本メモ)
PyTorchでMNISTをやってみる
第13回 PyTorchによるディープラーニング実装入門(2)

関連記事

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ