theanoでLocal Response Normalization(LRN)を使う
Deeplearning Tutorialでtheanoによる実装、アルゴリズムを勉強中。
前回のLCNに引き続いて、LRNの正規化についても試す。
今回はpylearn2内のコードがそのまま流用できるので、新しくコードを書いたりする必要はない。
参考元は以下
pylearn2/normalize.py at master · lisa-lab/pylearn2 · GitHub
MIRU2014 tutorial deeplearning
pylearn2内のコードではLocalResponseNormalizationではなくCrossChannelNormalizationという名前になっている。LCNとごっちゃになるのを避けてるのかもしれない。
LRNが最初に世に知られたのが、Imagenetの論文である。オーバーラッププーリングや活性化関数のReLUなどと並べて説明されており、このCNNの性能の要になっているように思える。
LRNは端的に述べると、「同一位置(ピクセル)において複数の特徴マップ間で正規化する」ということだそうだ。元の論文にも書いてあるが、LRNは"brightness normalization"であり、LCNのように輝度の平均を減算して0にしないことがミソらしい。
式で書くと以下のようになる(論文の式そのままです)
k, n, , がパラメータである。はi番目の特徴マップの(x,y)のピクセルを、Nは特徴マップの総数を表す。
summationの部分は、「i番目の特徴マップに対して、n近傍の特徴マップの二乗和をとる」という意味である。
下みたいなイメージ
端っこの特徴マップに関しては片側だけ和をとる。
この処理をCNN内の1層として組み込む。Imagenetの論文では畳みこみ層の直後にLRNを配置しているが、Caffeで用意されているモデルではプーリングの直後に配置されていた。岡谷先生の[asin:4061529021:title]でもそのモデルが紹介されていたので、どっちでもいいのかもしれない。
実際に使うのはすごく簡単。
pylearn2からnormalize.pyのCrossChannelNormalizationを引っ張ってくる。
Deeplearning Tutorialでは画像データの扱いは[batch_size, channel, row, column](bc01)となっていたので、それにあったものをインポートする。
from pylearn2.expr.normalize import CrossChannelNormalizationBC01 as Normalize # Normalizeは引数にalpha, k, beta, nが指定できる。 # デフォルトでは alpha=1e-4, k=2, beta=0.75, n=5 Normlayer = Normalize()
名前は適当に決めた。
あとはconvolutionかpoolingの出力をNormlayerに入れるだけである。
以前の記事に載せてあるConvLayer
を使って書くと、
layerC0 = ConvLayer(...) inputP0 = Normlayer(layerC0.output) layerP0 = PoolLayer(inputP0, ...)
これでおけ。
theanoじゃなくてpylearn2をそのまま使いたいところだけど、pylearn2でCNN使ったら11epochで止まっちゃって学習できなかった。
同じ症状の人も結構いるっぽいけど直し方がよくわからないし・・・ドキュメント全然更新されてないし・・・
そのうちchainerとかtensorflowとかも触ってみようかな。
theanoで局所コントラスト正規化(Local Contrast Normalization)を使う
Deep Learning Tutorial で theanoによる実装,アルゴリズムを勉強中。
研究では主にCNNをtheanoを使っているが、正規化層による効果はどんなものか試してみたくなったので実装する。
theanoはあくまで数値計算ライブラリなので、はじめから正規化のための関数が用意されているわけではない。その他にも機械学習でよく使うような関数が用意されていないこともままある。そこでtheanoをベースとしている機械学習ライブラリであるpylearn2の中から、コードを参考にして実装していく。
参考元は以下
https://github.com/lisa-lab/pylearn2/blob/master/pylearn2/datasets/preprocessing.py
Theano-3D-ConvNet/convnet3d.py at master · lpigou/Theano-3D-ConvNet · GitHub
python - Implementing LeCun Local Contrast Normalization with Theano - Stack Overflow
MIRU2014 tutorial deeplearning
正規化の方法にはいろいろあり、代表的なものを挙げると
- Global Contrast Normalization(GCN)
- Local Contrast Normalization(LCN)
- Local Response Normalization(LRN)
- ZCA whitening
- Local mean subtraction
などがある。Deep Learningに限らず、画像認識で一般的に行われる前処理としての正規化はGCNとかが多いらしい。CNNが世に知られるきっかけとなったKrizhevsky氏のImageNetの論文では、RGBの画素値の平均を引くだけにしているので、前処理の必要の有無はタスクによるのかもしれない。Caffeとかでもデフォルトで平均画像を引くようになってたような気がする。
CNN内の正規化層としては、LCNやらLRNが使われる。
お恥ずかしい話ではあるが、つい最近までLCNとLRNをごっちゃにして考えていた・・・。とりあえず違いを確認する。
以下、画像のチャネルを特徴マップと呼ぶ。(元画像はRGBの3チャネルを持つ)
LCNはその名の通り、特徴マップの局所領域内でコントラストを正規化する。この処理は一つの特徴マップ内で完結するので、すべての特徴マップに対して独立して行う。
対してLRNでは、同一位置における異なる特徴マップ間で正規化する。どちらもいくつかのハイパーパラメータはあるが、学習の対象となるパラメータはないので、誤差伝播が容易に可能である。
今回はLCNを実装するのでLRNはまた今度説明することとする。
LCNでは局所領域ごとに平均を求めて減算、そこから標準偏差をとって除算を行う。
単一の特徴マップに対して、画素を中心とする正方領域を考える。
これを局所領域のフィルタとして平均と分散を求める。式で書くと以下のようになる。
ここで、は重みであり、上の式では重み付き平均をとっていることになる。
一般的に画像では、注目画素から遠くなるほど輝度変化は大きくなるので、その影響を小さくするために、中心から離れるに連れて低下するような重みを用いる。(要するにガウシアンフィルタ)
上で求めた値を使って正規化する。
平均で引くだけにした場合を減算正規化(Local mean subtractionと同義)、その後標準偏差で割るところまで計算すると除算正規化(LCNと同義)と呼ばれるらしい。
ただし上の計算をそのまますると、コントラストが小さい領域ほど濃淡がはっきり出てしまうことになる。コントラストが大きいところにのみ上記の計算を適用するため、定数を用意して、以下のような計算をする。
こうすることでとなるところは濃淡が強調されることを防ぐ。
とりあえず書いてみる。
CNNのうちの一層として使えるようにオブジェクトで定義すると以下のようになる。
class NormLayer(object): def __init__(self, input, kernel_shape=9, threshold=1e-4, method="lcn"): input_shape = input.shape input_shape_X = (input.shape[0]*input.shape[1] , 1 , input.shape[2], input.shape[3]) X = input.reshape(input_shape_X) if method=="lcn": out = self.lecun_lcn(X, kernel_shape) self.output = out.reshape(input_shape) def lecun_lcn(self, X, kernel_shape, threshold=1e-4): """ Yann LeCun's local contrast normalization Orginal code in Theano by: Guillaume Desjardins """ filter_shape = (1, 1, kernel_shape, kernel_shape) filters = gaussian_filter(kernel_shape).reshape(filter_shape) filters = theano.shared(theano._asarray(filters, dtype=theano.config.floatX), borrow=True) # 'full' convolution outputのサイズは input_shape + filter_shape - 1 convout = conv.conv2d(input=X, filters=filters, filter_shape=filter_shape, border_mode='full') # 各ピクセルから、kernel_size x kernel_size 近傍の平均を減算 mid = int(numpy.floor(kernel_shape / 2.)) centered_X = X - convout[:, :, mid:-mid, mid:-mid] # kernel_size x kernel_size 近傍の標準偏差で除算 sum_sqr_XX = conv.conv2d(input=centered_X ** 2, filters=filters, filter_shape=filter_shape, border_mode='full') denom = T.sqrt(sum_sqr_XX[:, :, mid:-mid, mid:-mid]) per_img_mean = denom.mean(axis=[2, 3]) divisor = T.largest(per_img_mean.dimshuffle(0, 1, 'x', 'x'), denom) # 定数c(threshold)で、コントラストが大きい場合のみ標準偏差で除算 divisor = T.maximum(divisor, threshold) new_X = centered_X / divisor return new_X def gaussian_filter(kernel_shape): x = numpy.zeros((kernel_shape, kernel_shape), dtype=theano.config.floatX) def gauss(x, y, sigma=2.0): Z = 2 * numpy.pi * sigma ** 2 return 1. / Z * numpy.exp(-(x ** 2 + y ** 2) / (2. * sigma ** 2)) mid = numpy.floor(kernel_shape / 2.) for i in xrange(0, kernel_shape): for j in xrange(0, kernel_shape): x[i, j] = gauss(i - mid, j - mid) return x / numpy.sum(x)
使い方としては、画像を[batch_size, channel, height, width]の形の4Dtensorにしてinputに通すだけである。(パラメータは適当に調節する必要あり)
ここのコードはGCNと減算正規化もまとめて実装してあったので、拡張の余地を残すためにmethodという引数を入れといた。
これで一応theanoでLCNが使えるようになる。
正規化が有効かどうかは結局データに依存するのだが、まあ試してみるだけ試す。
次はLRNについて書く。
ubuntuでホームディレクトリの中身を英語表記にする
タイトルの通り。
CUIで動かしたいときにドキュメント等のフォルダが日本語表記だと不便なので、英語に変える方法をメモしておく。
環境
・Ubuntu14.04 LTS
方法は以下のコマンドを打ち込むだけ。
LANG=C xdg-user-dirs-gtk-update
こうするとディレクトリネームをアップデートするかどうか聞かれるダイアログが開くので、「Update Names」を選択する。
ただし、すでにディレクトリの中にファイルが入っている場合は、英語表記のディレクトリが新しく作られる形になる。
例えば「ドキュメント」のディレクトリにファイルが入っているときに上記のコマンドを使ってアップデートすると、ドキュメントのディレクトリの中身はそのままに新しく「Documents」というフォルダが作られる。中身を移すのは手動で行う必要がある。
移した後は日本語名のディレクトリは削除して問題ない。
アップデート後に再起動すると同じようなダイアログが開くかもしれないが、上と同様にする。
ちなみに戻すのは以下
xdg-user-dirs-gtk-update
同じようにダイアログが開くので確認する。
Machine Learning: An Algorithmic Perspective 読んでいく(2)
前回に引き続いて、機械学習の本を読んでいく。
読んでいるのはこれです
- 作者: Stephen Marsland
- 出版社/メーカー: Chapman and Hall/CRC
- 発売日: 2014/11/17
- メディア: ハードカバー
- この商品を含むブログを見る
例によってほぼ自分用なので参考にはならないかもです。
続きを読む【曲紹介とかしてみる】Winter Wonderland (Eddie Higgins Trio)
今年も残すところ2週間とちょっとです。すっかりクリスマスムードですね。
街中で流れるBGMやら装飾やらが一気にクリスマス仕様に変わるわけですが、別に一人寂しく過ごすとしても私はこの時期が好きです。なんか雰囲気とか、街全体が浮ついてる感じとか。子供の頃に感じたワクワク感みたいなのが根強く残ってるのかもしれません。。
そんなわけで、今回は皆が知っているであろう曲のjazzアレンジを紹介してみます。
Eddie Higgins Trioの「Winter Wonderland」です。
Eddie Higgins Trio / Winter Wonderland
トリオでスタンダードな仕上がりになってます。
特に派手なことをやっているわけではないですが、聴いていてとても心地よいです。
トリオって曲によっては
「これほんとに3人でやってんのか!音圧やべえ」
みたいなのもあって、それはそれでかっこいいのですが
こういう静かな、でも埋めるとこは埋める、みたいな曲もすごく好きです。
この曲を聴きながらなら聖夜に一人ぼっちでもへっちゃらですね。ええ、へっちゃらですとも。
異論は認めません。。
Eddie Higgins(1932-2009)は、ビバップを代表とするtraditional jazzを数多く手がけたピアニストです。残念ながら既に亡くなられていますが、彼が編曲したスタンダードjazzはこれからも後世に渡って聴かれ続けることでしょう。
Higginsは子供の頃は母親にピアノを教わっていたみたいです。母親がすごい音楽家だったかどうかはわかりませんが、物心つく前からの英才教育が今や当たり前になっていることを考えると、少しほのぼのするエピソードですね。。無論その後は音楽大学に進学しています。
卒業後はシカゴのジャズクラブで働き、Cannonball Adderley や Stan Getz などの数々の有名プレイヤーと共演してきたそうです。その繊細な音のタッチは、あのBill Evansと比較して語られるほどだとか。今まで知らなくてすいませんて感じです・・・。
もちろんこの曲だけでなく、クリスマスのjazzアレンジ曲はいっぱいありますので調べてみてもいいかもです。
予定は特にないという方、今年はjazzyな一日を過ごされてみてはいかがでしょう。
案外ぼっちも悪くないですよ?
まあ寂しいのは変わらんけど