ディープラーニング学習メモ #2 行列の積

UdacityのDeepLearning基礎コース、Week3以降は週5-6時間程度でレッスンコンテンツは一通りはこなせています。 ただ、後でしっかり復習しないと身につかない感じはあります。。 そりゃそうですよね、、世の中そんなに甘くない。(;^_^A

今日は行列の積についてメモを残します。

dot演算とelementwise演算

dot演算

学校の授業で習ったいわゆる行列の掛け算はdot演算と呼ばれるものになります。

  • 行列A (m,n) * 行列B (n, p) = 行列C (m, p)
  • Aの列数とBの行数を合わせる必要がある
  • 積ABの要素ij は Aのi行とBのj列の畳み込み

f:id:sanshonoki:20170301050110p:plain:w400

elementwise演算 (*演算)

elementwise演算は 単純に要素同士を掛け算するだけです。

  • 積ABの要素ij は Aの要素ijとBの要素ijの掛け算
  • 厳密には A、Bの行数と列数が同じでないと掛け算できない
  • ただし、numpyにはブロードキャストという仕組みがあるので列数と行数が一致していなくても演算可能(な場合がある)

f:id:sanshonoki:20170301050124p:plain:w400

numpyにはブロードキャストという仕組みがあるので列数と行数が一致していなくても演算可能になっています。ここが混乱しどころです。これは numpyが演算するときにサイズを変換してくれるためです。

ブロードキャスト

ブロードキャストできるかどうか? Broadcasting — NumPy v1.12 Manual

  • ベクトル (n,) は行ベクトル (1,n) として扱う
  • 各軸の次元が同じまたはどちらかが1
*演算 dot演算
(m, 1) x (1, n) ok ok
(m, 1) x (n, 1) NG NG
(m, 1) x (n,) ok NG
(n,) x (m, 1) ok NG

okのパターンでは (m, n)の行列が出力されます。

使いどころ

ディープラーニングで出てくる計算の中で2種類の掛け算をどう使い分けるのか、、、

ざっくりまとめてみました。

*演算 dot演算
1つのノード内での計算
(シグモイドの微分計算etc)
複数ノード間の計算
(重みWとベクトルとの計算)
例1: シグモイドの微分  \sigma'(h) = \sigma(h) * (1 - \sigma(h))
例2: 入力誤差の伝搬  (\delta W^{T}) * \sigma'(h)
例1: 順伝搬  {Wx}
例2: 入力誤差の計算  \delta W^{T}
例3: 誤差から {\Delta W}を計算  \delta x^{T}

入力の次元数と出力の次元数が同じときは *演算 と考えていいです。

dot演算の例3では 入力が1次元のベクトルの場合に、*演算としても計算可能ですが2次元以上の場合に計算できないので dot演算として考えるのが無難でしょう。

競走馬のパドック画像を収集する

次の例のようにCNN (Convolutional Neural Network) で何か面白い分類をやってみたい

gigazine.net

MNISTやCifar10と言ったような練習用のありきたりのデータではなく何かcoolな題材はないかな〜と考えていたところ、、

馬体から短距離馬と長距離馬を見分けられたら面白いのではないか?(また、競馬かよ)

そう、短距離馬と長距離馬は首筋の長さ、太さで特徴が違うのです。

もしかしたらディープラーニングで見分けられるかも〜?!   ¨キ(o゚Д゚o)¨キ

ということで、パドック画像を探してみます。パドック画像だけを取りまとめているリソースがなかなか見つかりませんでしたが、、、

ありました! 競馬道のサイトの競馬ブックコーナーです。ヽ( ´¬`)ノ

早速、クローラを実装して画像を収集させていただきました。ソースコードはこちらにあります。

github.com

2001年より前はフォーマットが違っていて以下のように写真の中に文字も含まれてしまうので2002年以降の写真を収集しました。

http://www.keibado.ne.jp/keibabook/010109/photop.html http://www.keibado.ne.jp/keibabook/010109/images/pp01.jpg

2017年1/23時点で のべ頭数 8707頭、ユニーク頭数としては 2528頭分の画像を収集できました。

収集した画像はこちらからダウンロードできます。

今回はここまでです。

ディープラーニング学習メモ #1 行列

Udacityの Deep Learning Nanodegree Foundation の Week1 が終わりました。

シラバスでは学習時間の目安は 3-4 hours per week と書いてありましたがかれこれ20時間近く費やしています。。ヽ(;´Д`)ノ

誤差の逆伝搬の詳しい仕組みとか今までスルーしてきたところなのでそれなりに理解に時間がかかるのは仕方ない…とは思いつつも Week2以降大丈夫だろうか? 不安。。

それはおいとき、自分自身の理解をより深めるために少しずつ学習メモを残していきたいと思います。

1回目は 行列です。

行と列とrowとcolumn

どちらが行でどちらが列か、、

イメージで覚えると忘れにくいです。次の図が分かりやすかったです。

http://sci.tea-nifty.com/blog/2014/12/row-column-f052.html

http://sci.tea-nifty.com/photos/uncategorized/2014/12/06/b4ffosxciaazysl.jpg

http://id.fnshr.info/2015/10/17/matrix/

http://id.fnshr.info/wp-content/uploads/sites/2/2015/10/column.png

http://id.fnshr.info/wp-content/uploads/sites/2/2015/10/row.png

http://lambdalisue.hatenablog.com/entry/2013/07/18/134507

http://cdn-ak.f.st-hatena.com/images/fotolife/l/lambdalisue/20130718/20130718131854.png

行と列の関係は 画像処理に慣れている人は混乱するかもしれません。(私だけ??)

というのも、画像のサイズは通常、 W (横の大きさ) x H (縦の大きさ) と表現しますがこれを行列にすると逆になります。

つまり、W x H の画像は H x W の行列で表現されます。

f:id:sanshonoki:20170214062324p:plain:w400

numpyでの行ベクトルと列ベクトル

numpyの次の3つの構造のイメージつくでしょうか..?

(m, )

(m, 1)

(1, m)

正解・・・

(m, ) は 1次元ベクトル、

https://wikimedia.org/api/rest_v1/media/math/render/svg/507111acf945f5fe57c45ecc563ec02a4aff4a1b

(m, 1) は 列ベクトル

https://wikimedia.org/api/rest_v1/media/math/render/svg/32bf4d54c8e316178fca0b9f4a79dd0a0a34f34f

(1, m) は 行ベクトル

https://wikimedia.org/api/rest_v1/media/math/render/svg/507111acf945f5fe57c45ecc563ec02a4aff4a1b

(m, 1) はついつい横方向のベクトル、行ベクトルと思ってしまいますがこれは落とし穴で列ベクトルです。 慣れだとは思いますが。。

1次元ベクトルを列ベクトルに変換する方法

いったん2次元にしてから転置(transpose)する必要があります。 記述は 2パターンあります。

>>> data = np.array([1,2,3])
>>> data
array([1, 2, 3])

# 方法1
>>> data[:, None]
array([[1],
       [2],
       [3]])

# 方法1'
>>> data[:, np.newaxis]
array([[1],
       [2],
       [3]])

# 方法2
>>> np.array(data, ndmin=2).T
array([[1],
       [2],
       [3]])

2回目へ続く(はず。。)

ダースベイダー

4才の息子が"パパの大好きなスターウォーズ"のダースベイダーを作ってくれました。

f:id:sanshonoki:20170206063618j:plain:w300

おぉ、言われるとそう見えてきます。。(^ ^)

ちなみに、おしっこもできるように穴を開けた そうです。

子どもの頭の柔軟さを改めて感じた週末でした。

Udacityのディープラーニングのナノ学位基礎コースを受講することにした

Udacityのディープラーニングのナノ学位基礎コースを受講登録しました。

f:id:sanshonoki:20170125064028j:plain

お値段 399ドル !!

住宅ローン残高がモリモリ残っている中それなりの投資額にガクブルしましたが来たるAI時代のビッグウェーブに飲み込まれないようにディープラーニングを学ばないわけにはいきません。(๑•̀д•́๑)キリッ

必要な時間は毎週3〜4時間程度とのことでそれであれば仕事しながらでも十分いけそうです。

講師のSirajさんがYouTubeスターなそうでYouTubeスターの授業というものはどんな授業なのか? 普通の教え方とは何か違うのか? 期待度が高くワクワクしてます。

機械学習系のオンライン講座といえば無料かつそして受講者からの評価も高いCoursera (https://www.coursera.org/learn/machine-learning)という超有名な講座がありますがディープラーニングにフォーカスしたより実践的なカリキュラムを学びたかったので身銭を切ることにしました。 身銭を切ると真剣度が違いますから。。

シラバス

ちなみに、シラバスは以下のようになってます。

  • WEEK 1
    • Types of Machine Learning and when to use Machine Learning
  • WEEK 2
    • Neural Network Architecture and Types
  • WEEK 3
  • WEEK 4
    • Math Notation and Recommender Systems
  • WEEK 5
    • Data preparation (cleaning, regularization, dimensionality reduction)
  • WEEK 6
    • Drone Image Tracking
  • WEEK 7
    • Prediction
  • WEEK 8
    • Art Generation
  • WEEK 9
    • Music Generation (LSTMs applied to Audio)
  • WEEK 10
    • Poetry Generation (LSTMs applied to NLP)
  • WEEK 11
    • Language translation (sequence to sequence)
  • WEEK 12
    • Chatbot QA System with Voice
  • WEEK 13
  • WEEK 14
    • Image Compression
  • WEEK 15
    • Data Visualization
  • WEEK 16
    • Image Generation
  • FINAL WEEK 17
    • One-shot Learning (Probabilistic Programming)

楽しみです。

RNNで競走馬の名前を生成してみる

RNN (Recurrent Neural Network) を使って何かをやってみようと前々から考えてましたがネタが思いつかない・・・

・・・・・・・・・・・・・・・

・・・ ありました! 競走馬の名前を生成してみよう

ということで早速やってみました。

名前を題材にしたワケ

RNNを使った文章生成というのはいろいろ試されています。

が、何となくの文章は作成できますがまともに意味の通った文章は作成できません... >< 。 名前であればそういう問題を回避でき実用的なアプリケーションとしても成立し得るのでは?と考え選択しました。

データの収集

何はともあれ、データの収集です。 競走馬の名前データはNetkeibaさんのサイトからクローラで取得してきました。

クローラのコードはこちら github.com

以下のような感じで賞金順に約5万頭分取得しました。

テイエムオペラオー
ディープインパクト
ゴールドシップ
ブエナビスタ
オルフェーヴル
ジェンティルドンナ
ウオッカ
ヴァーミリアン
ゼンノロブロイ
スペシャルウィーク
タップダンスシチー
メイショウサムソン
ホッコータルマエ
エスポワールシチー
ダイワメジャー
メジロマックイーン
(以下続く)

学習

yusuketomotoさんのコードを一部だけ修正して学習します。

修正した点

  • 単語単位で入力するのではなく文字単位で入力する
  • 名前の最後に終端記号 <eos> を挿入し、これも入力する

学習のコードはこちらです。 github.com

学習時間は手持ちのGPUなしのMacBookProで50分ちょっとでした。 epoch数を始めパラメータはチューニングせずにとりあえずそのまま使いました。

名前の生成

学習した結果を使って生成してみます。

オリジナルのコードから修正している点は

  • <eos>が出力されたら改行コードに置き換えて出力

だけです。

1epoch後の学習データから生成してみると、、

$ python sample.py --vocabulary data/umaname/vocab.bin --model cv/charrnn_epoch_1.20.chainermodel

ドキドキ、、

ポィー
コンモカッゴード
エンボラータンド
コシャンシィード
ジァブナンシュベ
ダイシッハーブゲ
ダイキビビィ
フメボシャタブウス
マエンジィニスアイ
アインチルダントス
スエーショモンダ
ホイナードフロム
スロフミニント
トサトフリクテケリー
(以下、続く)

おぉ、なんとなく馬の名前っぽい (^^)

さらに学習してみます。 50epoch学習した後で以下のように生成されました。

シタ
メジロモスカル
コスモフローラ
アカネホール
タイコウ
フジノフェアリー
メイショウドナバブ
ラウンドストール
ミサフルチャペル
トウショウコラント
トウショウタキフ
イデルスユー
ダークストーリー
トーセンミューター
(以下、続く)

「トウショウ」や「トーセン」といったおなじみの冠名も再現されてます。より馬名っぽくなりました!

成功です。ヾ ( ´ ρ ` ) ノ

デモサイト

こちらにあります。

https://tanakatsuyo-umaname-generator.herokuapp.com/

「Get one」ボタンを押すとコンピュータが生成した名前をランダムで表示します。 仮想の馬名を使いたいけど考えるのが面倒だというシチュエーションで役立つと思います。。

新ももたろう

むかしむかし、あるところに、おじいさんとおばあさんが住んでいました。

のおなじみのフレーズで始まる日本昔ばなし「桃太郎」。

通常ならば「おじいさんは山へ柴刈りに、おばあさんは川へ洗濯へ」となりますが、 最近、4歳になったばかりの息子に「おばあさんは山へ柴刈りに、おじいさんは川へ洗濯へ」と ストーリーを変えてその後のストーリーも即興で作りながらしゃべってあげました。

4歳ともなると、通常の「桃太郎」のストーリーは知っていて通常とのギャップも理解でき、これが意外とうけました。

ちなみに、おじいさんは川へ洗濯へ行って流れてきた桃を拾おうとしたら流されてしまいました.. という展開をしました。。

ストーリーを即興で作るのはなかなか大変ですが子どもにも受けるし、自分にとってもちょっとした頭のトレーニングになります。引き続きやってみようと思います。