読者です 読者をやめる 読者になる 読者になる

真にコスパのいいGPUはどれか、TFLOPS換算で比較してみた(DeepLearning•機械学習用)[2017/03/14更新 gtx1080ti追加]

DeepLearning chainer

経緯

友人のPC購入のアドバイスをしていてふと「純粋にTFLOPSと価格だけで比較した場合、どのGPUが一番コスパがいいんだろう?」と疑問に思ったので簡単に調べてみた。
radeonはcuda使えないから論外。GTX900以下、TITAN等は一般的ではないため除外してある。

2017/03/13 gtx1080tiを追加し、価格・結果を更新。
結果は大して変わらず。
ただし、Resnet等のGPUメモリを大量消費するモデルがどんどん出てきていることを考えると、コスパが多少悪くなってもGTX1080ti程度のものが必須になってきているような気もする。

GPU/価格対比表

GPUの型番、TFLOPS、メモリ量、価格、最後に1TFLOPSあたりの単価としてまとめた。
見方はシンプル、円/TFLOPSが一番低いGPUが最高コスパGPUとなる。

GPU TFLOPS(FP32) メモリ 価格(2016/10/20価格コム最安) 円/TFLOPS
GTX1080ti 11.34TFLOPS 11GB 118,570円 10455
GTX1080 9TFLOPS 8GB 69793円 7754
GTX1070 6.5TFLOPS 8GB 44800円 6892
GTX1060 4.4TFLOPS 6GB 27983円 6359
GTX1060 4.0TFLOPS 3GB 22982円 5745
GTX1050Ti 2.1TFLOPS 4GB 16718円 7960
GTX1050 1.8TFLOPS 2GB 12790円 7105
GTX980Ti 5.63TFLOPS 6GB 44820円 7960
GTX980 4.61TFLOPS 4GB 27980円 6069
GTX970 3.49TFLOPS 4GB(実際は3.5GB) 29700円 8510
GTX960 2.3TFLOPS 2GB 18338円 7973
GTX950 1.57TFLOPS 2GB 15098円 9616
GTX750Ti 1.4TFLOPS 2GB 10665円 7617
TX1 0.512TFLOPS 2GB 93798円 183199
TK1 0.364TFLOPS 2GB 29160円 80109

結果(2017/03版)

結果は大して変わらず、GTX1060 3GBのコスパが際立つ結果になった。
しかし、発売からまもなく半年になろうとするのに、GTX1080,1070が大して値段が下がらないどころか値上がりしていたのには驚き。
今からGPUを買うに進めるなら、こんなイメージかな。

ちょっとDeepLearning試したい→GTX1060 3GB
お金がないけどある程度真剣にやりたい→GTX1070
研究に使いたい→GTX1080ti

結果(2016/10版)

感覚的にはGPX1070が一番コスパがいいと思っていたのだが、計算してみるとGTX1060 3GBのコスパが際立つ形になった。
次点でGTX1060 6GB、GTX980、GTX1070の順。GTX1070ユーザーとしては悔しい限り。
体感から、学習では最低でもメモリ4GB必要のため、これを鑑みると、GTX1060 6GBがDeepLearning用としては現状の最高コスパGPUだと考えられる。

また、2016/10/20時点ではGTX1050Ti等の市価が判明していないため、予想価格を記載してある。
GTX1050Tiが13353円以下にならないとGTX1060 6GBのコスパを抜けないが、GTX750Tiの価格を見てもそこまで下がることは考えにくい。
コスパという観点から見ると、当分の間GTX1060 6GBの優勢は揺らがないだろう。


(余談)
TX1のコスパの悪さが尋常じゃない。
TX1,TK1はGPUボードのみでなく評価用ボード、CPU等も付いているとはいえ、桁が2つ違うとは・・・・。

pythonのpickleでSystemError: error return without exception setが出る原因

chainer DeepLearning python

pythonで大きなデータをpickleで保存しようとすると、

SystemError: error return without exception set

と出て保存ができない。
調べてみると、どうやらpython2系のバグの模様、およそ1.9GB以上のデータを保存しようとするとエラーになる。
これを解決するにはpython3.3に上げるしかない。
他の依存関係があって2.7から動けない場合、解決策としては以下の通り。

  1. 保存データの分割
  2. numpy.save
  3. h5py
  4. pytables

新しいコマンドを覚えるのが面倒なので、結局分割して対応しました。

(2016/10/22追記)
joblibを使うことでもっと簡単に解決できることが判明。
t-nkb.hatenablog.com


(参考)
困った時はgithub or stackoverflowですね。

ndarray dump function (and straight cPickle) fails for large arrays (Trac #1803) · Issue #2396 · numpy/numpy · GitHub
ubuntu - cPickle:SystemError: error return without exception set - Stack Overflow

JetsonTK1、TX1にopenCV(cv2も)を導入する方法

DeepLearning python

JetsonTK1にOpenCVを導入するために、いつもどおりopenCVコンパイルしてみた・・・が、環境が特殊なため、うまく動作しない。

t-nkb.hatenablog.com


いろいろ探していくと、NvidiaがJetson用のOpenCVを用意してくれていた。
日本語ではこのあたりの情報があまりないため、メモがてら導入方法を残しておく。

openCV導入方法

apt-getのリポジトリを入れて、apt-get installするだけ!!

sudo apt-add-repository universe
sudo apt-get update
sudo dpkg -i libopencv4tegra-repo_l4t-r21_2.4.10.1_armhf.deb
sudo apt-get update
sudo apt-get install libopencv4tegra libopencv4tegra-dev
sudo apt-get install libopencv4tegra-python

導入に失敗した場合

上記導入をする前に、自分でOpenCVコンパイルして導入することを試みていると、実行してもうまく行かなくなることがある。
私の場合はpythonでcv2がうまくインポートできなかった。

そういう時は慌てず、以下で一旦cv2.soを消してやって

sudo find / -name cv2.so
sudo rm (上記で見つかったファイル)

再度libopencv4tegra-pythonをインストールし直すことで解決する。

sudo apt-get autoremove libopencv4tegra-python
sudo apt-get install libopencv4tegra-python

参考サイト

Jetsonの情報ならここが一番参考になる。
Jetson/Installing OpenCV - eLinux.org

sftp接続でサーバー上のフォルダをマウント(mac,ubuntu)

linux ubuntu

導入の経緯

以前、サーバー環境の構築で、SCPにてファイル転送を行うことにすると決めた。
それ以来、Filezillaを使ってサーバー上のファイルを見てきた。

t-nkb.hatenablog.com

t-nkb.hatenablog.com

しかし、pythonスクリプト等をいじり始めるとやはりマウントしてスムーズにファイルをいじりたくなる。
最初はsamba over sshといった形でポートフォワーディングを使用して問題を解決しようと考えたが、もっとシンプルにマウントする方法があったので、以下を実装した。

macの場合

osxfuse,sshfsのインストール

以下HPからosxfuseとsshfsの最新版をダウンロードし、インストールする。
HP右側に二つのアプリケーションの最新版がインストールできるリンクが貼ってあるはず。
osxfuseの方は、チェックできる項目は全てチェックしてインストールする。

Home - FUSE for macOS

sshfsの実行

以下コマンドを実行して、マウントする。
うまくいったら~/.bashrcにエイリアスを作成しておくと便利。

sshfs -p ポート番号 ユーザー名@ホスト名:接続先ディレクトリ名 マウント先ディレクトリ名

ubuntuの場合

ubuntuの場合はapt-getでsshfsを導入して実行するだけだから簡単。

sudo apt-get install sshfs
sshfs -p ポート番号 ユーザー名@ホスト名:接続先ディレクトリ名 マウント先ディレクトリ名

感想

と、いうことで実行は出来たが、テザリング環境で実行すると、ディレクトリ移動が遅くてストレスがたまる。
ただし、ファイルの編集等はいちいち転送を意識しなくとも自動でアップデートしてくれるので、非常に便利!!
使用する用途によってsftpとfilezillaを使い分けるといいかもしれない。

(追記)

通信が切れた際に自動でアンマウントするようエイリアスを追加。
t-nkb.hatenablog.com

フォルダ分けされた大量の学習画像を一括で読みこむ方法(python)

DeepLearning python linux

chainerのサンプルを一通り試して、いざ自分のデータセットを読み込ませよう!と思ったときにまずつまずくのがここ。
どうやって自分の画像データを読み込ませたらいいの??と最初悩んだので、まとめておく。

学習データのファイル構造

まずは、学習データを整理する。流れとしては以下の通り。

  1. ラベルとしてつけたい名前のフォルダを作成。これでラベルの数だけフォルダができる
  2. 各フォルダに画像ファイルを入れていく。今回の場合、拡張子は.png .jpg .jpeg
  3. 全てのフォルダを(プログラムの置いてあるパス)/data/フォルダに入れる

データの読み込み

以下の順番でファイル名、データを読み込んでいく

  1. dataディレクトリ内を読み込み、ラベル名のリスト(=ディレクトリ名のリスト)を手にいれる
  2. ディレクトリ名をlist.txtに記載
  3. ディレクトリ内部の画像ファイルを見つけて処理を行う

以下に抜粋したpythonスクリプトを記載する。エラー処理はしていないため注意。

import os

data_dir_path = u"./data/"
dir = os.listdir(r'./data/')
dir_list = sorted([x for x in tmp if os.path.isdir(data_dir_path+x)])
target = []
target_name = []
label_f = open('list.txt', 'w')

for dir_name in dir_list:
    label_f.write(str(dir_name) + "\n")
    file_list = os.listdir(data_dir_path+dir_name)
    for file_name in file_list:
        root, ext = os.path.splitext(file_name)
        if ext == u'.png':
            #以下各画像に対する処理を記載する
abel_f.close() 

SSHの接続が切れても継続して学習させる方法(screenを使った実行)

DeepLearning linux

sshでログインしてそのまま学習を実行してしまうと、sshのリンクを切ることができず、ノートパソコンを閉じることができなくなってしまう。
学習途中で通信が切れて、これまでの結果が全部消える、なんてことに・・・・。

そこで、基本的にはscreenを使ってセッションを貼り、screen上で学習を実行させる。
こうすると、sshが切れてもscreen上でプログラムが走り続けてくれる。
学習経過を携帯等で確認することもできて、非常に便利!!

screenの導入

apt-getで導入するだけ。認証されていないソフトですが・・・等のエラーが出ても気にせず導入。

$ sudo apt-get install screen

実行方法

screenを実行し、screen上でプログラムを起動する。
一旦screenから出てしまえば、sshが切れても問題ない。
screenから出る前にsshの接続を切ると、プログラムが終了されるため注意。

$ screen
screen上のターミナル画面に切り替わるため、プログラムを実行
ctrl a+dでscreenから出る。

確認方法

screen -lsで起動中のscreenを確認。
screen -r ***(lsによって出た番号)でscreen画面に戻る。
終了はscreen上でexitと入力。

(追記)

screen中にマウスホイール等を使用できるように設定ファイルを変更。
t-nkb.hatenablog.com

pythonでlistをファイルに保存し、読み込む方法

DeepLearning python

listを一時的にファイルに保存し、読み出したいことが良くある。
いつもちょっと考えるので、まとめておく。

pythonだったらpickle使う方が一般的なのかも知れないけれど…。

listの書き出し

listを要素ごとに改行して書き出し。

f = open('list.txt', 'w')
for x in list:
    f.write(str(list) + "\n")
f.close()

listの読み出し

各行ごとに読みだして、listに戻す。
appendを使っているあたり、pythonらしくないコードのような気がするけど、とりあえずこれでも動く。

f = open("./list.txt","r")
list = []

for x in f:
    list.append(list.rstrip("\n"))
    #以下のようにしてしまうと、改行コードがlistに入ってしまうため注意
    #list.append(list)
f.close()