Slide 1

Slide 1 text

はじめての文字認識 改 oda@sendai   令和元年 6月18日

Slide 2

Slide 2 text

環境 Python 3.7.3 JupyterLab 0.35.4 scikit-learn 0.20.3 matplotlib 3.0.3 opencv-python 4.1.0.25

Slide 3

Slide 3 text

JupyterLab ・ブラウザ上でPythonのプログラミングができるツール ・プラグインを入れれば、JavaやRも使用できる https://github.com/jupyterlab/jupyterlab

Slide 4

Slide 4 text

JupyterLab

Slide 5

Slide 5 text

scikit-learn ・Pythonのオープンソース機械学習ライブラリ ・サポートベクターマシン(SVM)のサポート ・1797個の8x8サイズ 手書き数字イメージサンプル有り http://scikit-learn.org/ https://ja.wikipedia.org/wiki/Scikit-learn

Slide 6

Slide 6 text

matplotlib ・グラフ描画ライブラリ http://matplotlib.org/ https://ja.wikipedia.org/wiki/Matplotlib

Slide 7

Slide 7 text

opencv-python ・画像処理ライブラリ https://opencv.org https://ja.wikipedia.org/wiki/OpenCV

Slide 8

Slide 8 text

データ読み込み 1つ目のセル # cell 1 # モジュールのインポート from sklearn import datasets # 数字データセット読み込み digits = datasets.load_digits() # 学習データ data = digits.data # ラベル(教師あり学習用) target = digits.target

Slide 9

Slide 9 text

学習データの表示 2つ目のセル(1/2) # cell 2 # モジュールのインポート import matplotlib.pyplot as plt # 表示する学習データの指定(0 ~ 1797) n=100 # n番目のラベルの表示 print(target[n])

Slide 10

Slide 10 text

学習データの表示 2つ目のセル(2/2) # n番目の学習データの表示 i=0 for j in data[n]: if i<7: print(j, end='') print(", ", end='') i+=1 else: print(j) i=0 # n番目の学習データを画像表示 plt.imshow(digits.images[n], cmap='Greys')

Slide 11

Slide 11 text

学習データの表示 2つ目のセルの実行結果

Slide 12

Slide 12 text

学習 3つ目のセル(1/2) # cell 3 # モジュールのインポート from sklearn.model_selection import train_test_split from sklearn import svm import time # データを学習用とテスト用に分ける x_train, x_test, y_train, y_test = train_test_split(data,target,test_size=0.2)

Slide 13

Slide 13 text

学習 3つ目のセル(2/2) # SVM(サポートベクターマシン)アルゴリズムを使う clf = svm.SVC(C=1, kernel='linear') # 学習用データと学習用ラベルで学習する startTime = time.time() fitted = clf.fit(x_train, y_train) elapsedTime = time.time() - startTime # 処理時間の表示 print("処理時間 ", round(elapsedTime * 1000000)/1000, "msec") 実行結果 処理時間 81.47 msec

Slide 14

Slide 14 text

データを学習用とテスト用に分ける ・学習用データとテスト用データが同じなら、 正解率が100%に近くなるため分ける。 ・ここでは、学習用データを8割・テスト用データを2割 にしている。 train_test_splitが良しなにしてくれる。

Slide 15

Slide 15 text

SVM(サポートベクターマシン) ・教師あり学習を用いるパターン認識モデル。 ・線形分類が得意。

Slide 16

Slide 16 text

検証 4つ目のセル # cell 4 # モジュールのインポート from sklearn import metrics # テスト用データで予測する predict = fitted.predict(x_test) # 検証する print(metrics.confusion_matrix(predict, y_test)) # スコア計算 print("テストデータの正解率:", str(metrics.accuracy_score(predict, y_test) * 100) + "%")

Slide 17

Slide 17 text

検証結果 横軸が検証結果 縦軸がテスト用ラベル [[33 0 0 0 0 0 0 0 0 0] [ 0 35 0 0 0 0 0 0 0 0] [ 0 0 44 0 0 0 0 0 0 0] [ 0 0 0 35 0 0 0 0 0 0] [ 1 0 0 0 39 0 0 0 0 0] [ 0 0 0 1 0 24 0 0 0 0] [ 0 0 0 0 0 1 38 0 0 0] [ 0 0 0 0 0 0 0 47 0 0] [ 0 0 0 1 0 0 0 0 30 0] [ 0 0 0 1 0 0 0 0 0 30]] テストデータの正解率: 98.61111111111111%

Slide 18

Slide 18 text

学習済みモデルの保存 5つ目のセル # cell 5 # モジュールのインポート import joblib # 学習済みモデルの保存 joblib.dump(fitted, 'model.pkl')

Slide 19

Slide 19 text

手書き数字の判定 6つ目のセル(1/3) # cell 6 # モジュールのインポート import cv2 from sklearn.externals import joblib from IPython.display import display, Image # 読み込む画像ファイル名 filename="7.png" # 画像の表示 def display_cv_image(image, format='.png'): decoded_bytes = cv2.imencode(format, image)[1].tobytes() display(Image(data=decoded_bytes))

Slide 20

Slide 20 text

手書き数字の判定 6つ目のセル(2/3) # 画像読み込み pngData = cv2.imread(filename) print("読み込んだ画像") display_cv_image(pngData, '.png') # モデル読み込み clf = joblib.load("model.pkl") # グレースケール変換 pngDataGray = cv2.cvtColor(pngData, cv2.COLOR_BGR2GRAY) print("グレースケール変換した画像") display_cv_image(pngDataGray, '.png') # 8x8サイズ変換 pngDataGray88 = cv2.resize(pngDataGray,(8,8)) print("8x8サイズ変換した画像") display_cv_image(pngDataGray88, '.png')

Slide 21

Slide 21 text

手書き数字の判定 6つ目のセル(3/3) # 白黒反転 pngDataGray88Rev = 15 - pngDataGray88 // 16 print("白黒反転した画像") display_cv_image(pngDataGray88Rev, '.png') # 一次元変換 pngDataGray88RevDim = pngDataGray88Rev.reshape((-1,64)) print("一次元変換した画像") display_cv_image(pngDataGray88RevDim, '.png') res = clf.predict(pngDataGray88RevDim) # 結果表示 print("判定結果は「", str(res[0]), "」です。\n")

Slide 22

Slide 22 text

手書き数字の判定 6つ目のセルの実行結果(1/2)

Slide 23

Slide 23 text

手書き数字の判定 6つ目のセルの実行結果(2/2)

Slide 24

Slide 24 text

8x8サイズ変換データをデカく表示 7つ目のセル # cell 7 # 8x8サイズ変換データをデカく表示 print("8x8サイズ変換データをmatplotlibで表示") plt.imshow(pngDataGray88, cmap=plt.cm.gray)

Slide 25

Slide 25 text

8x8サイズ変換データをデカく表示

Slide 26

Slide 26 text

手書き数字の判定(間違い) 6つ目のセルの実行結果(1/2)

Slide 27

Slide 27 text

手書き数字の判定(間違い) 6つ目のセルの実行結果(2/2)

Slide 28

Slide 28 text

8x8サイズ変換データをデカく表示

Slide 29

Slide 29 text

考察 ・5を判定させる数字は難しい。 4か6に誤認されることが多かった。 ・数字を8x8にしたときに失われるデータが多い。 誤認の原因と考えられる。 ・実用するためには、学習データはもっと大きいサイズに する必要がある。 ・8x8に変換する際に、余白を削除すれば良くなる・・・かな?

Slide 30

Slide 30 text

参考ページ ・scikit-learn Tutorials https://scikit-learn.org/stable/tutorial/index.html ・【Python】scikit-learnで手書き数字を判定してみた https://ymgsapo.com/2018/12/03/hand-digits-test/ ・sklearnで手書き文字認識 http://akiniwa.hatenablog.jp/entry/2013/12/20/120734

Slide 31

Slide 31 text

はじめての文字認識 END