3次元配列の要素足しあわせとか numpy
忘れそうなのでメモ
3次元配列の足し合わせ
画像を局所領域ごとにA,B,Cの3クラス分類し、それぞれの確率をndarrayに格納する。(m,n,3)という形になる。
m * n個の各確率をそれぞれのクラスについて平均をとりたいとき、足し合わせる方法は以下のようにする。
# probに(m,n,3)のndarrayが入っているものとする prob_sum = sum(sum(prob))
numpy.sum()
でaxisを指定してやる必要があると思ったが、python標準のsum()
でもできた。
あとはm * n で割ればよい。
prob_ave = prob_sum / (prob.shape[0] * prob.shape[1])
配列の最大値のindexを取得
[(Aの確率), (Bの確率), (Cの確率)]みたいなndarrayがあったときに、それらの最大値のindexを取得する。
ndarrayについてはpython標準のmax()
は使えなかったので、numpy.max()
を使う。
# probが各クラスの確率が入ったndarrayとする index = numpy.where(prob==numpy.max(prob)) index = index[0]
numpy.where
で最大値のindexを取り出すわけだが、これの戻り値はndarrayで返される。
欲しいのはint型のindexの値なので、二行目でこれを取り出すわけである。
もっとうまいやり方があるような気もするけど・・・
(追記)
こうすれば一発で出来た。
index = np.argmax(prob)
axis
を指定しない時は、flattenされた時のindexを返すっぽい。
axis=0
とすれば行(縦)で見た時の最大値、axis=1
なら列(横)で見た時の最大値のindexをndarrayで返す。
なかなかnumpyの使い方覚えられなくてげんなりする今日この頃
【曲紹介とかしてみる】Take Me There
気づけば11月ももうすぐ終わりそうですね。早いものです。
やらなければならないことは山積みですが、とりあえず息抜きにjazzでも聴いときますか。
今回はピアニストの曲。Bob Jamesの「Take Me There」です。
Bob James - Take Me There - YouTube
いわゆるsmooth jazzとかゆーやつです。スタンダードなjazzよりはキャッチーで聴きやすい印象があります。こういうのこそ作業中のBGMには向いているかもしれません。
ピアノは当然のことながら、エレピの電子音がすごくオサレでかっこいいです。
Bob James(1939-)はjazz, fusion系のピアニストとして活躍されています。Fourplayというfusion/smooth jazz バンドでピアノを担当しておられます。というかむしろそっちのほうが有名だと思う。
4歳でピアノを始めて、ミシガン大学を修士までやってからバークリー音楽大学へ転入したそうな。もうなんか世界的ミュージシャンのテンプレですね。。
映画音楽とかクラシックとかにも積極的に取り組んでいるそうです。
はい、完全にwikipediaのコピペです
もっと詳しく知りたい方は自分でググったほうがためになります。。
この曲は、ソロ名義で出された「Joy Ride」というアルバムに収録されています。
このアルバムは他にも良曲揃いなので、ぜひ聴いてみることをお勧めいたします。
実は全曲Youtubeにあがってるんですが...こっそり聴いてみて、気に入ったら買いましょう(笑)
64bit windows8.1 に Theano, Pylearn2をインストール(GPU使用, Anaconda)
普段は研究室のPC(Ubuntu14.04 LTS, GTX780)を使っているが、どうにも学習に時間がかかるので、自分のPCでも軽く実験とかできたらなーと思った次第。今更すぎるが64bitのwindowsにTheanoを導入したので、手順をメモしておく。
参考元は以下
Installing CUDA 7.5 and PyCUDA on windows (for testing theano with GPU) – Weimin Wang
TheanoをWindowsにインストール - 人工知能に関する断創録
<環境>
Windows8.1 64bit
GeForce GTX970
Anaconda Python2.7
Anacondaを使いたいので、まずはそれからインストールする
https://www.continuum.io/downloads
上のページからpython2.7のインストーラをダウンロード。指示に従ってインストール。
64bit版を使って問題ないと思います。
必要なパッケージは大体入っているので便利だと思う。
あとwindowsのコンソールからもpipコマンドが使えるようになります。
インストール途中でpathを追加するか聞かれるので、指示通り追加しておく。
Visual Studio 2013 community
MicrosoftのおなじみVisual Studioをインストールする。
2015は対応していないので注意。2013 communityだと無償で利用できるが、Microsoftアカウントへの登録は必要。
以下からVisual Studio 2013 communityのインストーラをダウンロードしてインストール。途中でいろいろ聞かれるが、GPUで使う分には推奨設定で問題なさそう。ただし読み飛ばしてると付属で別のソフトが入れられるのでその辺は注意。
https://www.visualstudio.com/ja-jp/downloads/download-visual-studio-vs.aspx
その後「システムの詳細設定」から環境変数にpathを追加する。場所は適宜読み替えてください。
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\;C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE
依存パッケージ
Anacondaを入れるとほぼ必要なものが入るそうなので、以下のコマンドで事足りる。
conda install mingw libpython
CUDA Toolkit
NVIDIAのサイトから、CUDA Toolkitをダウンロードする。
2015/11/21現在ではCUDA7.5が最新でした。
CUDA Toolkit 9.2 Download | NVIDIA Developer
このサイトで、使用するGPUが対応しているかを確認しておく。
Git
gitを使える環境でなければインストールする。これじゃなくてもgitが使えれば何でもよい。
Git for Windows
PyCUDA
pythonでCUDA Toolkitを使うためのライブラリ。バイナリからインストールしている人が多かったので一応同じようにした。以下からバイナリをダウンロードできる。
http://www.lfd.uci.edu/~gohlke/pythonlibs/
python2.7 64bit版のAnacondaをインストールしたので、
pycuda-2015.1.3+cuda7518-cp27-none-win_amd64.whl
をダウンロードする。
その後同じディレクトリまで移動し、
pip install pycuda-2015.1.3+cuda7518-cp27-none-win_amd64.whl
としてインストール。
うまくできたか確認するには、以下のコードを使用する。
# from: http://documen.tician.de/pycuda/tutorial.html import pycuda.gpuarray as gpuarray import pycuda.driver as cuda import pycuda.autoinit import numpy a_gpu = gpuarray.to_gpu(numpy.random.randn(4,4).astype(numpy.float32)) a_doubled = (2*a_gpu).get() print a_doubled print a_gpu
乱数の行列が出力されればおけ。
ここからtheano↓
Theano
Theanoをインストール。以下のコマンドでcloneする
git clone git://github.com/Theano/Theano.git
その後、
cd Theano python setup.py install
としてインストール。GPUを使う場合は、ホームディレクトリ(C:\Users\ユーザ名 とかそんなん)に.theanorc.txt
ファイルを作成し、以下のように記述する。
#!sh [global] device = gpu floatX = float32 [nvcc] compiler_bindir=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin # flags=-m32 # we have this hard coded for now [blas] ldflags = # ldflags = -lopenblas # placeholder for openblas support
動作確認には以下のコードを使う。
from theano import function, config, shared, sandbox import theano.tensor as T import numpy import time vlen = 10 * 30 * 768 # 10 x #cores x # threads per core iters = 1000 rng = numpy.random.RandomState(22) x = shared(numpy.asarray(rng.rand(vlen), config.floatX)) f = function([], T.exp(x)) print f.maker.fgraph.toposort() t0 = time.time() for i in xrange(iters): r = f() t1 = time.time() print 'Looping %d times took' % iters, t1 - t0, 'seconds' print 'Result is', r if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]): print 'Used the cpu' else: print 'Used the gpu'
実行して以下のように表示されれば、めでたくインストール完了。
Using gpu device 0: GeForce GTX 970 (CNMeM is disabled) [GpuElemwise{exp,no_inplace}(<CudaNdarrayType(float32, vector)>), HostFromGpu(GpuElemwise{exp,no_inplace}.0)] Looping 1000 times took 0.674000024796 seconds Result is [1.23178029 1.61879349 1.52278066 ..., 2.20771813 2.29967761 1.62323296] Used the gpu
これで自宅pcでもtheanoが使えるようになった。
二台体制で実験できるでこれ
ここまでやったのでついでにpylearn2も入れる。
theano モメンタム項を導入する
theanoを使って色々実験中。
学習率の制約等に関してはまだ試してなかったのでやってみる。
参考元は以下
http://nbviewer.ipython.org/github/craffel/theano-tutorial/blob/master/Theano%20Tutorial.ipynb
python - Clarification in the Theano tutorial - Stack Overflow
データセットにもよるだろうが、自分が使っているものについていえばかなりValidation errorが振動してしまうことが多かった。つまり誤差関数が急勾配な位置では重みの更新量が大きすぎて、なかなか極小値までたどり着かないという問題である。これは重みの更新式にモメンタム項を加えればある程度改善される。
追加するのは至って単純。畳みこみ、全結合、softmax層はそれぞれオブジェクトとして定義しておき、paramsというインスタンスに重み、バイアスを入れておくようにする。詳しくは前回。モメンタム項なしの場合の学習を以下のように書いたとする(layerの定義とかは省きます)。
cost = layer4.negative_log_likelihood(y) params = (layer4.params + layer3.params + layerC2.params + layerC1.params + layerC0.params) grads = T.grad(cost, params) updates = [ (param_i, param_i - learning_rate * grad_i) for param_i, grad_i in zip(params, grads) ] train_model = theano.function( [index], cost, updates=updates, givens={ x: train_set_x[index * batch_size: (index + 1) * batch_size], y: train_set_y[index * batch_size: (index + 1) * batch_size] } )
train_set_x
とtrain_set_y
にはそれぞれ訓練データとラベルが入ってます。Tutorialと変えてません。
updateの定義の部分を関数化し、以下のようにすることでモメンタム項を追加できる。
def gradient_updates_momentum(cost, params, learning_rate, momentum): # momentumが正しい値か確認 assert momentum < 1 and momentum >= 0 updates = [] for param in params: # 一つ前の状態のparamを保存しておくparam_updateという共有変数を導入する param_update = theano.shared(param.get_value()*0., broadcastable=param.broadcastable) # paramの更新式を定義 updates.append((param, param - learning_rate*param_update)) # param_updateの更新式を定義, momentum項の追加 updates.append((param_update, momentum*param_update + (1. - momentum)*T.grad(cost, param))) return updates
こうして、
cost = layer4.negative_log_likelihood(y) params = (layer4.params + layer3.params + layerC2.params + layerC1.params + layerC0.params) updates = gradient_updates_momentum(cost, params, learning_rate, momentum) train_model = theano.function( [index], cost, updates=updates, givens={ x: train_set_x[index * batch_size: (index + 1) * batch_size], y: train_set_y[index * batch_size: (index + 1) * batch_size] } )
こうする。
重みの更新式は
と表される(MLP「深層学習」より)。更新に一つ前の状態の重みを用いる。は学習率、がコスト関数であり、をモメンタムのパラメータとして調整する。
が一定となる間は、
と収束し、これは学習率を倍するのと同等であると言える。そのため何もしていない状態からモメンタム項を追加するときは、学習率を少し調整する必要が出てくる。
ここによると、まずは0.5ぐらいに設定し、徐々に上げて0.9ぐらいにするのが望ましいらしい。その間で誤差の減少が不安定になるようなら学習率を1/2倍ずつ減らしていくといいという。とりあえず学習率を1/2にしてとするとすぐ使えそうである。
使ってみたところ、かなり安定して学習が行えるようになった。
次は重み減衰とか? 順番めちゃくちゃなのは気にしない
【曲紹介とかしてみる】The Shade Of The Cedar Tree
昨日からずっと雨でちょっと気分が乗りませんね。
そんな時はかっこいいjazzの曲でも聴いて元気出していきましょう。
雨降ってなくても聴きましょう。
そんなわけで今回は、世界的ベーシストChristian McBrideの曲
「The Shade Of The Cedar Tree」です。
Christian McBride & Inside Straight - The Shade Of ...
テーマのメロディ、コード進行、構成、全部かっこいい。
かっこいい(大事なことなので二回言いました)。
音域とかフレーズとか、ベースという楽器がおおよそ受けうるような制約を全く感じさせません。あとビブラフォンが凄くいい味出してると思います。残念ながら誰が演奏してるかはわからなかったのですが...ご存知の方がいれば教えてください
自分はちょっと耳が貧弱なので音(コード)を取れなかったのですが、知人に採譜してもらってこの曲を弾いたことがあります。くっそ気持ち悪いコード進行です。。こんなんでよくかっこよくなるなぁと、楽譜を見るたびに思います。
Christian McBride(1972-)は言わずと知れた、第一線をゆくベーシストですね。jazzに限らず多彩なジャンルで活躍されています。何より驚くのはその若さ、まだ四十代前半で現役バリバリです。これからのjazzシーンを引っ張っていかれること請け合いでしょう。ちなみにこの人、エレキベースも弾けます。それはもう鬼のように弾きます。。興味がある人はYoutubeとかで調べてみてください。
これの百分の一でも弾けたらなぁ...