LoginSignup
13
16

More than 5 years have passed since last update.

KerasでImageNetのハンバーガーと自転車を分類した

Posted at

ImageNetから取得した画像でデータセットを作って、分類してみた。

同じコードで、何故かうまく行く時と、そうでない時があって原因はよくわからない。1
notebookはこちら:https://gist.github.com/juntaki/263d9c43c0509c6610bdf95a59867e99
以下はノートの解説です。

データのダウンロード

ImageNetで検索したURLリストを適当な場所に保存したら、画像をダウンロードする。
容量が異常に小さいものや、テキストファイルは失敗しているので捨てる。

cat ../urllist | xargs wget -T1

画像読み込み

Kerasに渡すにはRGB画像なら、[3(RGB), 50(縦), 50(横)]のようにする必要がある。
Image.open()で来たものは[50,50,3]となっているため、transpose()で順序を変更している。
引数は、[0,1,2]を[2,0,1]にするという意味。

    im_reading = np.array( Image.open(i).resize((50,50)))
    im_reading = im_reading.transpose(2,0,1)

データセット作成

さらに、Kerasに入力するには、[サンプル、3,50,50(RGB画像)]のnp.arrayにしなければならないので、
空の配列にappendしていく形でデータセットを作成した。pythonのarrayと違って、最初に行列サイズを定義してやる必要がある。また、画像のdtypeはuint8なので、unsignedで揃えないとimshow()でうまく画像として表示できなくなる(学習だけなら支障はなさそうだが)2

image = np.empty((0,3,50,50), dtype=np.uint8)
...
    image = np.append(image, [im_reading], axis=0)

画像表示

入れ替えた順序を戻すと、表示できる。

plt.imshow( image[number].transpose(1,2,0) )

データセット分割

scikit-learnにデータセットをトレーニング用とテスト用に分割する関数がある。
データセットは順番にappendしているので前後で綺麗にわかれてしまっているが、この関数を通せばランダムにピックアップして分割してくれる。

from sklearn.cross_validation import train_test_split
data_train, data_test, labels_train, labels_test = train_test_split(image, result, test_size=0.10, random_state=10)

モデルの定義と学習

モデルの中身はコンボリューション層とMaxpoolingを適当に重ねてみたもの。

model = Sequential()
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu" ,input_shape=(3, 50, 50) ))
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu"))
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu"))
model.add(Convolution2D(96, 3, 3, border_mode="same", activation="relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation("relu"))
model.add(Dense(10))
model.add(Activation("relu"))
model.add(Dense(2))
model.add(Activation("sigmoid"))
#model.summary()
model.compile(loss='binary_crossentropy', optimizer="adadelta", metrics=['accuracy'])

結果

2クラスの単純な分類だが、適当に選んだラベル付き画像を読み込んで、90%の精度を出せた。


  1. Kerasのバグ? 

  2. 読み込みにやたらと時間がかかるので、もっと良いやり方があるはず。格納のたびにメモリコピーが発生してしまっているかも、未確認。 

13
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
16