Caffeを使ったCNNによる手書き文字分類 [1] - CNNの概要、データセットの準備

blog.li.nu >
この記事が役に立ったら
このシリーズでは、Caffeと呼ばれるニューラルネットワーク向けライブラリを使って、0から9までの手書き文字を分類できるような畳み込みニューラルネットワーク(CNN)を分類させる方法について説明します。 ここでは以下のことはすでに知っている・やってあるものとして話を進めます。

CNNとは?

 畳み込みニューラルネットワーク(CNN, Convolutional Neural Network)とは、生物の脳における視覚システムにヒントを得た情報処理の手法です。この由来から、神経を意味する neural の名前がついています。 別に、アメリカのニュースを放送しているテレビ局とは関係があるというわけではありません。
 わざわざ「畳み込み」とかいう変な名前がついていますが、それがついていない普通のニューラルネットワークもあります。 これらはいずれも「機械学習」と呼ばれる、与えた情報がどのようなパターンに属するのかを判断するパターン分類に代表される大きな分野の中の1つの小分野として位置づけられます。 機械学習という名前から想像が付くように、これらは「訓練」と呼ばれる過程をそれぞれのモデルに行うことで、実際に使える状態に自らを変化させていきます。 つまり脳のたとえで言うなら、人間と同じように、ある入力に対して正しい反応ができるよう、脳の神経細胞同士の繋がりの度合いを自ら強めたり弱めたりするようなことをして学習していくのです。
 そういう意味ではこの2つは学習のメカニズムはほぼ同じものですが、CNNの場合、普通のニューラルネットに加えて、入力情報の周囲のつながり、画像の場合は上下左右の位置関係になるわけですが、それを考慮しながらより抽象的な情報へと変換してき、それを普通のニューラルネットワークでパターン分類するという2段構成になっています。 このように、周りの情報を考慮しながら情報を抽出するという特性により、主に畳み込みニューラルネットワークは画像認識の分野で非常に広く用いられていて、実際非常に高い性能を発揮しています。
 もしここまでで書いたことがよく分からない場合は、それでも問題ありません。 とにかくこのシリーズでは、コンピュータビジョンや機械学習、アルゴリズムなどの専門的な知識は仮定せず、CNNの構造をできるだけ誰でも分かるように、かつできるだけ詳しく書くことを目標にしているので、最後まで読み進めるようにしてください。

データセットの重要性

まず初めての人が勘違いしてはならないのは、ニューラルネットワークには訓練データが必要だということです。 私達が自分で入力データおよびそれに対して出てきて欲しいデータを用意し、ニューラルネットが出した答えに対して具体的な間違いを指摘してやる必要があります。 その結果、ニューラルネットはその間違いに気付き、正解に近づけるよう学習をしていきます。 これを繰り返すことで、未知のデータがやってきても、問題なく判断できるモデルが出来上がるのです。
 こう書くとまるでニューラルネットワークが魔法で動いているように思ってしまうかもしれないので、一応コンピュータがちゃんと計算できる仕組みになっているということを補足するため、 より詳しくこの流れを書き直します。CNNを含むニューラルネットには、更新可能な内部パラメータが大量にあります。 これらのパラメータは、最初はランダムで決めてあり、与えられた入力データを元に、それらのパラメータに基づいて計算がなされ、結果が得られます。 例えば、CNNで「人」「犬」「猫」を分類したいとしましょう。ここで、パラメータはランダムに決まっているので、人の画像をCNNに入力したとしても、CNNはほぼランダムにどれかを出力します。 つまり、最初は人を入力しても人、犬、猫のどれかわからないで適当に答えます。定期テストで、問題の意味が全くわからない3択問題が出た時、鉛筆転がしで答えを決めたようなものです。
 そうして出てきた結果に対して、「違う」ということをCNNに伝えます。具体的には、CNNの場合は各カテゴリの「確率」を出力します。 例えば上の例の場合、全くどれがどれか分かっていないため、人、犬、猫どれも33%という結果が出てくるというわけです。 そこで誤差関数というものを定義して、その違いの度合いを数値化して伝えます。「それは人の画像であり、人は100%、残りは0%になるべきだったんだ」ということを、今出てきた全部33%の数値との誤差という形でニューラルネットに伝えるのです。
 これを受けたCNNは、誤差逆伝搬法という、高速にパラメータを更新するための方法を使い、確率的勾配降下法という、確実に正解に近づける、言い換えると確実に誤差を減らすような方法でパラメータを自動で更新します。 これを何百回、何千回、何万回と実施することで、はじめて分類器として機能できるようになります。
 ここで強調したいのは、○○法とかいう変な名前の難しそうなコンピュータアルゴリズムについてではなく、ニューラルネットは訓練データとそれに対する正解データを与えて訓練しなければ使えるようにならないということです。 分類器に限らず、何をさせるにあたっても、ニューラルネットは訓練のための入力データ、およびそれに対する正解データの組を必ず、それも多くの場合大量に(少なくとも数千〜場合によっては数百万)必要とします。
 CNNを使って分類器を作りたいと思ったら、どういう構造にするかとか、細かいところはどうでもいいので、「どうやって訓練データを用意するのか」、つまり、 「入力画像とそれに対する正解の分類結果をどうやって大量に用意するのか」ということをまず考えてください。 そもそも訓練のためのデータが用意できなければ、どんなに素晴らしい構造やタスクを思いついても、最終的にモデルが構築できないので意味がありません。 例えばあなたがアニメが大好きで、アニメキャラクターAとアニメキャラクターBの区別がCNNで付くのか試したければ、それぞれのキャラクターの画像を少なくとも何百枚かは用意しなければなりません。 しかも、どちらがどちらなのか、ファイル名、フォルダ分けなり、テキストファイルなりで区別できるような状態になっている必要があります。
 さらに、必要なのはこれだけではありません。訓練したら、結果としてどれくらい正解できるようになっているのかを測定できなければならないからです。 訓練をしたらそれでおしまいでは、万が一正しく訓練できていない場合、いざ実用の段階に入った時に全く分類ができていないという悲惨な結果が待っているかもしれません。 したがって、訓練データ同様に、CNNの性能を見るため、入力データと正解データの組をある程度の数は別途保持しておく必要があります。この正答率を見るためのデータをテストデータといいます。 テストデータの用意の仕方は2種類考えられます。まずは単純に大量にある訓練データの中から一部(10%〜20%くらい)を拝借してそれらをテストデータに作り変えることです。これは簡単です。 もうひとつは、全く別のデータセットを用意することです。基本的には前者のアプローチでいいのですが、場合によっては後者の方法が適切な場合もあります。
 例えば、あるアニメシリーズにおけるキャラクターAとキャラクターBの分類をしたいとき、第1期と第2期で製作会社が変わって全く絵柄も変わったとします。このような場合、第1期の映像からだけ 2キャラクターを持ってきて訓練データとテストデータを作ると、確かにテストデータに対する正答率は訓練により高まっていくのですが、 それで分類器ができたと思い込み、いざ第2期の同じキャラクターの画像を入れると、絵柄が大きく違うためにほとんど正しく分類できないという現象が生じる場合があります。 このように、訓練データ(またはそれを流用したテストデータなど)にしか成果を発揮できず、それ以外のデータに対しては成果が低くなってしまう現象を過学習(オーバーフィッティング)といい、 このようなおそれがある場合は全く別のデータセットをテスト用として用意するのが無難です。

この項のまとめ

手書き文字分類とは

ここでは、1989年にY.LeCunらによって提案されたLeNetという、元祖CNNとでもいうべきニューラルネットを提案した論文における目標であった「手書き文字分類」を、厳密な仕組みは若干違いますがLeNet同様のCNNを構築することで行います。 ちなみに、CNNが本格的に注目されるようになったのは2012年ごろになってからです。なぜそんなにすごいものが放置されてきたのかと思うかもしれませんが、もともとCNNの構造そのものはこの時代から何ら変わっておらず、 変わったのは大量のデータが手に入るようになったこととコンピュータの処理能力が大幅に上がったことです。「時代が追い付いてきた」というのが現状を説明するのに適切な表現かもしれません。
 この手書き文字分類では、以下のような28x28ピクセルの正方形でできている手書き文字画像が0から9のどれなのか分類することを目標とします。
mnist.png
これは8枚の画像を横に連結しているのですがそれぞれ5, 0, 4, 1, 9, 2, 1, 3であることが理解できます。このような手書き文字分類を行う際には、 先ほど説明したように、0〜9の10種類の手書き文字画像、およびそれに対応する正解データを大量に用意する必要があります。 そこで、その手間を省くため、世の中には様々なタスクに応じた「データセット」と呼ばれるものが転がっています。 何かやりたいと思いついた時は、まずそのやりたいことにふさわしいデータセットが無料で手に入らないか探しましょう。なければ残念ですが自分で作らなければなりません。 先程も書きましたが、どういう構造にしたらいいかなどは後回しであり、データセットの目処がたった後です。 実は、ニューラルネットワークの世界では、コンピュータで計算するくらいなので、訓練するためのアルゴリズムはきっちりと定まっているのですが、なぜそれが良いのか、どのような構造なら最も良いのかという本質的な部分については理論的に解明されているわけではありません。 何が言いたいかというと、新しい方法やタスクを思いついたとしても「やってみなければ分からない」、言い換えれば試行錯誤的な側面が非常に強く、それを検証するには訓練するためのデータがなければならないということであり、データセットのことは常に念頭に置いて欲しいということです。
 手書き文字分類においては、幸い上の画像のような28x28の手書き文字画像が訓練データ60,000枚、テストデータ10,000枚収録されたMNISTと呼ばれるデータセットが存在するのでこれを使います。 LeCunらがもともとLeNetを学習するために使ったのもこのMNISTです。
その他、ディープラーニングの分野で非常に有名なデータセットとしては、A.Krizehvskyらが2012年に発表し、1000カテゴリの一般物体認識タスク(犬、猫、鳥・・・)の正答率を競うコンテストにおいて 非常に高い性能を示したことで注目されたAlexNetの訓練に使われた、Imagenetというデータセットがあります。これも一般の人が無料でダウンロードできますが、こちらは小規模バージョン(コンテスト用)ですら100GB近くあるので上級者向けです。

Caffeにおけるデータセットの扱い

ここからは、どのライブラリを使っていたとしてもCNNを手段にする限りは共通する一般論ではなく、Caffe特有の取り扱い方に入っていきます。 Caffeでは、より高速に、効率的に訓練を行うため、jpgやpngといった画像をそのままCNNに食わせるのではなく、LMDBという形式にデータセットを変換したものを与えます。 普通の画像を1枚ずつ食わせることもできますが、面倒だと思ったとしても、基本的には訓練・テスト用データセットにはLMDBを作るべきです。 正解データをテキストファイルとして記述したものと画像ファイルを用意しておくことで、LMDBは一行で作ることができますが、この作り方は別のチュートリアルで紹介します。 今回のMNISTデータセットに関しては、嬉しいことに、最初からLMBDが完成した状態でダウンロード可能なので、それを使うことにします。

MNISTデータセットの準備

 ここでは、 "/home/ユーザー名/caffe/" が Caffee のルートディレクトリ(一番上のフォルダ)だとしましょう。 各ユーザーの一番上の階層のフォルダが "/home/ユーザー名/" であり、普通はここに caffe がインストールされているはずです。 次の手順で、MNISTの生データ(LMDBになる前のデータ)を取り寄せます。 Ubuntuでは、ファイルの移動や削除といったレベルのことはWindowsと同じ感覚でできるものの、多くの作業は黒い画面(端末)で行うことになります。 sh とは、その黒い画面上で打ち込むコマンドを一連の処理として1つのテキストファイルにまとめたもので、シェルスクリプトと呼ばれています。 これを実行するための命令が sh というわけです。 "sh ファイルパス" でこのようなシェルスクリプトを実行できます。
 get_mnist.sh を実行してしばらく待つと、ダウンロードが完了して、get_mnist.sh と同じフォルダ(/home/ユーザー名/caffe/data/mnist/)に変なファイルが4つ登場します。
1.png
生データを取り寄せたら、次の手順を実行することにより、LMDBに変換します。これもスクリプトが適切な変換手順を実行してくれているのですが、 ここではどれも1回しか使わないので中身については気にせず、自動でなにかやってくれてるくらいの認識でも問題ありません。 手順としては、 cd というコマンドで caffe のルートディレクトリに移動します。その後、その中にある create_mnist.sh を実行しています。 なぜさっきは移動しなかったのに今回は cd で移動したかですが、単純に create_mnist.sh が、現在参照しているディレクトリが Caffe のルートであることを前提に組まれているというだけのことです。 以下のような画面が出たら正常にLMDBが生成されました。
myusername@myusername:~$ cd caffe
myusername@myusername:~/caffe$ cd /home/ユーザー名/caffe/
myusername@myusername::~/caffe$ examples/mnist/create_mnist.sh
Creating lmdb...
Done.
このように、 create_mnist.sh があるフォルダである /home/ユーザー名/caffe/examples/mnist/ に行ってみると、 mnist_test_lmdb というフォルダと mnist_train_lmdb というフォルダができていることがわかります。 それぞれが名前の通りテスト用のLMDB、訓練用のLMDBです。このLMDBを、わかりやすい場所にコピペします。今回は、 /home/ユーザー名/mycnn/ というフォルダで一連の作業をしたいことにしましょう。
この2つのフォルダを選択して右クリックし、「コピー」を選びます。
2.png
今回、CNNを構築するために作った作業フォルダ /home/ユーザー名/mycnn/ に移動し、右クリックして「貼り付け」を選ぶことで、貼り付けます。
3.png
これでMNISTのデータをLMDB化したものを調達することに成功しました。自分でデータセットを作る際でも、訓練用、テスト用と2つのLMDBを作る必要があります。 同じLMDBを指定してしまうと、Caffeでいざ訓練をするという時、テスト、訓練で同じファイルを2度同時に開こうとしてしまうためにフリーズします。

今回のまとめ

今回は、ディープラーニングにおけるデータセットの重要性を説明しました。また、LeNetというCNNの祖先が目標とした手書き文字認識のタスクを追体験するため、LeNetが使ったのと同じデータセットであるMNISTをダウンロードしました。 次に、Caffeを訓練する際には画像ではなくLMDBというファイルに変換して行うことが好ましいことを紹介し、MNISTのデータをLMDB形式で訓練用、テスト用と作成しました。

その他の記事

コメント

名前 :
電子メール :
URL :
コメント