はじめに
カラスが嫌いな友達のために、画像判定AIを使って、カラスを発見したらslackに「カラス来たぞ~!!!」と通知してくれる、特に役立たなそうなものを作りました。
ゴミ捨て場などにカラスがたまっていたら「カラスがいる!」ということをslackで教えてくれ、ごみ捨てに行く心の準備ができるもの。くらいに考えています(笑)
本当は、実際にストリーミングをとっているカメラが、カラスを発見したらslackに通知するという流れでやりたかったですが、カメラの部分はまたの機会にということで・・・。余裕があればやります。カメラの方も。
Udemyの【画像判定AI自作にチャレンジ!】TensorFlow・Keras・Python・Flaskで作る機械学習アプリ開発入門を参考に分類器を作り、評価の値にカラスを検出したらslack通知をするという構造にしています。
CNNに関する内容は、Udemyの【画像判定AI自作にチャレンジ!】TensorFlow・Keras・Python・Flaskで作る機械学習アプリ開発入門を参考にしていただくか、
「エアコン消したっけ?」をAIでなくそう!をご参考ください。
この記事では、評価結果からslackに流す部分をメインに記述しております。
ちなみに
Udemyの【画像判定AI自作にチャレンジ!】TensorFlow・Keras・Python・Flaskで作る機械学習アプリ開発入門をお作りいただいた井上 博樹さんに感謝です。お勧めです。
内容
画像を事前に学習させたのちに、分類器にかけ、その画像がカラスかどうかを判定するという内容です。
内部
■モデルの形成とロード
model_train()で、モデルを形成して「cnn.h5」という名前でモデルを保存します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
def model_train(X, y): model = Sequential() model.add(Conv2D(32, (3, 3),padding='same',input_shape=X.shape[1:])) 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')) opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6) # Let's train the model using RMSprop model.compile(loss='categorical_crossentropy',optimizer=opt,metrics=['accuracy']) model.fit(X, y, batch_size=32, epochs=100) # モデルの保存 model.save('./cnn.h5') return model |
以下のload_model()で、保存したモデルをロードします。
1 2 3 4 |
def load_model(): # モデルのロード return load_model('./cnn.h5') |
■分類器の結果をslackに通知
slackへの通知方法はググれば出てくるので、ここでは省略します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# slackへ通知 def notify_slack(urlToHook, message): slack = slackweb.Slack(url = urlToHook) slack.notify(text = message) def main(): # slackへ通知するためのWebhookのURL url_to_hook = "hogehogehogehogehoge" image = Image.open(sys.argv[1]) image = image.convert('RGB') image = image.resize((image_size, image_size)) data = np.asarray(image)/255 X = [] X.append(data) X = np.array(X) model = load_model() result = model.predict([X])[0] predicted = result.argmax() percentage = int(result[predicted] * 100) # 80%以上似ているならカラスで通知 if percentage > 80 and classes[predicted]=="crow": message = "それはカラスだ率" + str(percentage) + " %" + "つまりカラスだそいつは" else: message = "カラスじゃねー。安心しろ" notify_slack(url_to_hook, message) |
実験
では早速、カラスを分類器に入れてみて、カラスかどうか教えてもらいます。
として、カラスの画像を引数にして、分類器に投げます。
お。うまくできてますね。
カラスらしいです。
ちなみに判定に使った画像はこんな感じです。
では、まったく違うサルの画像では?
として、サルの画像を引数にして、分類器に投げます。
お。うまくできてますね。
まあゴミ捨て場にサルいた方が安心できませんがね。
ちなみに判定に使った画像はこんな感じです。
じゃあカラスに似ているやつは?
として、鷹?鷲?の画像を引数にして、分類器に投げます。
ん?カラスではないのだが・・・。
ちなみに画像は・・・なんだろう、鷹かな?鷲?
ちなみに判定に使った画像はこんな感じです。
下の画像はおじさんがいますが、おじさんがいない下のような鷹を使いました。
しかも、ファイル名にbird3って・・・
鳥大好きな人に怒られそうなファイル名の付け方でした。
すみません。
結論
ということで、モデルを定義する前処理と画像の枚数やその質によって、値がだいぶ変わるみたいです。
まだまだ自分も勉強中ですので、精度を高くして頑張ります。
さらに、実際のカメラから即時に判定してSlack通知とかやれたらやります。
参考
・【画像判定AI自作にチャレンジ!】TensorFlow・Keras・Python・Flaskで作る機械学習アプリ開発入門
・「エアコン消したっけ?」をAIでなくそう!