AIスクール「Aidemy 」 AIアプリ開発講座の成果物作成

AIアプリ開発

7月からAIアプリ開発講座を受講していよいよ成果物作成をすることになりました。

講師の先生に相談し、イエベブルベ診断(パーソナルカラー診断)のアプリを作ろうと決めました。

きっかけは、私がどんなアプリを作ろうか悩んでいたら娘が「イエベブルベ診断のアプリが良いな♪」と言ってくれたのでこれに決めました。

イエベ・ブルベとは

イエベ・ブルベは4つあるパーソナルカラー分類(診断)のひとつで、別名「2ベース分類」とも呼ばれています。全てのパーソナルカラーの中で最も基本となる色味の分け方です。

自分のパーソナルカラーと選んだ色が合っていないと実際に鏡越しで当ててみると似合わなかったり、かえって顔色が悪く見えたりすることがあります。

イエベ・ブルベとは、それぞれイエローベースとブルーベースの略で、肌の色の傾向を表したものです。

イエベとはイエロー(黄味)よりの肌色のことで、ブルベとはブルー(青み)よりの肌のこと。
自分はどちらに当てはまるのかを診断することで、自分に似合う色を知ることができます。

イエベ・ブルベ診断はイエベ春・イエベ秋・ブルベ夏・ブルベ冬の4つに分類されます。

イエベ・ブルベ診断でわかること

イエベ・ブルベ診断ではあなたのベースカラー(似合う色の傾向)がわかりますイエベの人は、黄色、オレンジ、ピンク、赤、茶色などの暖色系の色が似合いやすく、ブルベの人は青、紫、緑、黒などの寒色系の色が似合いやすいです。

イエベ・ブルベ診断の注意点

イエベ・ブルベ診断でわかるのは、あくまでもペースカラーの傾向です。具体的にこの色が似合うという診断はイエベ・ブルベ診断だけでは限界があるので注意してください。

それぞれの特徴

【イエベ春】タイプは、ほんのりした血色感とみずみずしさのあるつややかな肌、明るいブラウン系の瞳、ミディアムブラウンや明るめブラウンの髪が特徴です。
フレッシュでキュートな雰囲気が魅力です。

代表的な芸能人は深田恭子さんや桐谷美玲さん。

[イエベ春] 深田恭子さん
[イエベ春] 桐谷美玲さん

【イエベ秋】タイプは、しっかりとした黄みが感じられる陶器のようにしっとりした肌と、ダークブラウンや黒の瞳、深みのあるブラウンや黒系の髪が特徴。 シックで大人っぽい雰囲気の持ち主です。

代表的な芸能人は滝沢カレンさんや山本美月さん。

[イエベ秋]滝沢カレンさん
[イエベ秋]山本美月さん

【ブルベ夏】タイプは、軽く赤みがかってふわりとした質感の肌、ソフトブラックや紅茶のように明るいブラウンの瞳と髪が特徴。
透明感のある、エレガントで女性らしい印象が魅力です。

代表的な芸能人は有村架純さんや橋本環奈さん。

[ブルベ夏]有村架純さん
[ブルベ夏]橋本環奈さん

【ブルベ冬】タイプは、透明感がありながらも血色感のあまり感じられないツヤ肌、はっきりした黒の瞳、つややかな黒髪が特徴。
クールかつスタイリッシュな雰囲気と、華やかな存在感の持ち主です。

代表的な芸能人は小松菜奈さんや菜々緒さん。

[ブルベ冬]小松菜奈さん
[ブルベ冬]菜々緒さん

実行環境

MacBook Pro (16-inch, 2019)

GoogleCoraboratory

Visual Studio Code

学習モデル作成のためのデータ収集

作成にあたってカウンセリングの予約をしたら、「まず画像収集から始めましょう!」とアドバイスをいただいたので早速画像収集に取り掛かりました。

color

今回はパーソナルカラーということなのでデータセットには無さそうなので芸能人の画像をネットから一枚一枚をコピペで収集しました。
画像の拡張子は決まりはないとのことですが、データサイズの観点よりjpgを勧められましたが、これを聞いた時点で最初の100枚くらいをjpegで保存してしまったので先生に質問しました。

「.jpg も.jpeg もどちらも同じJoint Photographic Experts Groupというファイル形式なので,データサイズの観点でいえばどちらでも変わりはなく、実装のしやすさからどちらかに統一をするか,両方を扱うかを決めていいと思います・・・」

とのことなのでその後の全部jpegで保存することに決めました。

Goole Colaboratoryを使い画像の読み込み及び正解ラベルの付与

1種類につき135枚集め、4種類なので合計540枚を集め早速GoogleCoraboratoryでモデル作り♪

画像を集め先生に相談した結果、過去の生徒さんの成果物を参考にすると良いとのアドバイスを頂いたので参考にさせていただきました。

男女識別の時はファイルをfor文で1枚1枚を空のリストに入れる為に2種類の空のリストを用意しましたが、今回はイエベ春・イエベ秋・ブルベ夏・ブルベ冬の4種類が必要なので書き方を変えるということ。

img_male = []
img_female = []

上記のコードは男女識別の時の空のリストを2つ用意した例です。今回は4種類なので沢山書かないとならないので簡潔なコードを書きます。それが下記のコードです。

# 画像ファイルの一時保管用リスト
pre_list = [[] for i in range(4)]

このように書くと4つの空のリストが作成されます。

次に画像ファイルを読み込みます。

# 画像ファイルの読み込み    
for n, color_name in zip(range(4), pasokara):
    numbers = len(make_path(color_name))
    for i in range(numbers):
        img = cv2.imread('/content/drive/MyDrive/artifact/{}/'.format(color_name) + make_path(color_name)[i])
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (350, 350))
        pre_list[n].append(img)

正解ラベル格納リスト

# 正解ラベル格納リスト
labels = []
for i,color_name in enumerate(pasokara):
    numbers = len(make_path(color_name))
    labels += [i]*numbers

コード解説・・

zip関数は二つの要素をリストにします。

for文で要素の数とクラス名を回す。[(1,’イエベ春’),(2,’ブルベ夏’)・・・]という感じ

作成されたリストをnumbersに格納します。

そのnumbersの中からさらにfor文で一つ一つを取得し、cv2.imread()で画像ファイルをNumPy配列ndarrayとして読み込み、ndarrayを画像として読み込み保存する。

この時にクラス名(イエベ春など)とmake_path関数(独自関数)で取得したディレクトリと画像のファイル名を{}の中に入るようにして、iに入れる。

OpenCVの関数cvtColor()でBGRとRGBを変換。

カラー設定と画像のリサイズをして先程作成した一時保管用リストpre_listの中にnとして一つずつ追加していく。

正解ラベル格納リストには、空のリストlabelsの中にenumerate関数でインデックスとクラス名を一つずつ取り出し、各クラス分の画像の枚数分の正解ラベルを0から順番にlabers中に格納していきます。


# VGG16のインスタンス生成
input_tensor = Input(shape = (350, 350, 3))
vgg16 = VGG16(include_top = False, weights = 'imagenet', input_tensor = input_tensor)


top_model = Sequential()
top_model.add(Flatten(input_shape = vgg16.output_shape[1:]))
top_model.add(Dense(256, activation = 'relu'))
top_model.add(BatchNormalization())
top_model.add(Dense(4, activation = 'softmax'))

# モデルの連結
model = Model(inputs = vgg16.input, outputs = top_model(vgg16.output))

# VGG16の重みの固定
for layer in model.layers[:15]:
    layer.trainable = False

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


#モデルチェックポイント
modelCheckpoint = ModelCheckpoint(filepath = 'XXX.h5',
                                  monitor='acc',
                                  verbose=1,
                                  save_best_only=True,
                                  save_weights_only=False,
                                  mode='max',
                                  period=1)

# 学習の実行
history = model.fit(X_train, y_train, 
                    validation_data = (X_test, y_test), 
                    batch_size =16, 
                    epochs =30,
                    verbose=1,
                    callbacks=[modelCheckpoint])

今回はVGG16を使用して転移学習をしました。

VGG16とは、

VGG-16 は、深さが 16 層の畳み込みニューラル ネットワークです。100 万枚を超えるイメージで学習させた事前学習済みのネットワークを、ImageNet データベース[1]から読み込むことができます。この事前学習済みのネットワークは、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マウス、鉛筆、多くの動物など) に分類できます。結果として、このネットワークは広範囲のイメージに対する豊富な特徴表現を学習しています。

この構築モデルはそれぞれ4種類の画像データを元に、似たようで似ていない特徴を捉えパーソナルカラーを分析して判断しております。

実行結果

実行結果は以下の通り

accuracy:1.00 val_accuracy:最高で42%。

講師の先生にアドバイスを受けながら試行錯誤してどうにか精度をあげようと先生も頑張ってくれましたが今回はこれが限界でした。

精度が上がらなかった理由とその反省点

精度が上がらなかったのは、

①データに背景などの必要のない情報が沢山入っていたこと。

②今回構築したモデルが肌の色を判断できるのものではなく、輪郭を取得するモデルだったこと。

以上の2点が原因となりました。

機械はどうやってパーソナルカラーを診断したのか

機械はそれぞれ4つの特徴を分析し、主に輪郭の特徴を捉え判断しました。

今回は男女識別モデルを使用したので輪郭を捉えるという分析方法で、目的変数を特には決めずこの結果となりましたが、パーソナルカラーというのは輪郭ではなく肌の色や目の色といった特徴をもとに診断します。

パーソナルカラー診断に必要なのは肌の色が一番大切なので、精度を上げるには肌の色を集中的に採取し、その平均数値を割り出して分ける。という方法が良いと先生からアドバイスも頂きました。

次回パーソナルカラー診断アプリを制作する際は、余計な背景などの部分を取り除き、肌の色や目の色などのカラー数値の平均値を割り出し、例えば平均数値が100-120はイエベ春、121~140はブルベ夏といったように目的変数(yデータ)を決めるようにして制作すればもっと精度の高いモデルができると思うので、いつかリベンジしたいと思います。

AIでパーソナルカラー診断
https://iebe-bulube.herokuapp.com/

以下は全コードです。

import os
from google.colab import files
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras import optimizers
from keras.callbacks import ModelCheckpoint
from keras.applications.inception_v3 import InceptionV3

!sudo apt install tree
!tree -d /content/drive/MyDrive/artifact

#パスに使用する用のパーソナルカラーの名前リスト
pasokara=['ブルベ夏','ブルベ冬','イエベ秋','イエベ春']


# 画像ファイルのパス作成関数
def make_path(dir):
    path_name = os.listdir('/content/drive/MyDrive/artifact/{}/'.format(dir))
    return path_name

# 画像ファイルの一時保管用リスト
pre_list = [[] for i in range(4)]

# 画像ファイルの読み込み    
for n, color_name in zip(range(4), pasokara):
    numbers = len(make_path(color_name))
    for i in range(numbers):
        img = cv2.imread('/content/drive/MyDrive/artifact/{}/'.format(color_name) + make_path(color_name)[i])
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (350, 350))
        pre_list[n].append(img)


# パーソナルカラーの種類ごとに分けられていた画像ファイルを1つのリストに統合する
img_list = []
for i in range(4):
    img_list += pre_list[i]

# 正解ラベル格納リスト
labels = []
for i,color_name in enumerate(pasokara):
    numbers = len(make_path(color_name))
    labels += [i]*numbers

# 画像データをnumpy配列に変換
X = np.array(img_list)
y = np.array(labels)

# 画像データをシャッフル
rand_index = np.random.permutation(np.arange(len(X)))
X = X[rand_index]
y = y[rand_index]

# トレーニングデータとテストデータに分ける
X_train = X[:int(len(X)*0.8)]
y_train = y[:int(len(y)*0.8)]
X_test = X[int(len(X)*0.8):]
y_test = y[int(len(y)*0.8):]

# ラベルデータをone-hotベクトルに変換
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)


# VGG16のインスタンス生成
input_tensor = Input(shape = (350, 350, 3))
vgg16 = VGG16(include_top = False, weights = 'imagenet', input_tensor = input_tensor)


top_model = Sequential()
top_model.add(Flatten(input_shape = vgg16.output_shape[1:]))
top_model.add(Dense(256, activation = 'relu'))
top_model.add(BatchNormalization())
top_model.add(Dense(4, activation = 'softmax'))

# モデルの連結
model = Model(inputs = vgg16.input, outputs = top_model(vgg16.output))

# VGG16の重みの固定
for layer in model.layers[:15]:
    layer.trainable = False

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


#モデルチェックポイント
modelCheckpoint = ModelCheckpoint(filepath = 'XXX.h5',
                                  monitor='acc',
                                  verbose=1,
                                  save_best_only=True,
                                  save_weights_only=False,
                                  mode='max',
                                  period=1)


# 学習の実行
history = model.fit(X_train, y_train, 
                    validation_data = (X_test, y_test), 
                    batch_size =16, 
                    epochs =30,
                    verbose=1,
                    callbacks=[modelCheckpoint])


# 以下、評価指標を可視化するコード

# 正解率の可視化
plt.plot(history.history['accuracy'], label='acc', ls='-')
plt.plot(history.history['val_accuracy'], label='val_acc', ls='-')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(loc='best')
plt.show()

まとめ

AIアプリを制作するときはその内容によってデータの収集方法、モデルの構築方法を選択するのがとても重要ということを実感いたしました。

この結果は私のこれからのアプリ制作人生においてとてもプラスとなる内容でした。

コメント

  1. I am actually grateful to the holder of this site who has shared this enormous article at here.

タイトルとURLをコピーしました