初心者がAIアプリ開発講座を終えて

#はじめに
私は汎用系のサーバ保守を仕事としているSEですが
開発経験は全くなく、SEとして開発言語に触れていないことに
後ろめたさを感じていたため今回アイデミーのAIアプリ講座を受けることにしました。
※技術的に詳しいブログは山ほどあると思うので所感をメインに書きたいと思います。

##本記事の概要  
* 全くの初心者がAIアプリ開発講座を受けての率直な感想
* 当初想定していた到達点とのギャップ
* 作成した成果物と反省点
* 今後の課題


###1.全くの初心者がAIアプリ開発講座を受けての率直な感想　　
講座自体は非常にためになるものであって受けて損はないというのが正直な感想です。
しっかり言語の入門から始まりますし、段階を踏んでステップアップしていくのが
自分でも体感できていました。ただし注意しなくてはいけないことは、、、、
**絶対に受け身になってはいけないこと！！**
これは非常に重要だと感じました。というのも特に初心者の方はいわゆる業界用語に
慣れていないため、講座で飛び交う用語がよくわからないと思います。
特に機械学習分野では**不明な用語は自分で調べながら講座を受ける**スタイルを
徹底して受けないとよくわからないまま進んでしまうので要注意だと感じます。
そしてお金に余裕がある方はぜひ**6ヶ月コース**をお勧めします！
私は昼間働きながら受講しましたが3ヶ月ではなかなか厳しく感じました。

###2.当初想定していた到達点とのギャップ　　
受講前は**受けきれば1人前！！**と思っていましたが
現実はそう甘くないなと感じました。
そして**受講後にどれだけ自分で触っていけるか**が重要だと思います。
というのも感覚をあけて受講すると前回の単元の内容を忘れてしまい
また復習から始めないといけないんですよね。するとスケジュールが
どんどん遅れていき、結果ギリギリになってしまいます。
とにかく毎日触る！
**習うより慣れろ**が開発には必要なことだと痛感しました。
結論として受講後も趣味でAIアプリを作成するか
同じ技術を必要とする仕事に就くことをおすすめします。

###3.作成した成果物と反省点　　
私はファッションアイテムを画像で識別するアプリを作成しました。
いわゆるFashion Mnist？と呼んで差支えないと思いますが
あまり時間がなくて精度の高いものを作れませんでした。。。。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1592786/44939002-22da-6f3e-a212-b36a836d2836.png)

仕組みとしては単純です。
スニーカーやシャツの画像を分類するニューラルネットワークモデルを訓練させ
TensorFlowを使ってモデルを構築しました。

データセットは以下を使用
keras.datasetsを使ってデータをロードさせました。

```
fashion_mnist = keras.datasets.fashion_mnist
 
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
```

訓練させる前にピクセル値が0から255に収まるようにデータを前処理しました。

####ピクセル値の確認
```
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
```
####0と1の範囲にスケール
```
train_images = train_images / 255.0
test_images = test_images / 255.0
```
あとは層をセットアップしてモデルをコンパイルして訓練してと続いて行きます。
今回はFlask入門で学習した内容を参考にして書きましたので教材と同じように
モデルを作成して重みを保存します。
では上記のコードを含めた全体のソースはこちらです。

###モデル作成・構築のソース
```
from __future__ import absolute_import, division, print_function, unicode_literals
from keras.models import Sequential, load_model
from tensorflow import keras
from google.colab import files
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
 
print(tf.__version__)

#学習データのロード
fashion_mnist = keras.datasets.fashion_mnist
 
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

#クラス名を指定
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

#データの前処理
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

train_images = train_images / 255.0
test_images = test_images / 255.0


plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

#モデルの構築
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

#モデルのコンパイル
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

#モデルを訓練させる
model.fit(train_images, train_labels, epochs=10)

#精度の評価
test_loss, test_acc = model.evaluate(test_images, test_labels)
 
print('\nTest accuracy:', test_acc)

#予測
predictions = model.predict(test_images)

#resultsディレクトリを作成
result_dir = 'results'
if not os.path.exists(result_dir):
    os.mkdir(result_dir)
# 重みを保存
model.save(os.path.join(result_dir, 'model.h5'))

files.download( '/content/results/model.h5' ) 

```

そして実際に判定する画像をnumpyの配列形式に変換したのち
先述のソースで作成したモデルに値を渡して予測を実施し結果を返すところまでを
以下のソースで実施してみました。

###画像判定のメインソース
```
import os
from flask import Flask, request, redirect, render_template, flash
from werkzeug.utils import secure_filename
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.preprocessing import image

import numpy as np


classes = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
image_size = 28

UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

model = load_model('./model.h5')#学習済みモデルをロード


@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('ファイルがありません')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            flash('ファイルがありません')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(UPLOAD_FOLDER, filename))
            filepath = os.path.join(UPLOAD_FOLDER, filename)

            #受け取った画像を読み込み、np形式に変換
            img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
            img = image.img_to_array(img)
            data = np.array([img])
            #変換したデータをモデルに渡して予測する
            result = model.predict(data)[0]
            predicted = result.argmax()
            pred_answer = "これは " + classes[predicted] + " です"

            return render_template("index.html",answer=pred_answer)

    return render_template("index.html",answer="")


if __name__ == "__main__":
    port = int(os.environ.get('PORT', 8080))
    app.run(host ='0.0.0.0',port = port)
```

個人的な反省点はモデルの精度もそうですが
時間があれば***見栄えももっとこだわりたかった！！***
個人的に服のデザインとかもやっていてAdobe系のソフト使えるので
見栄えもこだわりたいですね。***美しいwebデザインで精度の高いＡＩを実装したかった。***
これが最大の反省点です。
ただ諦めていません。受講期間が終わっても合間縫っていろいろ試したいと思いました。


###4.今後の課題
モデルの構築とその評価が課題かなと個人的には感じています。
というのもまだ調べながら作業しないとどんなモデルが最適か
すぐに選択・想像ができないからです。
そこが当初想定していた到達目標でしたが
今後はそこに到達できるようにこの講座を活かしていきたいと思います。

#最後に
開発未経験の私が開発の雰囲気とさらに今熱いＡＩ分野を学習できたことは
非常に良かったと思います。
ぜひ受講を検討されている方がいればまずは飛び込んで見てほしいなと思います。
※長年開発アレルギーでしたが仕組みを知るだけで世界が変わりました。
乱文ですが最後まで読んで頂きありがとうございました。