備忘録とか日常とか

学んだこととかを書きます。

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では局所領域ごとに平均{\overline{x}_{ij} }を求めて減算、そこから標準偏差{\sigma_{ij} }をとって除算を行う。

単一の特徴マップ{x_{ij} }に対して、画素{(i,j)}を中心とする正方領域{P_{ij}}を考える。
これを局所領域のフィルタとして平均と分散を求める。式で書くと以下のようになる。

{\displaystyle
\overline{x}_{ij} = \sum_{(p,q)\in P_{ij}} w_{pq}x_{i+p,i+q}
}

{\displaystyle
\sigma^2_{ij} = \sum_{(p,q)\in P{ij}} w_{pq}(x_{i+p,j+q}-\overline{x}_{ij})^2
}

ここで、{w_{pq} }は重みであり、上の式では重み付き平均をとっていることになる。
一般的に画像では、注目画素から遠くなるほど輝度変化は大きくなるので、その影響を小さくするために、中心から離れるに連れて低下するような重みを用いる。(要するにガウシアンフィルタ)

上で求めた値を使って正規化する。

{\displaystyle
z_{ij} = \frac{x_{ij}-\overline{x}_{ij}}{\sigma{ij}}
}

平均で引くだけにした場合を減算正規化(Local mean subtractionと同義)、その後標準偏差で割るところまで計算すると除算正規化(LCNと同義)と呼ばれるらしい。
ただし上の計算をそのまますると、コントラストが小さい領域ほど濃淡がはっきり出てしまうことになる。コントラストが大きいところにのみ上記の計算を適用するため、定数{c}を用意して、以下のような計算をする。

{\displaystyle
z_{ij} = \frac{x_{ij} - \overline{x}_{ij}}{max(c, \sigma_{ij})}
}

こうすることで{\sigma_{ij} < c } となるところは濃淡が強調されることを防ぐ。


とりあえず書いてみる。
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)

前回に引き続いて、機械学習の本を読んでいく。
読んでいるのはこれです

Machine Learning: An Algorithmic Perspective, Second Edition (Chapman & Hall/Crc Machine Learning & Pattern Recognition)

Machine Learning: An Algorithmic Perspective, Second Edition (Chapman & Hall/Crc Machine Learning & Pattern Recognition)

例によってほぼ自分用なので参考にはならないかもです。

続きを読む

【曲紹介とかしてみる】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 AdderleyStan Getz などの数々の有名プレイヤーと共演してきたそうです。その繊細な音のタッチは、あのBill Evansと比較して語られるほどだとか。今まで知らなくてすいませんて感じです・・・。



もちろんこの曲だけでなく、クリスマスのjazzアレンジ曲はいっぱいありますので調べてみてもいいかもです。
予定は特にないという方、今年はjazzyな一日を過ごされてみてはいかがでしょう。
案外ぼっちも悪くないですよ?

まあ寂しいのは変わらんけど

Machine Learning: An Algorithmic Perspective 読んでいく(1)

機械学習に関する色んな書籍が世の中には出回っている。星の数ほどはないかもしれないけどかなりの数あると思う。
最近は「実装しながら説明していくよ!」という本も増えているそう。自分みたいなコーディングどへたくそな人間にとっては凄くありがたい(そして英語の勉強にもなる)。。そんな背景もあって以下の本を読むことになりました。

Machine Learning: An Algorithmic Perspective, Second Edition (Chapman & Hall/Crc Machine Learning & Pattern Recognition)

Machine Learning: An Algorithmic Perspective, Second Edition (Chapman & Hall/Crc Machine Learning & Pattern Recognition)

内容は

  • chapter1: Intorduction
  • chapter2: Preliminaries
  • chapter3: Neurons, Neural Networks, and Linear Discriminants
  • chapter4: The Multi-layer Perceptron
  • chapter5: Radial Basis Functions and Splines
  • chapter6: Dimensionality Reduction
  • chapter7: Probabilistic Learning
  • chapter8: Support Vector Machines
  • chapter9: Optimisation and Search
  • chapter10: Evolutionary Learning
  • chapter11: Reinforcement Learning
  • chapter12: Learning with Trees
  • chapter13: Decision by Committee Ensemble Learning
  • chapter14: Unsupervised Learning
  • chapter15: Markov Chain Monte Carlo Methods
  • chapter16: Graphical Models
  • chapter17: Symmetric Weights and Deep Belief Networks
  • chapter18: Gaussian Processes

と、かなり盛りだくさんである。全部読めばそれなりの知識が得られそうではあるが、さすがにしんどいのでまずは3,4章を読んでいく。
理論的な部分はかなり省略されており、入門用の本なのだと思う。あと完全に自分が頭の中を整理するためのものなので、読んでても参考にはなりません。。

続きを読む