未経験が3時間で「AIを知っている」から「AIを作れる」に進化する方法。～爆速でAIエンジニアになる方法～

急に朝礼をお願いされたので書きました。
感謝ですね。


##はじめに
①「人工知能ってなんか凄いよね！ディープラーニングで畳み込みだよね？」
②「AIを使って学習から画像認識を行い分類推論を行うアプリケーションを作成できます」

①と②の間には大きな壁がありますが、この記事を見れば3時間で②の状態に到達できます。
プログラミング未経験でも大丈夫。技術的な事は書きません。というかあんまり知りません。
コピペしましょう。




使用技術
・python
・Teachable Machine
・ngrok
・MessagingAPI


用意するもの
・windowsPC
・ネット環境
・時間



##流れ
AIアプリ開発で面倒なのは、サーバーの構築とフロントだと思います。
そこで今回はngrockを使い爆速でサーバーを構築。
LINEのMessagingAPIを使用する事で爆速でフロントを構築します。
ゴールはこんな感じ。




![IMG_6126.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/11b12e78-e0d6-655f-0fd5-8b7fbc3ea4c2.png)

##①画像準備
Teachable Machineを使って教師データを作成します。
Teachable Machineとはgoogleが開発した画像認識のモデルをノーコードで作成してくれるアプリです。
モデルはダウンロードできるので他の環境で使用できますし、アップロードすればAPIとしてアクセスする事も出来ます。


事前準備としてAIに教える為の画像が必要になります。例えば犬と猫を判別したい場合は10～30枚ずつあればよいかと思います。
余裕がある方は更に、他の画像を用意しても面白いと思います。
写真はなんでも良いのですが、手持ちがない方はフリー素材のサイトから入手して下さい。著作権に触れる行為はお気をつけ下さい。




##②モデル構築
https://teachablemachine.withgoogle.com/

![FireShot Capture 005 - Image Model - Teachable Machines - teachablemachine.withgoogle.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/0da1658f-ead7-3918-a636-69ed15d72098.png)

URLにアクセスして→「使ってみる」→「画像プロジェクト」を選択します。
画像分類をするので、アップロードをクリックして画像をアップロードして下さい。
30枚ぐらいあると良いですが、10枚でも結構いけます。
今回は猫と犬の画像を教師データとして使用しますのでクラス分けを犬と猫にします。


##②モデルダウンロード

アップロードが終わったらトレーニングを押して（ちょっと時間かかります）エクスポートモデルを選択して下さい。
そうすると下の画像の画面になるので、「Tensorflow」と「savedmodel」を選択して「モデルをダウンロード」を選択して下さい。
これで分類モデルの完成です。簡単ですね。ダウンロードしたモデルは「model.savedmodel」という名前で保存されていると思います。
また後で使います。

![FireShot Capture 025 - Image Model - Teachable Machines - teachablemachine.withgoogle.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/44397df7-0751-3c7f-bf7a-9f095bd485fd.png)


##③フォルダの準備
imagebotとか好きな名前を作成してディレクトリを作成します。
直下に先ほど作成した「model.savedmodel」を配置します。
同じくpythonファイルも準備しますので、テキストファイルを開いてimagebot.pyと名前を変更して下さい。
拡張子がpyであれば名前は何でも良いです。





##④LINE公式アカウント作成
フロントとなるLINEを準備します。LINEディベロッパーツールから適当に作成しましょう。
作成したら「チャネルアクセストークン」「チャネルシークレット」を保存しておきます。後で使います。

![FireShot Capture 019 - LINE Developers - developers.line.biz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/cf71ab75-08de-4a05-6440-c1f7af2ef83e.png)







##⑤pythonのインストールと必要なライブラリのインストール
※爆速で行う為、依存関係完全無視です。今後も開発等行うPCの場合はVenvやanaconda等で開発環境を作成して下さい。
下記からpythonをインストールします。バージョンは3.7にして下さい。
https://www.python.org/


コマンドプロンプトを起動して、必要なライブラリをインストールします。

``` 
pip install line-bot-sdk==1.8.0
pip install TensorFlow==2.2.0
pip install　Flask==1.1.2
pip install numpy==1.18.1
```


##⑥プログラム作成
imagebot.pyに以下のコードを貼り付けます。
「チャネルアクセストークン」と「チャネルシークレット」は③で保存した値に置き換えてください。
※tensorflowでモデルをロードしておいて、Flaskでサーバーを立ち上げています。
line-bot-sdkを使って画像が来たら推論をして、結果をテキストで返しています。



```python
import numpy as np
from PIL import Image, ImageOps
import tensorflow
from flask import Flask, request, abort
import os
import numpy as np
from pathlib import Path
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, ImageMessage
)
app = Flask(__name__)
imagepath = ""

#自分のLINE botのデータを設定する。
line_bot_api = LineBotApi('チャネルアクセストークン')
handler = WebhookHandler('チャネルシークレット')

# 署名検証とエラー処理
@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'
@handler.add(MessageEvent)
def handle_message(event):
# # これやらないとテストの時にエラー起きるらしい。
    if event.reply_token == "00000000000000000000000000000000":
        return
    line_bot_api.reply_message(event.reply_token,TextSendMessage(text='爆速なのでテキストには対応していません！ごめんなさい。画像を送ってね！'))
@handler.add(MessageEvent, message=ImageMessage)
def handle_image(event):
    message_id = event.message.id
    imagepath=f"{message_id}.jpg"
    # message_idから画像のバイナリデータを取得
    message_content = line_bot_api.get_message_content(message_id)
    with open(imagepath, "wb") as f:
        for chunk in message_content.iter_content():
            f.write(chunk)
    image = Image.open(imagepath)
    size = (224, 224)
    image = ImageOps.fit(image, size, Image.ANTIALIAS)
    image_array = np.asarray(image)
    normalized_image_array = (image_array.astype(np.float32) / 127.0) - 1
    data[0] = normalized_image_array
    #丸め関数
    def round_func(x):
        return round(x*100, 5)
    prediction = model(data).numpy()
    res_text = f"この画像が猫の可能性は\n{round_func(prediction[0][0])}%です！\n犬の可能性は\n{round_func(prediction[0][1])}%です！"
    line_bot_api.reply_message(event.reply_token, TextSendMessage(
        text=res_text))

#モデルロード
np.set_printoptions(suppress=True)
export_dir = 'model.savedmodel'
model = tensorflow.saved_model.load(export_dir)
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)


if __name__ == "__main__":
    app.run()
```



##⑦サーバーを構築します。
AWSやherokuやら時間がかかるサーバー構築も爆速です。なぜならngrokを使います。
あなたのPCが今からWEBサーバーです。使い方は下記のURLが分かりやすいです。
https://qiita.com/mininobu/items/b45dbc70faedf30f484e


今回はFlaskを使っているので、5000を開放します。

```
ngrok http 5000
```

成功すると以下の画面になりますので、URLをコピーしましょう。
HttpsのURLじゃないと動かないです。LINEの仕様です。


```
Session Status                online 
Account                       登録したアドレス (Plan: Free)
Version                       2.3.35 
Region                        United States (us) 
Web Interface                 http://127.0.0.1:4040                                                                     
Forwarding                    http://生成されたURL.ngrok.io -> http://localhost:5000 
Forwarding                    https://生成されたURL.ngrok.io -> http://localhost:5000   

```


⑦LINEにURLを登録
画像を参考にさっきコピーしたURLをペーストして下さい。その後設定のチェックをします。
下記と同じにしましょう。

〇公式アカウント管理画面から
・応答モード→BOT
・WEBhook→オン
・応答メッセージ→オフ
〇developers管理画面から
・Webhookの利用→オン



![FireShot Capture 022 - LINE Developers - developers.line.biz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/bc8fe29e-7a7c-80cd-481c-465f001e337e.png)




##⑧完成！お疲れ様でした。
![FireShot Capture 028 - LINE Developers - developers.line.biz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337456/3fb59cb0-42bf-fa26-21c3-a7c80f981dbf.png)

developers管理画面のMessagingAPI設定から自分のLINEアカウントのQRコードが見れるので、追加して画像を送信してみましょう！
うまく返してくれたら成功です。




##まとめ
物理学者リチャード・ファインマンは「自分が作れないものは理解できない」と名言を残しています。
手軽に人口知能を体験して理解を深めて頂ければ幸いです。


※記事も爆速で書いています。コードのミスなどありましたら修正致しますのでご指摘下さい。