人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

CIFAR-10

MNISTの数字画像はそろそろ飽きてきた(笑)ので一般物体認識のベンチマークとしてよく使われているCIFAR-10という画像データセットについて調べていた。

f:id:aidiary:20151014211729p:plain

このデータは、約8000万枚の画像がある80 Million Tiny Imagesからサブセットとして約6万枚の画像を抽出してラベル付けしたデータセット。このデータセットを整備したのは、SuperVision(またはAlexNet)と呼ばれる畳み込みニューラルネットワークを使ってILSVRC2012で優勝したAlex Krizhevskyさんとのこと。こういう泥臭い仕事もしていたなんて尊敬する。

CIFAR-10の元となる80 Million Tiny Imagesは類似画像検索(2009/10/3)で少し言及したことがあった。初出はこの論文(PDF)だと思うけれど、最初に読んだときいろいろな画像があってとてもわくわくし、いつか使ってみたいと思った覚えがある。今回は類似画像検索ではなく、Deep Learningを使った一般物体認識が主目的。だけど隠れ層の圧縮データを使って類似画像検索もできるらしいので後で試してみたい。

CIFAR-10の特徴

特徴をまとめておこう。

  • 80 million tiny imagesのサブセット
  • 全部で60000枚
  • 画像サイズは32ピクセルx32ピクセル
  • RGBの3チャンネルカラー画像
  • クラスラベルはairplane, automobile, bird, cat, deer, dog, frog, horse, ship, truckで10クラス
  • 50000枚(各クラス5000枚)の訓練画像と10000枚(各クラス1000枚)のテスト画像に分割されている
  • クラスラベルは排他的
  • PythonのcPickle形式で提供されている

最後が重要。BMPやPNGといった画像ファイルが60000枚提供されているわけではなく、ピクセルデータ配列としてPythonから簡単に読み込める形式で提供されている。Python使い歓喜!

逆に言うとピクセルデータしか提供されていないので人の目に見える画像として表示するには一手間かかる。人工知能がものを「見る」ためにはピクセルデータの数列さえあればよいが、人間が見るためにはそういうわけにはいかない。というわけで今回はこの画像セットをロードして画像として描画するところまでやってみたい。

CIFAR-10のCIFAR-10 python versionをダウンロード。tarで解凍すると

  • batches.meta - ラベル名のリスト
  • data_batch_1 - 訓練画像(1万枚)
  • data_batch_2 - 訓練画像(1万枚)
  • data_batch_3 - 訓練画像(1万枚)
  • data_batch_4 - 訓練画像(1万枚)
  • data_batch_5 - 訓練画像(1万枚)
  • test_batch - テスト画像(1万枚)

というファイルが出てくる。訓練画像は1万枚ずつ別のファイルになっている。全部、PythonのcPickleのバイナリダンプ形式のためcPickleモジュールでロードできる。ロードするとPythonのlistdictnumpy.ndarrayのオブジェクトとしてすぐに使える。ファイルをロードするにはホームページに記載されている通り下の関数でできる。

多くはdict形式なのでkeys()でどんなデータが格納されているか簡単に調べられる。

CIFAR-10の描画

data_batch_1の1万枚の画像から各クラス10枚の画像をランダムに描画してみよう。実行するたびに違う画像が表示される。

Pythonで描画するときはmatplotlibのimshow()が使える。ただし、RGBの3チャンネルの画像を描画するには、ndarray(row, column, channel) の順番に並び変える必要がある。これをやっているのが

plt.imshow(img.reshape(3, 32, 32).transpose(1, 2, 0))

のコード。オリジナルの画像はchannel(3チャンネル)、row(32ピクセル)、column(32ピクセル)のフラット形式3*32*32=3072次元ベクトルの形で格納されている。そのため、まずreshape()を使って([0]channel, [1]row, [2]column)の3次元arrayに変換している。これをimshow()で読める([1]row, [2]column, [0] channel) の順番に変更するためにnumpyのtranspose()を使って次元を入れ替えている。ちなみにChainerで画像を読み込む場合は(channel, row, column)の順番でよいらしいので元のままでOK。

実行するとCIFAR-10の元サイトにあるような画像が描画できる。

f:id:aidiary:20151014200947p:plain

上から飛行機、自動車、鳥、猫、鹿、犬、蛙、馬、船、トラックである。解像度がピクロスレベルの32x32しかないためすごく識別しにくいが何となくわかる。どうしてこの10種類のクラスを選んだのかはっきりしないけれど、動物と乗り物が好きだったのかな?(笑)

次回は、与えた画像が10種類のどのクラスかを当てる一般物体認識と呼ばれるタスクを畳み込みニューラルネットワークで解いてみたい。

参考