Symfoware

Symfowareについての考察blog

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)

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2019/03/11(月) 23:26:19|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

PyQt5にmatplotlibを埋め込んでグラフを表示する

PyQt5、matplotlibを埋め込むことができるようです。
user_interfaces example code: embedding_in_qt5.py

使い方を調べてみます。


シンプルなサンプル



参考にしたソースから、極力シンプルなプログラムに切り出して構造を理解します。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib
  3. matplotlib.use('Qt5Agg')
  4. from PyQt5 import QtCore, QtWidgets
  5. from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
  6. from matplotlib.figure import Figure
  7. class ApplicationWindow(QtWidgets.QMainWindow):
  8.     def __init__(self):
  9.         QtWidgets.QMainWindow.__init__(self)
  10.         self.main_widget = QtWidgets.QWidget(self)
  11.         l = QtWidgets.QVBoxLayout(self.main_widget)
  12.         
  13.         # --------------------------------------------
  14.         # FigureCanvasに表示するグラフ
  15.         fig = Figure()
  16.         # グラフを表示するFigureCanvasを作成
  17.         fc = FigureCanvas(fig)
  18.         # グラフの設定
  19.         fc.axes = fig.add_subplot(111)
  20.         fc.axes.plot([1, 2, 3], [2, 3, 4])
  21.         # 描画設定
  22.         fc.setParent(self.main_widget)
  23.         FigureCanvas.setSizePolicy(fc,
  24.                                  QtWidgets.QSizePolicy.Expanding,
  25.                                  QtWidgets.QSizePolicy.Expanding)
  26.         FigureCanvas.updateGeometry(fc)
  27.         # --------------------------------------------
  28.         # 作成したFigureCanvasを画面に追加
  29.         l.addWidget(fc)
  30.         # 中央に配置
  31.         self.setCentralWidget(self.main_widget)
  32. qApp = QtWidgets.QApplication([])
  33. aw = ApplicationWindow()
  34. aw.setWindowTitle("matplotlib sample")
  35. aw.show()
  36. qApp.exec_()



ポイントは
・FigureCanvasというmatplotlibのグラフを配置する専用のCanvasをQtの画面に追加する。
・FigureCanvasへはmatplotlibの「Figure」を設定する
・「Figure」を介してグラフの描画を指定する
というところでしょうか。

実行結果はこうなりました。

959_01.png



背景画像の指定



グラフに背景画像を描画してみます。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib
  3. matplotlib.use('Qt5Agg')
  4. from PyQt5 import QtCore, QtWidgets
  5. from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
  6. from matplotlib.figure import Figure
  7. import matplotlib.image as mpimg
  8. class ApplicationWindow(QtWidgets.QMainWindow):
  9.     def __init__(self):
  10.         QtWidgets.QMainWindow.__init__(self)
  11.         self.main_widget = QtWidgets.QWidget(self)
  12.         l = QtWidgets.QVBoxLayout(self.main_widget)
  13.         
  14.         # --------------------------------------------
  15.         # FigureCanvasに表示するグラフ
  16.         fig = Figure()
  17.         # グラフを表示するFigureCanvasを作成
  18.         fc = FigureCanvas(fig)
  19.         # グラフの設定
  20.         fc.axes = fig.add_subplot(111)
  21.         fc.axes.plot([50, 350], [175, 175], 'r', lw=5)
  22.         # 背景画像設定
  23.         im = mpimg.imread("/home/baranche/lena.jpg")
  24.         fc.axes.imshow(im)
  25.         # 描画設定
  26.         fc.setParent(self.main_widget)
  27.         FigureCanvas.setSizePolicy(fc,
  28.                                  QtWidgets.QSizePolicy.Expanding,
  29.                                  QtWidgets.QSizePolicy.Expanding)
  30.         FigureCanvas.updateGeometry(fc)
  31.         # --------------------------------------------
  32.         # 作成したFigureCanvasを画面に追加
  33.         l.addWidget(fc)
  34.         # 中央に配置
  35.         self.setCentralWidget(self.main_widget)
  36. qApp = QtWidgets.QApplication([])
  37. aw = ApplicationWindow()
  38. aw.setWindowTitle("matplotlib sample")
  39. aw.show()
  40. qApp.exec_()



実行結果

959_02.png



動的に変化するグラフ



時間経過により変化するグラフを描画してみます。


  1. # -*- coding:utf-8 -*-
  2. import random
  3. import matplotlib
  4. matplotlib.use('Qt5Agg')
  5. from PyQt5 import QtCore, QtWidgets
  6. from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
  7. from matplotlib.figure import Figure
  8. import matplotlib.image as mpimg
  9. class ApplicationWindow(QtWidgets.QMainWindow):
  10.     def __init__(self):
  11.         QtWidgets.QMainWindow.__init__(self)
  12.         self.main_widget = QtWidgets.QWidget(self)
  13.         l = QtWidgets.QVBoxLayout(self.main_widget)
  14.         
  15.         # --------------------------------------------
  16.         # FigureCanvasに表示するグラフ
  17.         fig = Figure()
  18.         # グラフを表示するFigureCanvasを作成
  19.         self.fc = FigureCanvas(fig)
  20.         # グラフの設定
  21.         self.fc.axes = fig.add_subplot(111)
  22.         self.fc.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r')
  23.         # 描画設定
  24.         self.fc.setParent(self.main_widget)
  25.         FigureCanvas.setSizePolicy(self.fc,
  26.                                  QtWidgets.QSizePolicy.Expanding,
  27.                                  QtWidgets.QSizePolicy.Expanding)
  28.         FigureCanvas.updateGeometry(self.fc)
  29.         # --------------------------------------------
  30.         # タイマーを設定し、update_figureを定期的に呼び出す
  31.         timer = QtCore.QTimer(self)
  32.         timer.timeout.connect(self.update_figure)
  33.         timer.start(1000)
  34.         # 作成したFigureCanvasを画面に追加
  35.         l.addWidget(self.fc)
  36.         # 中央に配置
  37.         self.setCentralWidget(self.main_widget)
  38.     def update_figure(self):
  39.         l = [random.randint(0, 10) for i in range(4)]
  40.         self.fc.axes.cla()
  41.         self.fc.axes.plot([0, 1, 2, 3], l, 'r')
  42.         self.fc.draw()
  43. qApp = QtWidgets.QApplication([])
  44. aw = ApplicationWindow()
  45. aw.setWindowTitle("matplotlib sample")
  46. aw.show()
  47. qApp.exec_()



動いてくれました。

959_03.gif



【参考URL】

user_interfaces example code: embedding_in_qt5.py

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2019/02/24(日) 21:26:01|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

matplotlib 5 背景画像を表示し、プロット結果も表示する(matplotlib.image, Pillow, OpenCV2)

matplotlibのグラフの背景に画像を表示する方法です。
matplotlib.image、Pillow, OpenCV2を使用する方法があります。

matplotlib.image



matplotlibパッケージ単体で処理が完結するので、一番お手軽な方法だと思います。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. import matplotlib.image as mpimg
  4. # 画像の読み込み
  5. img = mpimg.imread('lena.jpg')
  6. # 画像の表示
  7. plt.imshow(img)
  8. plt.show()



実行結果

958_01.png


Pillow



画像処理ライブラリのPillowを使用した例。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. from PIL import Image
  4. # 画像の読み込み
  5. img = Image.open('lena.jpg')
  6. # 画像の表示
  7. plt.imshow(img)
  8. plt.show()



実行結果はmatplotlib.imageを使用した場合と同じです。



OpenCV2



OpenCVのimreadを利用する例。
GBR形式で読み込まれるので、RGB形式へ変換してやります。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. import cv2
  4. # 画像の読み込み
  5. img_bgr = cv2.imread('lena.jpg')
  6. img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
  7. # 画像の表示
  8. plt.imshow(img)
  9. plt.show()



これも実行結果はmatplotlib.imageを使用した場合と同じです。



グラフの描画



線や点をプロットしてみます。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. import matplotlib.image as mpimg
  4. # 画像の読み込み
  5. img = mpimg.imread('lena.jpg')
  6. # 画像の表示
  7. plt.imshow(img)
  8. # グラフの描画
  9. plt.plot([50, 350], [175, 175], 'r', lw=5)
  10. plt.plot([50, 350], [200, 200], 'b--', lw=5 )
  11. plt.plot(100, 150, 'ro')
  12. plt.show()



実行結果

958_02.png


【参考URL】

Image tutorial
Matplotlibで画像の表示
openCVで読み込んだ画像をmatplotlibで表示する方法

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2019/02/24(日) 19:43:22|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Python matplotlibで3Dデータを可視化(散布図プロットと3次元座標での指定)

こちらでROS版のORB SLAM2を動かしてみました。
ROS orb_slam2_rosによる車載カメラ動画の解析

検出結果は3次元で得られるようです。
簡単に可視化するには、matplotlibが便利そうなので試してみます。

こんなグラフが簡単に描画できる模様。
mplot3d tutorial


インストール



今回、Ubuntu 18.04 + Python2で動作させます。
matplotlib本体、pipでも良いのですが、aptでインストールしてみました。


$ sudo apt install python-matplotlib





簡単なサンプル



こちらを参考にさせていただきました。
【matplotlib】Pythonでデータを可視化する(3D散布図編)

サンプルは以下のとおり。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. fig = plt.figure()
  5. ax = fig.add_subplot(111, projection='3d')
  6. x = [1, 2, 3, 4, 5]
  7. y = [1, 2, 3, 4, 5]
  8. z = [1, 2, 3, 4, 5]
  9. ax.scatter(x, y, z)
  10. plt.show()



実行すると、あっけないぐらい簡単に3Dプロットが行えました。

957_01.png

マウスのドラッグで、ぐりぐり回転できます。



マーカーの色と形状



色は「c」、形状は「marker」キーワードで指定。


  1. # -*- coding:utf-8 -*-
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. fig = plt.figure()
  5. ax = fig.add_subplot(111, projection='3d')
  6. x = [1, 2, 3, 4, 5]
  7. y = [1, 2, 3, 4, 5]
  8. z = [1, 2, 3, 4, 5]
  9. ax.scatter(x, y, z, c='green', marker='X')
  10. plt.show()




実行結果

957_02.png


【参考URL】

mplot3d tutorial
【matplotlib】Pythonでデータを可視化する(3D散布図編)

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2019/02/24(日) 15:24:03|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

pipのエラー「from pip import main, ImportError: cannot import name main」

pipコマンドを実行するとエラーが発生。


Traceback (most recent call last):
File "/usr/bin/pip", line 9, in <module>
    from pip import main
ImportError: cannot import name main



aptでインストールしたpipをpip自身で更新すると壊れます。

手っ取り早く回復する方法は、aptでインストールしたpip以外を削除。


$ python -m pip uninstall pip

Uninstalling pip-19.0.2:
Would remove:
    /home/baranche/.local/bin/pip
    /home/baranche/.local/bin/pip2
    /home/baranche/.local/bin/pip2.7
    /home/baranche/.local/lib/python2.7/site-packages/pip-19.0.2.dist-info/*
    /home/baranche/.local/lib/python2.7/site-packages/pip/*
Proceed (y/n)? y
Successfully uninstalled pip-19.0.2




これでpipが使えるようになりました。


【参考URL】

【Ubuntu】pip install –upgrade pip コマンドを実行すると、その後、ImportError: cannot import name main というエラーが発生する場合の対応方法

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2019/02/14(木) 23:32:51|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ