LoginSignup
21
25
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

Python AIプログラミング その1 環境構築、文字認識

Last updated at Posted at 2024-07-07

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オプション")を入れてます。
MSstore1.png

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

で、読み込み対象の文字はこんな感じ。
digits.png

結果は、こんな感じ。
results.png

うーん微妙。
原因としては、俺の字が汚いのもあるだろうけど、本にも3.3の最後の「改良のヒント」で今回のテストデータではそれほど正確な結果が出ないと書いてあるので、次はMNISTというデータセットを使うやり方で改良できるか見てみるか。

4. まとめと今後の展望

今回は久々のAIプログラミングということで試運転だったけど、環境構築は思ったより簡単だったのに驚いた。
次は数字認識の改良と、数字以外の文字の認識にチャレンジしてみるか。
その次は顔認識や動画解析、ニュース記事の分類などもやってみて、ある程度のところまで来たらFlaskかDjangoで機械学習のAPIサービスみたいなのを作ってみたい。
行く行くはそのAPIサービスを使ったWebサービスを作るところまで行けたらいいな。

21
25
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
25