- 投稿日:2019-07-14T18:34:00+09:00
TensorFlow,PyTorchの比較
TensorFlow,PyTorchの比較
普段はTensorFlowを用いて機械学習、Deep Learningの勉強をしているのですが、今回は現在流行っているPyTorchを用いてプログラムの作成を行ったのでTensorFlowとPyTorchの比較を行ってみました。
TensorFlowとは?
TensorFlowとはGoogle社が2017年にリリースしたオープンソースの機械学習用ライブラリです。
PyTorchとは?
PyTorchはfacebook社の人工知能研究グループが開発したオープンソースの機械学習用ライブラリです。
今回使用したPCのスペック
今回プログラムを動かす際に使用したPCのスペックは以下の通りです。
・Mac book pro2017
・Mac OS Mojave
・プロセッサ 2.3 GHz Intel Core i5
・メモリ 8GB学習データ
今回は一次元のデータを用いて識別を行うデータで検証を行った。また、今回は2000回学習を行なった。
TensorFlowでの結果
TensorFlowを用いた場合の結果は以下のようになった。
正解率は70%程度であり、学習時間は354秒程度となった。
PyTorchでの結果
PyTorchを用いた場合の結果は以下のようになった。
正解率は70%程度であり、学習時間は3.5秒程度となった。
使用してみた感想
TensorFlow,PyTorch共に結果としては正解率が70%程度であまり精度に違いはなかった。
しかし、学習にかかった時間はTensorFlowに比べPyTorchは100倍も早い結果となった。
使用した感覚としてはPyTorchは初期値に依存する傾向が強いように感じた。
TensorFlowは学習している最中にメモリが溜まるため学習が進むにつれて1回学習するのにかかる時間が長くなる。最後に
今回はあくまでもノートパソコンで計算を回した結果であり、GPUやTPUを用いて計算を行えば結果は変わるかもしれません。
今後TPUを用いて計算を回す予定があるのでその時にもう一度比較を行いたいと考えています。
- 投稿日:2019-07-14T13:34:55+09:00
tensorflowをAzure App Service上で動かしてみる
いよいよtensorflowの画像認識をAzure App Serviceで動かす事にトライしました。
demo
※タイムアウトした場合もう一度画面更新してみて下さい。(FREE版なので都度起動しているので重たいようです。)
手順
もはや定型処理になりつつありますが、python拡張モジュールを入れて、ライブラリを追加します。
1.Google Colaboratoryだとtensorflowはライブラリとして用意されているので、今回はそちらを利用しました。こちらの記事を参考にcifar10h5の画像識別モデルを作成しました。これを一旦ローカルにダウンロードしてからAzure App Serviceにftpでアップロードして利用します。
2.AzureのWebappsはPythonサーバを作成。
3.webappsダッシュボードの「開発ツール」→「拡張機能」→「追加」でPython 3.6.4 x64を追加。
4.webappsダッシュボードの「高度なツール」→「移動」→「Debugconsole」→「CMD」→「フォルダ選択ができるのでPython364x64」を選んで、コンソール画面でライブラリを追加。
python -m pip install --upgrade pip pip install Flask pip install tensorflow pip install Pillow5.ファイル転送とjpegファイルをtensorflowが処理できる形式に変更する処理を加えてWebAppsアプリを作成します。
ソース
tensorUpload.html{% extends "base.html" %} {% block body %} <form action="/upload" method="post" enctype="multipart/form-data"> <h2>アップロード</h2> <table> <tr> <td><input type="file" name="uploadFile"/></td> </tr> <tr> <td><img src="{{ url_for('static', filename=file_url) }}"></td> <td>result = {{ result }}</td> <td><input type="submit" value="submit"/></td> </tr> </table> </form> {% endblock %}main.py# -*- coding: utf-8 -*- from common import * import tensorflow as tf application = Flask(__name__) application.config.from_object(__name__) ################################################################## # 初期メニュー ################################################################## @application.route('/') def index(): return render_template('index.html') #各画面からの戻りの時はこちら(/でうまく戻れないので) ※indexとIndexをわざと変えている @application.route('/Index',methods=['POST']) def Index(): return render_template('index.html') #************************************** # アップロード #************************************** #アップロード画面初期表示 @application.route('/tensorUpload',methods=['POST']) def tensorUpload(): return render_template('Upload.html') #*********************************************************************************** # アップロードデータ作成 https://qiita.com/5zm/items/ac8c9d1d74d012e682b4 #*********************************************************************************** UPLOAD_DIR = "./static/result/" label_names = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"] @application.route('/upload', methods=['POST']) def upload(): #アップロードファイルの読込 if 'uploadFile' not in request.files: return render_template('Upload.html', file_url='', result = 'uploadFile is required') file = request.files['uploadFile'] fileName = file.filename if '' == fileName: return render_template('Upload.html', file_url='', result = 'uploadFile is required') #アップロードファイルを保存 try: #saveFileName = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_") + fileName saveFileName = fileName os_saveFileName = os.path.join(UPLOAD_DIR, saveFileName) file.save(os_saveFileName) file_url = "result/" + saveFileName except: return render_template('Upload.html', file_url='', result = 'save error') try: #モデルの読込 model_loaded=tf.keras.models.load_model("./static/cifar10.h5") #画像の読込とtensorflowが処理できるように変換 img_path = os_saveFileName img = tf.keras.preprocessing.image.load_img(img_path, target_size=(32, 32)) x = tf.keras.preprocessing.image.array_to_img(img) x = np.expand_dims(x, axis=0) except: return render_template('Upload.html', file_url=file_url, result = 'model_load error') #アップロードファイルを識別 try: pred = model_loaded.predict_classes(x) result = label_names[pred[0]] except: return render_template('Upload.html', file_url='', result = 'pred error') return render_template('Upload.html', file_url=file_url, status='ok',result = result) #リクエストエンティティが大きすぎます @application.errorhandler(werkzeug.exceptions.RequestEntityTooLarge) def handle_over_max_file_size(error): print("werkzeug.exceptions.RequestEntityTooLarge") return 'result : file size is overed.' #************************************** # サーバ起動 マルチスレッド指定 デフォルトはTrueの動きをするようだが。 https://qiita.com/5zm/items/251be97d2800bf67b1c6 #************************************** if __name__ == '__main__': application.debug = True # デバッグ application.run(host='0.0.0.0', port=8000, threaded=True)その他【index.html】 {% extends "base.html" %} {% block body %} <div class="container"> <table class="table table-striped table-condensed"> <thead> <tr> <th>NO</th> <th>プログラム名</th> <th>リンク</th> <th>備考</th> </tr> </thead> <tbody> <tr> <th scope="row">1</th> <td>tensorflow画像識別</td> <td> <form action="{{ url_for('tensorUpload') }}" style="display: inline" method="post"> <button type="submit" class="btn btn-default" style="width: 120px; padding: 5px;">Upload</button> </form> </td> <td></td> </tr> </tbody> </table> </div> ---------------------------------------------------------- 【index.html】 {% endblock %} <!doctype html> <!--***************************************************************** * 共通のhtml * jsの読み込み、cssの読み込み、共通のヘダーの表示(メニューの戻りボタン、ログオフボタン付き) * 2018/10/03 佐藤(敏) *****************************************************************--> <head> <meta charset="utf-8"> <title>プロト</title> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/3.5.3/js/tabulator.min.js"></script> <script src="{{url_for('static', filename='xlsx.full.min.js')}}"></script> <!-- cdn設定だとsheetJSが動かない--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://oss.sheetjs.com/assets/vendor/samples.css"> <link rel="stylesheet" href="https://oss.sheetjs.com/assets/css/sheetjs.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/3.5.3/css/tabulator.min.css"> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css"> <style> html {overflow-y:scroll ;} body {zoom:80% ;} *,h1,h2,h3 {font-family:Times New Roman,Meiryo;font-style:italic} /*ダイアログ作成用*/ .dialog { width: 300px; margin: auto; position : absolute; top: 300px; left:500px; padding: 30px 20px; background-color:white; display: none; text-align: center; border: 1px solid #aaa; box-shadow: 2px 2px 4px #888; } </style> </head> <body> <div class="container"> <header> <!--ナビゲーションメニュー(Navbar) --> <div class="navbar navbar-dark" style="height:50px; background-color:black; "> <div class="navbar-brand d-flex align-items-center"> <strong>Flask(Powerd By Python+Flask+tensorflow)</strong> <form action="{{ url_for('Index') }}"style="display: inline" method="post"> <button type="submit" class="btn btn-default btn-sm" style="width:80px; position:relative;left:100px ">menu</button> </form> </div> </div> </header> </div> {% block body %} {% endblock %} </body> </html>web.config、base.html、common.pyは前記事と同じです。
入力は適当なjpegファイルを選んでアップするとそれなりに判別してくれます。
だいぶ機械学習らしいアプリになってきました。
- 投稿日:2019-07-14T00:09:46+09:00
TensorFlow (abseil-py)によるlogging汚染を回避する
概要
Pythonで
import tensorflow
すると、logging
のロガーの出力が消える。この問題はTensorFlow 1.14.0以降に存在するらしい。
(筆者は1.14.0で確認)原因は、TensorFlowが内部で利用しているabseil-pyがルートロガーのハンドラを書き換えるため。
- TensorFlowのissue: https://github.com/tensorflow/tensorflow/issues/26691
- abseil-pyのissue: https://github.com/abseil/abseil-py/issues/99
問題の再現
import logging import tensorflow as tf logger = logging.getLogger(__name__) def main(): logger.info('some log') if __name__ == "__main__": logging.basicConfig(level=logging.INFO) main()$ python tf_log.py何も表示されない
修正
ルートロガーからabseil-pyによってセットされたハンドラを削除する。
abseil-pyはwarning以上のレベルのログをstderrに出すようにする機能も勝手にONにするらしいので、それもついでにOFFにする。
このコードは
https://github.com/tensorflow/tensorflow/issues/26691#issuecomment-500369493
より。import logging import tensorflow as tf try: import absl.logging # https://github.com/abseil/abseil-py/issues/99 logging.getLogger().removeHandler(absl.logging._absl_handler) # https://github.com/abseil/abseil-py/issues/102 absl.logging._warn_preinit_stderr = False except ImportError: pass logger = logging.getLogger(__name__) def main(): logger.info('some log') if __name__ == "__main__": logging.basicConfig(level=logging.INFO) main()$ python tf_log.py INFO:__main__:some logログが出るようになった
- 投稿日:2019-07-14T00:09:46+09:00
Google系ライブラリ(TensorFlowやGoogle Cloudなど)のabseil-pyによるlogging汚染を回避する
概要
Pythonで
import tensorflow
すると、logging
のロガーの出力が消える。
この問題はTensorFlow 1.14.0以降に存在するらしい。
(筆者は1.14.0で確認)また、TensorFlowの他にも、Google Cloud Client Library (
import google.cloud
)などでも発生するらしい。原因は、これらのライブラリが内部で利用しているabseil-pyがルートロガーのハンドラを書き換えるため。
- TensorFlowのissue: https://github.com/tensorflow/tensorflow/issues/26691
- abseil-pyのissue: https://github.com/abseil/abseil-py/issues/99
abseil-pyはGoogle内で標準的に使われているライブラリらしく、Google系のライブラリだと内部でこれを使っているっぽい。
問題の再現
import logging import tensorflow as tf logger = logging.getLogger(__name__) def main(): logger.info('some log') if __name__ == "__main__": logging.basicConfig(level=logging.INFO) main()$ python tf_log.py何も表示されない
修正
ルートロガーからabseil-pyによってセットされたハンドラを削除する。
abseil-pyはwarning以上のレベルのログをstderrに出すようにする機能も勝手にONにするらしいので、それもついでにOFFにする。
このコードは
https://github.com/tensorflow/tensorflow/issues/26691#issuecomment-500369493
より。import logging import tensorflow as tf try: import absl.logging # https://github.com/abseil/abseil-py/issues/99 logging.getLogger().removeHandler(absl.logging._absl_handler) # https://github.com/abseil/abseil-py/issues/102 absl.logging._warn_preinit_stderr = False except ImportError: pass logger = logging.getLogger(__name__) def main(): logger.info('some log') if __name__ == "__main__": logging.basicConfig(level=logging.INFO) main()$ python tf_log.py INFO:__main__:some logログが出るようになった