【初心者】Aidemy AI画像認識アプリ開発コースの振り返り

はじめに

みなさん、こんにちは。
今回、Aidemy AI画像認識アプリ開発コース3か月プランに挑戦してみましたので、これから始める方に参考になればと思い、本記事を記載します。

私の職業は建設系でプログラミング経験は一切ありませんでした。
AIやディープラーニングという言葉自体はよく聞くものの、中身はまったく分かっておらず、まずは仕組みを理解したい、あわよくば業務や日常生活で活かしていきたい!という思いが受講のきっかけでした。

本記事の概要

本記事は、プログラミング未経験の方で挑戦してみたいという方に参考になると思います。学習できる内容や、必要とした時間、成果物等を紹介していきます。

  • コース内で学べること

  • 作成した成果物と反省点

  • 今後の課題

コース内で学べること

カリキュラム

私はAIアプリ開発講座3か月コースを受講しました。

具体的なカリキュラム
 ・Python基礎
 ・NumPy、Pandas、Matplotlib基礎
 ・データクレンジング
 ・機械学習概論
 ・教師あり学習
 ・スクレイピング
 ・ディープラーニング
 ・男女識別(深層学習発展)
 ・CNNを用いた画像認識
 ・Flask, Git, Renderの入門
 ・手書き文字認識アプリ
 ・自作アプリ作成

上記の必須課程を学ぶと、Webアプリ開発に必要な基礎知識を身に着け、実装までの流れを手を動かして学ぶことができます。
時間に余裕がある方は上記以外の講座も受け放題です。

スケジュール

3か月コースで受講し、最初の1か月は仕事が休み、残りの2か月は業務と並行しながら講座を進めました。

学習時間はStudy plusというアプリで記録を付けていましたが、必須課程の講座を一通り学び終えるまでに48時間、自作アプリの作成に6時間、本ブログの作成に2時間の合計56時間でした。

コースの途中から業務で多忙となり、自作アプリの作成に十分な時間が割けなかったことが反省点ですが、なんとか3ヶ月の期間内に全てのコースを完了することが出来ました。ただ、自作アプリには十分な時間をかけた方が理解も深まると思いますので、上記時間より多く見積もっておいた方が良いと思います。

コース内や添削課題で自身でコードを組む場面が多数ありますが、初心者でしたのでその場で完全には理解できませんでした。そういった場合も、とりあえず前に進めることで、学習速度を上げることが出来たと思います。後の講座を進めるなかで不明点がクリアになることは多々ありました。

基本的は講座の説明が丁寧なので詰まることはありませんでしたが、不明点はチャットで気軽に質問できるので、その点は学習の効率化に非常に有効だったと思います。

作成した成果物と反省点

成果物

Aidemyでは学習の最後に成果物として好きなアプリを作成します。
私は、ファッションアイテムを画像で識別するアプリを作成しました。
(自分で画像等を用意して自由度の高いアプリを作ることも出来ますが、時間の都合でデータセットが用意されている本テーマとしました。)

Fashion item識別
https://flask-mnis-app.onrender.com

作成したアプリ

使用したデータセット、Fashion-MNISTは衣料品の画像を10クラス (Sneaker, Shirtなど) に分類するデータセットです。学習サンプル数60,000・テストサンプル数10,000で、各画像は28x28のグレースケールとなっています。Kerasから読み込むことで、簡単に使用できます。

Fashion-MNISTのデータ一例

製作環境

  • Google Colaboratory

  • python 3.8.10

  • tensorflow 2.3.0

コード

Fashion item(スニーカーやシャツ)等を分類するニューラルネットワークモデルをTensorFlowを使って作成、訓練しました。

データセットはkeras.datasetsを使用して読み込みました。

from keras.datasets import fashion_mnist
(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()

訓練させる前にピクセル値を0から1の範囲に収まるように前処理しました。

plt.figure()
plt.imshow(X_train[0])
plt.colorbar()
plt.grid(False)
plt.show()

X_train = X_train / 255.0
X_test = X_test / 255.0

モデルのコード
講座Flask入門の内容を参考に参考に、モデルを作成して重みを保存しました。

from keras.datasets import fashion_mnist
from keras.layers import Dense, Dropout, Flatten, Activation, BatchNormalization
from keras.layers import Conv2D, MaxPooling2D
from keras.models import Sequential, load_model
from keras.utils.np_utils import to_categorical
from keras.utils.vis_utils import plot_model
import numpy as np
import matplotlib.pyplot as plt

#モデルの保存
import os
from google.colab import files

# データのロード
(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()

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

X_train = X_train / 255.0
X_test = X_test / 255.0

# Convレイヤーは4次元配列を受け取ります。(バッチサイズx縦x横xチャンネル数)
# MNISTのデータはRGB画像ではなくもともと3次元のデータとなっているので予め4次元に変換します。
X_train = X_train.reshape(-1, 28, 28, 1)
X_test = X_test.reshape(-1, 28, 28, 1)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# モデルの定義
model = Sequential()
model.add(BatchNormalization())
model.add(Conv2D(filters=64, kernel_size=(3, 3),input_shape=(28,28,1), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(BatchNormalization())
model.add(Conv2D(filters=128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(BatchNormalization())
model.add(Conv2D(filters=256, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))


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

history = model.fit(X_train, y_train,
          batch_size=128,
          epochs=60,
          verbose=1,
          validation_data=(X_test, y_test))

# 精度の評価
scores = model.evaluate(X_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

# データの可視化(検証データの先頭の10枚)
for i in range(10):
    plt.subplot(2, 5, i+1)
    plt.imshow(X_test[i].reshape((28,28)), 'gray')
plt.suptitle("10 images of test data",fontsize=20)
plt.show()

# 予測(検証データの先頭の10枚)
pred = np.argmax(model.predict(X_test[0:10]), axis=1)
print(pred)

model.summary()

#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' ) 

#AccuracyとLossの表示
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train_acc', 'Test_acc'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train_loss', 'Test_loss'], loc='upper left')
plt.show()

層毎にバッチ正規化を施した、3層から成るCNNでモデルを構築しました。
Testデータの正解率は87.4%となりました。

Test loss: 0.3548552393913269
Test accuracy: 0.8743000030517578

以下に「学習データ」と「検証データ」による損失関数と、精度の結果をグラフに示します。エポック数が増えるにつれて、損失関数の値が小さくなっていき、学習が進んでいることが分かります。

モデルの精度
損失関数

画像判定のメインコード
判定する画像を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)

今後の課題

画像分類に関しては、モデルの評価が課題と考えています。
今はとりあえずモデルを作ることはできるものの、どういった対応を行えば精度が向上するか判断出来ないためです。
今後複数の成果物を作成していく中で、身に着けていけたらと思います。
また、画像分類以外の様々なAIの活用方法についても学んで行きたいです。

最後に

Pythonに触るきっかけと、プログラミング、AIの基礎を学びたいという目標は達成できたので、受講して良かったと感じています。
特に、全くの初心者から、Webアプリがどのように構成されているか理解し、実装できるようになった点が良かったです。世の中のWebサービスへの見方が変わりました。

この記事が気に入ったらサポートをしてみませんか?