Python Computation Time Mesurement Class(Pythonでプログラムの実行時間を測る方法)
Computation time measuring is important issue for most programmers.
Pythonで実行時間を測って可視化したい時があるかと思います。
Basis (原理)
Many functions exist for the time measurement.
以下に詳しくありますがtimeをimportすればOKです。
16.3. time — 時刻データへのアクセスと変換 — Python 3.6.3rc1 ドキュメント
I use time.time() to get current time.
There are some alternative such as time.clock() or something.
そのうち、time.time()で現在の時間を浮動小数点で得ることができるため、
start=time.time() # ここでなにかする end=time.time() dt=end-start # かかった時間
となります。
My class (作成したクラス)
いちいち宣言したり、過去の値を保存するのは管理が面倒で馬鹿らしいため、クラスとして実装しました。
import numpy as np import matplotlib.pyplot as plt import time # time.time() to get time class Checktime: def __init__(self): self.checktime = [0] self.difftime = [] self.start = time.time() def check(self,name=""): self.checktime.append(time.time()-self.start) self.difftime.append(self.checktime[-1]-self.checktime[-2]) print(name) print("Now time is "+str(self.checktime[-1])+" [s]") print("Computed in "+str(self.difftime[-1])+" [s]\n") def show(self): leng = len(self.checktime) plt.plot(np.arange(0,leng,1),np.array(self.checktime),label="Accumulation time") plt.plot(np.arange(1,leng,1),np.array(self.difftime),label="Each Process time") plt.legend() plt.grid() plt.show()
How to Use
使い方は簡単。
import
Just put this function on you source or save this program as "FILENAME.py" and write as follows.
from FILENAME import *
上のソースコードをまるっとコピーして自分のソースに貼るか、適当な名前で保存して上のようにImportできます。
Usage
プロセス名を入れることでどのプロセスにどれだけ時間がかかったかを可視化できます。
# init T = Checktime() # do something T.check() # print current time # or you can name your processing T.check("PROCESS NAME") # Finally you can see the time consumption graph T.show()
以下のような出力を得るでしょう。
results is like this:
Console output
Image Reading Now time is 0.00387120246887 [s] Differ from 0.00387120246887 [s] Get Histogram Now time is 0.00810813903809 [s] Differ from 0.00423693656921 [s] Get Mask Now time is 0.00903105735779 [s] Differ from 0.000922918319702 [s] Extract ORB Feature Now time is 0.0206370353699 [s] Differ from 0.0116059780121 [s]
出て来る図はこんな感じ。
Figure output
pyplotlibに関する覚書
python初心者にありがたいわかりやすい日本語記事がこちら。
bicycle1885.hatenablog.com
Python 配列の形式メモ
c++とPythonを行ったり来たりしていると頭が混乱してきます。
どれがどれ?
基本は以下の3つ。
- ()がtuple
- []がlist
- {}がdict
これらに加えてnumpyのarrayとmatrixがよく使う奴らでしょう。
とりあえず名前さえわかればGoogle先生に聞くことができるので
最低限どんなオブジェクトを対象にしているのか知っておきましょう。
以下にあまりわかり易くなかったTutorialも載せておきます
Lesson 6 - Tuples, Lists, and Dictionaries
各々の違い
- list :
- tuple :要素を変更できないlist
- dict :文字通り辞書。
Pythonのこれらの配列は型の異なる値を代入可能です。
すごいけどそのせいで時々エラーを見逃しちゃったり...
あと、Printした時のnumpyのarrayとlistの出力はとても似通っています。
listのlist的表現
よく出てくるのはこういうやつらです。[({の形からどのタイプのファイルか確認できます。
私は現状、Printした時に横に並ぶのがlistで縦に並ぶのがarrayと覚えています。
[[0. 0.],[1. 1.],[2. 2.]] #こっちがlistのlist [[0. 0.] [1. 1.] [2. 2.]] # np.array
初期化と要素へのアクセス
よく使う機能をまとめます。
- 長さを取得するlen()はtuple,list,dict全てに使えます。
list
[]でアクセスします。もちろん0から。
list = [2005, 2006, 2007, 2008] #初期化 list[0] #最初の要素へのアクセス
dict
数字が名前になっただけです。
dict = {"yamada":75, "endou":82} #初期化 value = dict["yamada"] #yamadaへのアクセス
2次元配列とかの対処
以下を見てください。なんてことないでしょう?
list = [10, [20, 16], [32, 34], 18] list[1] # [20, 16] が左から2番めの要素 list[1][0] # 20 が[20,16]の1番目の要素
各種変換
実際numpy arrayとの変換とかが一番使う気もします。
まぁおいおい追記しましょう。
tuple と list 相互変換
tuple(list) list(tuple)
numpy arrayとlist 相互変換
これはよく使うと思います。
a = [1, 2] np.asarray(a) # array b = np.array([1, 2]) b.tolist() # list
参考になりそうなサイト
練 習 問 題
Q1.以下の配列の構造を答えよ
a=[(2228.739013671875, 1203.9490966796875), (2898.794189453125, 1092.8704833984375), (3060.037353515625, 852.7973022460938)
Q2.上のaを以下のbへと変換するコードを書け
print(b) [[[[ 2228.73901367 1203.94909668] [ 2898.79418945 1092.8704834 ] [ 3060.03735352 852.79730225]]]]
Ans:
b=np.array([[a]])
使用例
OpenCVでcalcOpticalFlowPyrLK()関数へとKeyPointsに渡すときに使います。
Passing ORB Features to calcOpticalFlowPyrLK - OpenCV Q&A Forum
にゃーんAAジェネレータ
にゃーん。
にゃ?
ーーーーーーーーーーーー んん にんに ーー ーーーーーーーーーーーー に にゃににににに にににゃゃゃにに にににににににに ーーーーー ーーーーーーーーーーーー にーゃ ににゃににゃに ー にゃゃににに ににゃに にに に ーー ーーーーーーーーーーーー に にに にゃに ん ににゃゃに にゃにゃにに ーー ーーーーーーーーーーーー に ゃ ににににに に にににににゃにに ーー ーーーーーーーーーーーーー にゃに ににににに ににににに ゃ ーーー ーーーーーーーーーーーーーーー にゃ に ん に に ー ーーーーーーーーーーーーーー にに ゃゃゃゃ ゃゃゃに に ー ーーーーーーーーーーーーーーー に ん ゃゃゃに ゃゃゃ に ー ーーーーーーーーーーーーーーー ゃ ににんににに ん にゃゃゃゃに に ー ーーーーーーーーーーーーーーーーーーにににににに にににに ゃゃゃゃゃゃ に ー ーーーーーーーーーーーーーーー ゃ にゃゃゃんゃゃゃに にゃゃに に に ー ーーーーーーーーーーーーーーー ににに に に ー ー ーーーーーーーーーーーーーーー に に ゃゃゃゃに ん に ー ーーーー に ー ににに にににに に ー ーー にに に ーー に ににに ー ににゃゃに んん ん ににゃゃに ーー に ににににゃににに に ににゃゃゃににににんににににゃゃゃにに にに ににににに にに に に にゃゃにににににゃゃ に にに ゃに に に ゃ にゃゃゃににんににーに に ーーー に ゃ にーに にゃ ににゃに ににゃに ーに ーーーーーー に に ゃ にゃ にににに ゃに ゃ ーーーーーーーー ゃ ゃ に にゃに にゃに にゃ ーーーーーーーーーー に に に にゃに ん にゃゃにににににににににゃにゃーー ーーーーーーーーー に に に ににゃににににににゃにに ん ゃ ー ーーーーーーーーー ゃ に ゃ にに ー に ー ーーーーーーーーーー に にゃ ーーーーーーーー に ー ーーーーーーーーーー にに にににに ーーーーーーーーーーーーーーーーー に ー ーーーーーーーーーーー にゃに ーーーーーーーーーーーーーー に ー ーーーーーーーーーーーーー にー ーー ににゃに ーー ーーーーーーーーーーーーーーーー ー に ー に ん ににににゃゃに に ーー ーーーーーーーーーーーーーーーーー ー ー にに んんんん ゃに ーーー ーー ーーーーーーーーーーーーーーーーー に ー に にに に ーーー ーーーーーーーーーーーーーーーーー に にに ーーー にに に ーーー
にゃ
にゃーん
ArduinoのPID制御ライブラリはどれがいいか
本来なら車輪の再発明はなるべく避けるべきと言いたいところですが
Arduinoのライブラリはちょっと挙動が特殊だったりするので自分で書いたほうが安全のような気もします.
見解まとめ
少なくとも公式のPIDライブラリはデフォルトの設定を一度見直して使うべきです。
アンチワインドアップがないのでI制御のゲインはなるべく落とすなど,ちょっとしたチューニングをいじる必要がありそうです.
発展的な事をしたい場合やリアルタイム性が気になる場合は「自分で書こう」
というのが結論。
公式のPIDライブラリ
公式のページをどうぞ。
Classできちんと書かれており、見た目すっきりとした感じで書くことができます。
Arduino Playground - PIDLibrary
以下日本語で解説してくれている人もいますね。
ArduinoのPIDライブラリ - カラクリの館
中身について
Arduino-PID-Library/PID_v1.cpp at master · br3ttb/Arduino-PID-Library · GitHub
Compute関数の中をみると、まず前回との時間差分をとってサンプリング時間を超えているかどうか調べて,PIDゲインを更新。
うーん,,,うーん,,,,
追記:一周回ってまずまずなんじゃないかと思ってきました。
毎時更新されるわけじゃないので以下のようにif文を使ったほうが安全です。
if(myPID.Compute()){//値が更新されたならTrueが帰る // 出力値の更新をここに書く }
計算自体は特に離散化するでもなく,連続系のままPID制御をしています。(安全っちゃ安全)
「初心者が比較的安全に動かせる」「ゲインをハンドチューニングする」ことを念頭において作られているようです.
不満
- 一定周期で関数を実行してくれない。
- サンプリング時間のデフォルトが200ms(遅すぎ)
- デフォルトで負値の信号を生成しない(Limitがかけられている)
- 出力制限はかけているのにアンチワインドアップが組み込まれていない。
デフォルトの設定が悪すぎるのが一番の問題。
モータ制御とかをしたいと思ったら200msの制御周期とワインドアップ,負値の出力不可の三連コンボでまず振動・発散します。
泣く泣くI制御を切る初心者の顔が浮かぶ(´・ω・`)
ArduPIDライブラリ
Gitに個人の作ったライブラリがあります。
GitHub - Tellicious/ArduPID-Library: A PID Library for Arduino digitalized with the Tustin's method with Anti-Windup
良いところ
- きちんとTustin変換で離散化した制御器(離散化による不安定化とかいう負の側面もあるけど)
- AntiWindupを2種類搭載
この上の2つだけで公式ライブラリより推したいところです。
プログラムの使い勝手としてはまぁまぁでしょうか。
サンプル時間をきちんと管理していない場合,AutoCompute()機能を使わないと少々変な挙動になったりするので要注意です。
あと,疑似微分の時定数もちゃんといじれたりと制御屋が作ったんだなぁと感じさせるライブラリ。
不満
- 依然厳密なサンプル時間で実行しているわけではない。
- 私のコードにバグが残っている所(このライブラリは多分悪くない)
- これが公式ではないという点(一番の問題点)
結論・再び
あまり良いものがないのできちんとしたものを書けば多方面から感謝されること請け合い。
(つべこべ言わずに自分で書いてはどうだろうか。)
余談:タイマ割り込みとシリアル通信の相性の悪さ
タイマ割り込みを実装しようとすると一部関数やピンが使えなくなるようです。
arduino使い方:タイマー割り込み(MsTimer2)
もっと問題なのはシリアル通信などを阻害するというケースがある点で,ROSのSubscriberとかと共存させるのにちょっと手の込んだ事をする必要がありそうですね。
Enabling timer overflow interrupt breaks rosserial - ROS Answers: Open Source Q&A Forum
arduino rosserial with interrupt - ROS Answers: Open Source Q&A Forum
解決法はもう少し暇で余裕のあるときに探します。
Arduino&MATLABでサーボモータ(とか)を制御する
ArduinoとMATLABを連携すると要はコンパイルなしにいろいろデバッグができて作業効率が良いということです。
Pythonでもできそうなもんだけど誰か代わりに調べてください。
この30分のビデオ見ればここにあることは全部わかります。
Using Arduino with MATLAB and Simulink - Video - MATLAB
パッケージのインストール
matlab2014以降から対応です。
Support Package InstallerからArduinoに関する追加のパッケージをインストールします。
Home画面のAdd-onから探せるそうですが
matlabコンソールから試しに
a = arduino();
とか入力してみて出たエラーからも簡単に飛ぶことが出来ます。
あとはひたすらポチポチするだけです。大体15分弱かかります。
Arduinoとの接続と試運転
Control Servo Motors - MATLAB & Simulink Example
を参考に進めていきます。
接続
ホーム画面から「コンピュータの管理」というのを探し当ててそこからデバイスマネージャーのポートという所を探してください。
こんな感じ。
ここから得た情報を元に次のように入力してみます。
2つ目の変数はボードの種類なのでunoを使っている人はunoを入れてください。
a = arduino('com4', 'Mega2560', 'Libraries', 'Servo');
サーボモータの制御
サーボモータのピンを調べます。私のはモータシールドの「OUT5」につながっているので以下のドキュメントからD5とわかります。
Arduino Motor Shield Rev3
s = servo(a, 'D5') s = Servo のプロパティ: Pins: D5 MinPulseDuration: 5.44e-04 (s) MaxPulseDuration: 2.40e-03 (s)
実際に遊んだ時のコードです。writePosition(s, angle);とcurrent_pos = readPosition(s);のようにして
位置の読み書きをします。
注意として0~180°が0~1に置き換わっているので180で割ったりしてください。
%% write value Base_angle = 90; Min_angle = -30; Max_angle = 30; for angle = Min_angle:10:Max_angle Wangle = (angle+Base_angle)/180; writePosition(s, Wangle); current_pos = readPosition(s); current_pos = current_pos*180; fprintf('Current motor position is %d degrees\n', current_pos); pause(1); end Wangle = (Base_angle)/180; writePosition(s, Wangle);
他のmethodの確認
methods(a)
とうつことで使用できる関数を確認できます。
私のはこんなのでした。最新バージョンではボタン等のUIも書けるようです。とビデオにはあったんですがね。
addon configurePin display readDigitalPin servo writePWMDutyCycle configureAnalogPin details i2cdev readVoltage spidev writePWMVoltage configureDigitalPin disp playTone scanI2CBus writeDigitalPin
連続的に制御するには?
時間を取得するticとtocというコマンドを使ってwhileループぶん回すことで擬似的にそれっぽい制御をすることが可能になります。
あとはdelayを適宜入れれば遅い周期の動作は可能です。
DCモータの制御
本当はシステム同定をしたかったのですが手持ちの環境ではちょっと難し目です。あとで別に書きます。
特定の部品を使っている場合は簡単
Adafruit社のモーターシールドV2を使っている場合はとても簡単にDCモータを制御可能です。
裏を返すとそうでないと割りと面倒という...
Control Motors Using Adafruit Motor Shield V2 - MATLAB & Simulink Example
安いので楽をしたい人は買ってどうぞ。
Adafruit Motor/Stepper/Servo Shield for Arduino v2 Kit [v2.3] ID: 1438 - $19.95 : Adafruit Industries, Unique & fun DIY electronics and kits
私は持ってなくて悔しいのでこれについては書きません(公式のドキュメントが十分わかりやすい為でもある)
Neural Network Console by Sony のセットアップと動かしかた
2017年8月にSonyが機械学習用のGUIコンソールを発表して話題になりましたね。
手が早い人はもう記事を書いているようですが、晩御飯食べてる間に試してみたので記しておきます。
Neural Network ConsoleでNVIDIAGPUの動作確認まで - Qiita
ダウンロードとセットアップ
以下のサイトからダウンロード、解凍しておしまい。
Neural Network Console
というわけにも行かず、Visual C++の再領付パッケージを入れる必要があるようです。
Download Microsoft Visual C++ 2015 再頒布可能パッケージ Update 3 RC from Official Microsoft Download Center
これもダウンロードしてポチポチしておしまい。
チュートリアル1:ロジスティック回帰による手書き文字認識
チュートリアルは手書き数字が4か9か判別する一層のニューラルネットワークモデルですね。
右上のTrainingという所で再生マークをクリックすると学習が始まります。
流石に早い。
その後Evaluateの下の再生マークから実行すると評価を始めます。
それぞれの入力に対する実際の出力の値、
タブを変えると学習の正答率を表す表が出てきます。
うんうん。なるほど。
所感、感想
Web上では敷居が低く、文系にも使いやすい等いろいろ書いてありましたが
「Pythonを覚えなくてもいい」というのが一番の進歩でしょうか。
このコンソールで出てくるネットワーク構造をきちんと理解し、正しい使い方を自力で収集できる人は、
数ヶ月プラスすればPythonだって普通に使いこなしそうな気がするので
「とても便利」だけど「革命的」とまでは行かないと思われます。
これからこういう風に、学習法や幾つかのネットワーク構造が徐々に確立されつつある中で、
データセットや適切な問題設定の重要性が爆上がりしていくんですかね。
データ収集には結局プログラム書かないといけないのでプログラミングフリーの機械学習はまだまだ先でしょうか。
jupyter notebookをmatlabで使う / Google Driveにnotebookを保存
ポ○ットモンスター 金/銀 みたいなタイトルですが、iPythonのセットアップについてです。
難易度はそこそこある気がします。「なみのり」を覚えてから来てください。
- 前提:Python環境
- jupyter notebookをmatlabで使う
- jupyter notebook を GoogleDrive上で扱う。
- Matlabが古いけど無理やりでもこの機能を試したい!
前提:Python環境
私の環境ではとりあえずWindowsでやるつもりでいます。
一連のパッケージ環境を整えるにはanacondaもしくはminicondaを使うのが良いでしょう。
あと、GitHubの一部コマンドが必要なので適当に調べて入れておきましょう。
例えばここを見るとか。
私家版 Git For Windowsのインストール手順 | OPC Diary
Anacondaを使う場合(簡単・ストレージを割りと食う)
Anacondaは一連のPython関連の便利パッケージを落としてくれるのでPythonに今後お世話になる気のある人はこちらを使いましょう。
デフォルトで2Gくらい容量持って行かれるので注意。
下の記事を参照。
ossyaritoori.hatenablog.com
画像関係に興味がある方はこちらの記事も踏んでおいたほうがいいですが、まぁ後からできるので無理にすることはないです。
ossyaritoori.hatenablog.com
Minicondaを使う(ストレージを沢山消費したくない人向け)
先ほどのAnacondaの機能絞った板がこちらです。
Miniconda — Conda
Pythonとcondaのパッケージ管理だけなので数百Mの容量で済むはず(試してない)
どのみちやることは同じです。
jupyter notebookをmatlabで使う
以下の参考サイトに準拠してすすめます。
Matlab-based IPython notebooks | Anne UraiGitHub - Calysto/matlab_kernel: Jupyter Kernel for Matlab
Install MATLAB Engine API for Python - MATLAB & Simulink
0.Python(仮想) 環境構築
MatlabのバージョンごとにPythonの対応するバージョンが違います。
現状2015a,bでPython2.7系とPython3.3,3.4
現状2017bではじめてPython3.5がサポートされます。
これは
「C:\Program Files\MATLAB\R20XXa\extern\engines\python」にあるsetup.pyというファイルを覗けばわかります。
バージョンとか何も考えずに次に行きたい!という方はAnacondaのダウンロードの際に2.7を選択すると良いです。
ただ,今後継続してPythonを使う人は3.X系のほうが良いかもしれないです(バージョンごとに微妙に文法が違う)
次に仮想環境の構築についてです。
私の2015bの場合はPython3.4までが対応ですのでAnacondaの現在の3.6と噛み合いません。
ということで仮想環境を立てます。
conda create -n matlab python=3.4
次に,デフォルトではipythonが入っていないので
activate matlab conda install jupyter notebook
とうちます。多分合ってると思うけどドチャクソ容量持って行かれますねこれ。
追跡したらAppdataの中を1Gくらい占拠していました。空き容量には余裕をもってください。
1.Matlab engineのインストール
anacondaから使いたい環境を選んでactivateしておいてください。(activateの単語に身に覚えのない人は気にせずanacondapromptを起動しましょう)
この際管理者権限でプログラムを実行したほうが良いです。
WindowsのHomeボタンで「AnacondaPrompt」とサーチして出てきたアイコンを右クリック&「管理者権限で実行」を選択しましょう。
以下を実行してください。2014以前のバージョンにはこのsetup.pyが含まれていません。中身書き換えて移せばなんとかなるんじゃね?なりませんでした。
cd "matlabroot\extern\engines\python" python setup.py install
matlabbootはmatlabがおいてあるPathです。
頑張って探してください。参考までに私のは以下のような感じです。(なおバージョンが古くてなかった模様)
C:\Program Files\MATLAB\R2007b\
上手くいったら2へとすすんでください。
エラーが出たら?
- Pythonのバージョン云々言われたら仮想環境の設定を確認してください。
きちんとactivate matlabってやって仮想環境入ってます?ダメなら先ほどの章を確認。
- その後厄介なのが管理者権限が無いことでおきるエラー
以下のようなエラーが出る事があると思います。
error: could not create 'build': アクセスが拒否されました。
Error Installing MATLAB engine API for Python - MATLAB Answers - MATLAB Central
ということでコマンドプロンプトを管理者権限で実行してください。
setup.pyがあるフォルダまで移動して,次のようにうちます。
"C:\Users\__USER__\AppData\Local\conda\conda\envs\matlab\python.exe" setup.py install
めっちゃ長いのはさっきの仮想環境のPythonのFullPathです。
__USER__には自分のユーザ名を入れてください。というか一度ちゃんと探すと良いでしょう。
- うまくいくとこんな感じ?
最後の行でエラーって出てなければ多分上手く行ってると思います。
なんだこれは戦後の教科書か。
2.必要パッケージのインストール
その後、自分の環境で以下のコマンドをうってください。
pip install matlab_kernel python -m matlab_kernel install
jupyter notebook を GoogleDrive上で扱う。
GitHubでソース管理するのもいいけどGoogleDriveにもおいておきたい!という方のために、拡張プラグインが開発されています。
github.com
日本語記事もこちらに。
jupyter-driveを使ってみる
インストール
これだけ。
git clone https://github.com/jupyter/jupyter-drive.git pip install -e jupyter-drive
起動
複数やり方はありますが、以下のように設定するのがおすすめ。
python -m jupyterdrive --mixed
下のような画面になりました。
localをクリックするとlocalのフォルダへ、gdriveを選択するとGoogleDriveへのアクセス許可を求められます。
Matlabが古いけど無理やりでもこの機能を試したい!
結論上手く行ってませんので諦めて新しいバージョンのmatlabに課金してください。
以上が「通常の手法」です。
matlabやpython,ipythonのバージョンが合わなかったりするととたんに闇のゲームへと突入します。
ちょっと調べただけでもうげぇとなるようなケースがちらほら。
anaconda3-4.2.0 (Python3.5.2) 環境で Jupyter Notebook 上で MATLAB R2017a API の使用ができないのはなぜですか? - MATLAB Answers - MATLAB Central
matlab live editorという逃げの1手
わりかし似たような事ができるものとしてLive editorというものがあるようですが...
www.mathworks.com
これで勘弁してくれないですかね。
さぁ、闇のゲームだ!
例えば強制的にengine以下のフォルダを持ってきてpythonスクリプトを修正して発動してしまうのはどうでしょう?
只今奮闘中...
追記:敗北しました。古いmatlabのバージョンでは騙せなさそう...
さらに追記:
setup.pyをいじってバージョン違いでもエラーを出さないように加工してもやはり最後に以下のようなエラーが出ます。
諦メロン
第二ラウンドだ!
Jupyter: Matlab Kernel Dies · Issue #22 · Calysto/matlab_kernel · GitHub
以下のコマンドを導入...
pip install metakernel pip install pymatbridge
追記:敗北しました。ていうかどこかしこを探しても無理って言ってますね。公式に楯突くのはやめておきましょう。