前回の記事では、データセットの中身を確認しました。
この記事では、ディープラーニングを使って「ながら運転」の分類分けをしていきたいと思います。
ラベルはC0からC9までありそれらを分類する問題です。
データセットはkaggleにあったものを使用します。
コードの流れは以下の通り。
- ファイル名の取得
- 画像の読み込み
- 前処理
- モデルの構築
- 機械学習、テスト
順番に見ていきたいと思いまーす。
目次
ファイル名の取得
画像の枚数は2万2千枚ほどありましたが、全部使うとかなりメモリを使用するので、1カテゴリあたり400枚(全部で4000枚)を使うことにします。(なにせ私のPCはメモリ16GB)
Pythonのパッケージglobの便利なところは、枚数を指定して読み込めるところですね。
base_dir = "./train" category = ["c0","c1","c2","c3","c4","c5","c6","c7","c8","c9"] files=[] for c in category: mypath = base_dir + "/" + c + "/*.jpg" files.extend(glob.glob(mypath)[:400])
こんな感じでglobの後に[:400]と指定することで、各カテゴリ400枚だけピックしてリストに追記しています。
画像の読み込み
OpenCVで画像を読み込みますが、その際にBGRからRGBに変換し、画像サイズを縦・横それぞれ1/4にしています。
(最初1/2サイズでやっていたのですが、途中でメモリエラーが出たのでやめました。)
最後にnumpyの配列に変換してます。
カテゴリー名はラベルとしてyに追加していきます。
X = [] y = [] for i in files: img = cv2.imread(i) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img,(120,160)) X.append(img) category = i.split("/")[2] y.append(category[1]) X = np.array(X) y = np.array(y)
訓練画像とテスト画像に分割します。
from sklearn.model_selection import train_test_split import keras X_train, X_test,y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
4000枚のうち、訓練画像は80%、テスト画像は20%にすることにしました。
前処理
画像をintからfloatに変換します。
ちなみに、intからfloatに変換する際にメモリが十分足りておらずOOM(Out Of Memory)エラーが何度か発生しました。
その場合には、画像サイズを小さくするなり、枚数を減らすなりの工夫を行う必要があります。
ラベルはワンホットベクターに変換します。
num_classes = 10 X_train = X_train.astype('float32') / 255 X_test = X_test.astype('float32') / 255 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes)
モデルの構築
畳み込みニューラルネットを組みます。
畳み込み4層からなるシンプルなネットワークです。
height = 120 witdh = 160 in_shape = (witdh,height,3) model = Sequential() model.add(Conv2D(32, (3, 3), padding='same', input_shape=in_shape)) model.add(Activation('relu')) model.add(Conv2D(32, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Conv2D(64, (3, 3), padding='same')) model.add(Activation('relu')) model.add(Conv2D(64, (3, 3))) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes)) model.add(Activation('softmax'))
機械学習、テスト
学習を行ってその後に評価を行います。
model.compile( loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) hist = model.fit(X_train, y_train, batch_size=32, epochs=50, verbose=1, validation_data=(X_test, y_test)) score = model.evaluate(X_test, y_test, verbose=1) print('正解率=', score[1], 'loss=', score[0])
正解率= 0.98375 loss= 0.09991514410969103
98.37%!
そこそこ良い正解率が出ました。
事故を防止するために、車の中にカメラを積んでAIが監視するなんて未来が来るかもしれませんね。
人間がAIに監視されるなんて考えただけで嫌ですが。
おわり。