見出し画像

ゼロから始めるAI画像認識

今日はお仕事のあとにそこそこ頑張った
今日から本格的に機械学習の利用を開始した

AI作成の手順

方針としては

  1. 教師なし学習でざっくり画像を分類

  2. 目検で画像を分類

  3. 各画像の背景を削除

  4. ラベル付け

  5. 教師あり学習でなすを認識するAIを作成

教師データの作成

今日はとりあえず教師なし学習でざっくり画像を分類した
使用したコードは以下
もとは似た国旗を分類するという趣旨のコード

こちらのサイトから拝借してきました

import os
import shutil
import numpy as np
from PIL import Image
from skimage import io
from sklearn.cluster import KMeans
import unittest
#import fizzbuzz as fb


# 1. 画像のサイズをそろえて保存する
# ./flag_origin 以下に国旗画像
# ./flag_convert 以下に200*100のサイズに変換したjpgを保存
for path in os.listdir('./flag_origin'):
    img = Image.open(f'./flag_origin/{path}')
    img = img.convert('RGB')
    img_resize = img.resize((200, 100))
    img_resize.save(f'./flag_convert/{path}')


# 2. 3次元配列の画像データを2次元配列のデータに変換
feature = np.array([io.imread(f'./flag_convert/{path}') for path in os.listdir('./flag_convert')])
feature = feature.reshape(len(feature), -1).astype(np.float64)

# 3. 学習(3種類のグループにクラスタリングする)
model = KMeans(n_clusters=3).fit(feature)

# 4. 学習結果のラベル
labels = model.labels_


# 5. 学習結果(クラスタリング結果の表示 + ラベルごとにフォルダ分け)
# ./flag_group 以下に画像を分けて保存する
"""
for label, path in zip(labels, os.listdir('./flag_convert')):
    os.makedirs(f"./flag_group/{label}", exist_ok=True)
    shutil.copyfile(f"./flag_origin/{path.replace('.jpg', '')}", f"./flag_group/{label}/{path.replace('.jpg', '')}")
    print(label, path)
"""
for label, path in zip(labels, os.listdir('./flag_convert')):
    os.makedirs(f"./flag_group/{label}", exist_ok=True)
    shutil.copyfile(f"./flag_origin/{path}", f"./flag_group/{label}/{path}")
    print(label, path)
├─── flag_origin/       -- 国旗画像pngファイルを保存しておく
├─── flag_convert/      -- 同一サイズに変換した国旗画像(jpg)を保存
└─── flag_group/        -- 学習結果によってグループ分けされた画像を保存
      ├─── 0/
      ├─── 1/
      ├─── 2/

こちらがディレクトリの構成


#1 サイズ変換

そもそも画像というのは各ピクセルに色が割り当てられ、そのというのが16進数の数値で表現されている


RGBのイメージ図


RGBというフォーマットではR(赤)、G(緑)、B(青)のそれぞれに二桁ずつが対応して、#01 D1 FF といった形で表現される
上の画像のように赤緑青のセットが200×100並んでおり、RGBの色の強さが01 D1 FFで表現され、そのバランスの結果、特定の色に見えるといったロジックだ
そして各ピクセルの座標(200×100ピクセルならば(0,0)から(199,99)まで)にRGBの数値が割り当てられることで画像が表現される

具体的にどう割り当てるか(コードとしてどのように画像を認識するか)というと、RGBの数値を200×100の配列として持つことで割り当てを表現する

具体的な処理についてはこちらをどうぞ
具体的なイメージで説明されていてわかりやすいです

#2 画像の配列を変換

ここまでで、どのようにして画像を数値で表現するのかご説明した
このステップがなぜ必要かというと、最初画像をPythonでリスト読み込んだ段階では3次元の配列になっており、(横の座標、縦の座標、RGBの数値)といった形になっている
今回だと100×200×3(16の二乗の3倍、色のパターン数)といった形
縦と横が配列の並びと逆なので注意
今回使うライブラリの仕様上この形は適さないので、上の赤緑青の画像のピクセルをさらに色素に分解し、100×600の形に変換する

具体的には、
12 34 56 | 12 34 56 | 12 34 56
12 34 56 | 12 34 56 | 12 34 56
となっている6桁の色データの2×3の配列だったものを
12 | 34 | 56 | 12 | 34 | 56 | 12 | 34 | 56
12 | 34 | 56 | 12 | 34 | 56 | 12 | 34 | 56
のように二けたずつの2×9とするみたいな感じ

#3 K平均法

ここから教師なし学習と呼ばれる統計処理の一つであるK平均法というものをざっくり説明する(というか私もざっくりしかわからんのでさっくりしか説明できない)

K平均法というのは教師なし学習の中でも、最初にいくつのクラスターに分類するか指定したうえでクラスタリング手法である

①まず指定したクラスターの数だけランダムにクラスター分けする
②各クラスター内で平均を算出する
③各点を②の平均のうち最も近い平均のクラスターに割り当てなおす
⓸①から③を繰り返し、どの点のクラスターも更新されなくなったら終了

といったアルゴリズムである

具体的に今回の例で見ていこう
簡単化のため2次元で考える

1×2ピクセル

1×2ピクセルの2次元の図形を想定する
この左右のピクセルは0-99が入る。
この数値が白から黒の間のグレーの濃淡に対応すると考えてもらえばよい

左右に色を入れた例

各画像は0-99の数値が入るxi, yiとして(iは画像の番号), (xi, yi)として表現される
これによって画像を2次元平面上の点として表現できる

例のような画像を二つのクラスターに分類していく
(xi, yi, 0)と(xi, yi, 1)といった感じ
左に濃い色・右に薄い(0-49、50-99)のセットと左に薄い・右に濃い(50-99、0-49)のセットに分けられれば大成功といった感じだ

例えば、画像が10000枚あったとする
まず10000枚の画像をランダムに二つに分ける
それぞれのクラスターの中で左と右についてそれぞれ数値の平均を計算する
これによって各クラスターの重心が求まる(重心がどれかの画像に対応しているとは限らない・中間的な色の組み合わせである可能性がある)

クラスター1の重心とクラスター2の重心のそれぞれと10000枚の各画像との距離を求める
√((gx-xi)^2+(gy-yi)^2)
かのピタゴラスの定理である
そして近い方のクラスターに分類しなおしていく
最後に、更新された点の個数を数え、0でないか確認する
更新された点の個数は(xi, yi, z)の更新前のzと更新後のz'を引き算して0でないものを数える

そうしてできた二つのクラスターの中でまた重心を求め各点との距離を求め分類しなおす
そして更新された点の個数を数え、0でないか確認する
これを繰り返して、更新された点の個数が0になったら終わる

まあ、大体こんな感じでクラスタリングできるはず

100×200ピクセルのRGB(3)だと100×600の6万次元空間の中で同じことをすればナスもクラスタリングできるはず


多分、、、

そういえば最初のランダムにクラスタリングするところとかを工夫するK-means++みたいなのもあるらしい、、、


今後すぐにすること

①教師なし学習、教師あり学習の理論理解
②引き続きなす画像の採取
③画像の選別
⓸背景を消して教師データに仕上げ

長期ですること

①PyTorchを不自由なく使えるよう


補遺:教師あり学習についてざっくり

教師あり学習による画像認識というのは、そのような数値の出現パターンをニューラルネットワークというフレームワークによって統計分析を行い、パターンを記録しているに過ぎない
乱暴に言えば高校で学んだヒストグラムを作成して数値の出力パターンの確率分布を求めるプロセスと似たようなものだ



違うか、、、


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