outlier

建築士、プログラミング、ライフハック、etc.

Octave使いがPython(Numpy)に乗り換えるときの注意

こんばんは。

 

東大松尾研で公開されているディープラーニング講座のテキストが無料で公開されています。やってみようと思いダウンロードしたものの、いきなりnumpyに苦しめられるということになるとは・・・

今さら感満載ですが、Octave使いがPythonに乗り換えるときにひっかかりやすい点を整理します。 

東大松尾研ディープラーニング講座の概要

ディープラーニングを基礎から学べる教材として無料で公開されています。使う言語はpythonで、各回がjupyter notebook形式の提供されています。(ただし、演習問題だけの公開で、講義は別。)

似たようなものとしてCouseraのMachine Learingの講座があります。こちらはビデオ講義が公開されていますが、すべて英語(日本語訳は一応ついていますが、ちょっと日本語が変だったりします)ですし、演習はOctaveを使っています。

 主なコマンドのOctave→Pythonへの変換

普段Octaveを使うことが多いので、Pythonとの違いでつまづくことがよくあります。ということで、両者の違いを整理してみます。

配列のインデックス

Octave : 1から

numpy : 0から

配列の作成

2行3列の行列X

X = [ 1  2  3 

         4  5  6] 

を作成する場合、

Octave : X=[ 1 , 2 , 3 ; 4 , 5 , 6 ]  

#コンマ(,)で列方向に区切り、セミコロン(;)で行方向に区切る

numpy : X=np.array( [ [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] ] )

#一つの列をカッコ[]で囲み、その中をコンマ(,)で区切る。

配列のサイズ取得

Octave : size(X)

numpy : X.shape

 

連番配列の作成

1から0.1刻みで10までの配列を作る場合、

Octave : x=(1:0.1:10); 

#カッコ内は(初期値:間隔:終了値)の順。間はコロン(:)

numpy : x=np.arange(1,10,0,1)     

# カッコ内は(初期値、終了値、間隔)の順。間はコンマ(,)

配列の転置

元の配列をXとして、それを転置した行列Yは、

Octave: Y=X'    # またはY=transpose(X)でも可(ふつう使わないが)

numpy : Y=X.T     

※Octaveの場合、1次元のベクトルは「n行1列」なのか「1行n列」なのかで区別されるので、n行1列のベクトルを転置すると1行n列のベクトルに変換される。

numpyの場合、1次元のベクトルは上記の操作で転置されないので、1次元ベクトルxもそれを転置したx.Tも同じとなる。

行列をベクトルに変換

行列W=[ 1 ,  2 , 3 ;

               4 , 5 , 6 ]

に対して、それを1次元のベクトルに変換したものvは、

Octave : v=W(:)    # または、v=reshape(W,1,size(W,1)*size(W,2) )

numpy : v=W.flatten()

※Octaveはcolumnメジャー、Matlabはrowメジャーのため、出力される1次元ベクトルはOctaveとMatlabで転置の関係になります。numpyはMatlabと同じrowメジャー。

配列の次元の変換

Octave : Y=reshape(X,n,m)

numpy : Y=X.reshape(n,m)

※これもcolumnメジャーかrowメジャーかに注意。

配列の一部を取り出し

行列W=[ 1,2,3 ; 4,5,6]に対して、

①1列目を取り出すベクトルu

Octave : u=W(:,1)

numpy : u=W(:,0)

②1行目を取り出すベクトルv

Octave : v=W(1,:)

numpy : v=W(0,:)

※numpyだとインデックスが0からなのに注意

 

条件式による配列へのアクセス

Octave: find(W==1)

numpy : np.where(W==1)

 

行列の積

Octave : C=A*B      # 行列の要素ごとの積の場合、ドット(.)を入れてC=A.*B

numpy : C=np.matmul(A,B)

※Octaveの場合、ベクトルも(nx1)または(1xn)の行列と認識されるので、ベクトルvと行列のAの積を考えるとき、行列積が定義できるように適宜ベクトルを転置(A*v')しないといけない。numpyは列ベクトルと行ベクトルに区別がないので、このような操作は不要となる。

テンソル積

おそらくnumpyを使う一番のメリットはこのテンソル積なのではないか。Octaveの場合、テンソル積を計算するにはforループを使わざるを得ないが*1、numpyならテンソル積を計算する関数が用意されている

テンソルA,Bに対して、その積Cは

C=np.tensordot(A,B)

numpyの強力ツール・アインシュタイン縮約規約einsum

一般のテンソル積和を扱うことができるeinsumはかなり強力。 というこほぼこれ一発で行列やテンソルの操作ができてしまう。

 

なかなか理解するのに苦労するが慣れれば簡単。こちらの記事にとてもよく整理されています。

www.procrasist.com

 

 

 

ということで、主に行列の操作についてOctaveとNumpyでの違いを整理をしました。ディープラーニング講座と言いながら、まだまだ本題までたどり着けません。コツコツ続けていきたいと思います。

 

 

*1:Matlabの場合、Tensor toolboxというものを使えば、簡単にテンソル積が計算できるようです