「エアコン消したっけ？」をAIでなくそう！

#1.概要
CNNをつかって、家のエアコンのオン・オフを見分けるAIをつくりました。


#2.はじめに

Aidemyで「[ディープラーニングで画像認識モデルを作ってみよう！](https://aidemy.net/routemaps/1)」の受講ルートを勉強しました。なにかアウトプットをしようと思って、この記事を書きました。

ぼくはエアコンのスイッチを消したか覚えてなくて気になることが多いです。そこで、AIでエアコンのオン・オフを判別できたら便利だなと思い作ってみました。

強迫性障害のひとにとってはすごく大事な問題です。友達に強迫性障害のような症状をもっているひとがいて、「ドアのカギを何度も確認したくなって辛い」と言っていました。

>強迫性障害では、自分でもつまらないことだとわかっていても、そのことが頭から離れない、わかっていながら何度も同じ確認をくりかえしてしまうことで、日常生活にも影響が出てきます。意志に反して頭に浮かんでしまって払いのけられない考えを強迫観念、ある行為をしないでいられないことを強迫行為といいます。たとえば、不潔に思えて過剰に手を洗う、戸締りなどを何度も確認せずにはいられないといったことがあります。

（[強迫性障害　厚生労働省](https://www.mhlw.go.jp/kokoro/know/disease_compel.html)を参照）

#3.準備

##3.1写真を撮る
自分の家のエアコンのオン・オフを見分けたいので、オン・オフの写真をそれぞれ300枚ずつ撮りました。

また、エアコンの前にカメラを取り付けて実用化もしたいと思っています。だから、カメラを取り付けられそうなエアコン前の天井付近からの写真だけにしました。

| ON | OFF |
|:-:|:-:|
| ![IMG_0001.JPG](https://qiita-image-store.s3.amazonaws.com/0/257093/87d01e3a-809e-efee-d11f-b24108e67f2e.jpeg)| ![IMG_0133.JPG](https://qiita-image-store.s3.amazonaws.com/0/257093/82f7b797-0cc0-a175-f564-519463452588.jpeg) |

##3.2実行環境
GPUが無料で使えるGoogle Colaboratory上で実行しました。GPUをつかうとCPUより数十倍も学習速度が速くなりとても便利です。

#4.コード
ひとによって変わりそうなところだけ載せました

##4.1画像を行列表示に変換

Udemyの[【画像判定AI自作にチャレンジ！】TensorFlow・Keras・Python・Flaskで作る機械学習アプリ開発入門](https://www.udemy.com/share/1004c0BEEdeVxaTHw=/)で勉強しました。

```python:generate.py
classes = ["on", "off"]
num_classes = len(classes)
image_size = 100

##画像の読み込み

X = []
Y = []
for index, classlabel in enumerate(classes):
        photos_dir = "./" + classlabel
        files = glob.glob(photos_dir + "/*.JPG")
        for i, file in enumerate(files):
                if i >= 301: break
                image = Image.open(file)
                image = image.convert("RGB")
                image = image.resize((image_size, image_size))
                data = np.asarray(image)
                X.append(data)
                Y.append(index)

X = np.array(X)
Y = np.array(Y)
```

##4.2 CNN

Aidemyの「[CNNを用いた画像認識](https://aidemy.net/courses/5100)」で勉強したものを少し変えています。

```python:cnn.py

model = Sequential()
model.add(Conv2D(32,(3,3), padding='same', input_shape=X_train.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(Dense(num_classes))
model.add(Activation('softmax'))

opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])

model.fit(X_train, y_train, batch_size=16, epochs=2, verbose=1)
```

#5.結果

![kekka.png](https://qiita-image-store.s3.amazonaws.com/0/257093/f047a2db-4ed4-746b-2518-49592dccf0af.png)
450枚の画像で学習して150枚の画像でテストしたところ、正解率は97.3%でした

![kekka2.png](https://qiita-image-store.s3.amazonaws.com/0/257093/7d505b8e-2fbe-94d0-da59-228d9bb4cd7b.png)
テスト画像の最初の10枚で結果を確認すると、すべて正解でした。(0がオンで、1がオフ)
写真が小さくてすみません

<!--
- 自分の家のエアコンだけじゃなく、どのエアコンの画像でもオン・オフを判別できるようにしたい
- 標準化、白色化、バッチ正規化、転移学習もしたい
- カメラを取り付けて家にいなくても判定できるようにしたい
- GAN（敵対的生成ネットワーク）を勉強中なので、エアコンの画像をAIで生成してみたり、それを使って精度をよくしたい
-->

#6.おわりに
エアコンの吹き出し口が開いてるか閉じてるかだけのちがいだったので、見分けるのは難しいかなあと思っていましたが、結構いい精度になりました。ほとんど同じ位置からの写真だったので簡単だったのかもしれません。

QiitaやTwitterに感想やアドバイスなどのコメントをいただけると嬉しいです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">家のエアコンのオン・オフを見分けるAIをつくりました❗️<br><br>これでエアコンを消したかどうか気になって家に戻ることはなくなります<br><br>人生ではじめての記事をQiitaに書いてみました<br>拡散してもらえると嬉しいです😊<a href="https://twitter.com/hashtag/Aidemynote?src=hash&amp;ref_src=twsrc%5Etfw">#Aidemynote</a><br>「エアコン消したっけ？」をAIでなくそう！ <a href="https://t.co/ptay5WIbNM">https://t.co/ptay5WIbNM</a> <a href="https://t.co/stSiAbsUeD">pic.twitter.com/stSiAbsUeD</a></p>&mdash; IT暇人@AIプログラマ,ニート (@it31415) <a href="https://twitter.com/it31415/status/1031077777003311104?ref_src=twsrc%5Etfw">2018年8月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>