1. はじめに
最近家でプログラミングあまりやっていないなと思い、以前やろうとしたWebサービス作りも滞ってしまっていたのでAIプログラミングを少し勉強してみようと思い、こちらの本を使って学習を始めてみた。
今回はその本の3.3 「文字認識・手書き数字を判定しよう」をやってみた。
2. 環境構築
今回はWindowsでの環境構築だが、今はMicrosoft Storeでインストールできるのでめっちゃ簡単!
ついでに必要なライブラリとかもコマンドプロンプトまたはPowershellからpipでインストールできるので、めっちゃ簡単!
3.3章で使うライブラリはmatplotlib(グラフ描画ライブラリ)とscikit-learn(機械学習ライブラリ)、OpenCV(画像処理ライブラリ)なので、以下のコマンドを打てば終わり。
pip install -U pip
pip install -U matplotlib
pip install -U scikit-learn
pip install -U opencv-python
ちなみに、pip自身も必要に応じてアップグレードする必要があるので、最初にpipのアップグレード("-Uオプション")を入れてます。
3. 手書き数字判定
本ではscikit-learnが持っているテストデータを学習するml_digist.pyと作った画像を判定するpredict-muimage.pyに分かれていたが、1回で実行できるよう下記のようにまとめてみた。
import cv2
import pickle
from sklearn.model_selection import train_test_split
from sklearn import datasets, svm, metrics
from sklearn.metrics import accuracy_score
def learn():
# データを読み込む --- (*1)
digits = datasets.load_digits()
x = digits.images
y = digits.target
x = x.reshape((-1, 64)) # 二次元配列を一次元配列に変換 --- (*2)
# データを学習用とテスト用に分割する --- (*3)
x_train, x_test, y_train, y_test = \
train_test_split(x, y, test_size=0.2)
# データを学習 --- (*4)
clf = svm.SVC()
clf.fit(x_train, y_train)
# 予測して精度を確認する --- (*5)
y_pred = clf.predict(x_test)
print(accuracy_score(y_test, y_pred))
return clf
def predict_digit(filename, clf):
with open("digits.pkl", "wb") as fp:
pickle.dump(clf, fp)
# 学習済みデータを読み込む
with open("digits.pkl", "rb") as fp:
clf = pickle.load(fp)
# 自分で用意した手書きの画像ファイルを読み込む
my_img = cv2.imread(filename)
# 画像データを学習済みデータに合わせる
my_img = cv2.cvtColor(my_img, cv2.COLOR_BGR2GRAY)
my_img = cv2.resize(my_img, (8, 8))
my_img = 15 - my_img // 16 # 白黒反転する
# 二次元を一次元に変換
my_img = my_img.reshape((-1, 64))
# データ予測する
res = clf.predict(my_img)
return res[0]
clf = learn()
# 画像ファイルを指定して実行
n = predict_digit("zero.png", clf)
print("zero.png = " + str(n))
n = predict_digit("one.png", clf)
print("one.png = " + str(n))
n = predict_digit("two.png", clf)
print("two.png = " + str(n))
n = predict_digit("three.png", clf)
print("three.png = " + str(n))
n = predict_digit("four.png", clf)
print("four.png = " + str(n))
n = predict_digit("five.png", clf)
print("five.png = " + str(n))
n = predict_digit("six.png", clf)
print("six.png = " + str(n))
n = predict_digit("seven.png", clf)
print("seven.png = " + str(n))
n = predict_digit("eight.png", clf)
print("eight.png = " + str(n))
n = predict_digit("nine.png", clf)
print("nine.png = " + str(n))
うーん微妙。
原因としては、俺の字が汚いのもあるだろうけど、本にも3.3の最後の「改良のヒント」で今回のテストデータではそれほど正確な結果が出ないと書いてあるので、次はMNISTというデータセットを使うやり方で改良できるか見てみるか。
4. まとめと今後の展望
今回は久々のAIプログラミングということで試運転だったけど、環境構築は思ったより簡単だったのに驚いた。
次は数字認識の改良と、数字以外の文字の認識にチャレンジしてみるか。
その次は顔認識や動画解析、ニュース記事の分類などもやってみて、ある程度のところまで来たらFlaskかDjangoで機械学習のAPIサービスみたいなのを作ってみたい。
行く行くはそのAPIサービスを使ったWebサービスを作るところまで行けたらいいな。