【日本語 – 手書き編】OCR用のオリジナル学習済みモデルの作成方法(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)

【日本語 - 手書き編】OCR用のオリジナル学習済みモデルの作成方法(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)

 

【動画】日本語 – 手書き編:自作OCRプログラム用の学習済みモデルの作成(オリジナルデータセット)

 

 

【日本語 – 手書き編 #1】
自作OCRプログラム用の学習済みモデルの作成(オリジナルデータセット)
Japanese handwritten character OCR : model


視聴時間:10分1秒

 




 

【動画の内容】

ステップ1 – 学習済みモデルの作成(日本語手書き)
0:00 Colaboratoryの設定・プログラムの概要
1:38 オリジナルデータセットのアップロード
5:18 圧縮ファイルの解凍・フォルダ化
6:11 CNNで学習済みモデルの作成

【コードの修正情報:2021年9月6日】
③のコード内の「#1 各種インポート」の
from keras.optimizers import Adam
でエラーとなるため修正しておきました。
不具合を教えてくださった方、ありがとうございました。

【コードの修正情報:2023年2月14日】

③のコード内の「#1 各種インポート」の
# from keras.preprocessing.image import load_img, img_to_array
でエラーとなるため修正しておきました。
不具合を教えてくださった方、ありがとうございました。

 

機械学習モデルのディープラーニング(深層学習)でおなじみの「畳み込みニューラルネットワーク」(CNN:Convolutional Neural Network)で、日本語画像(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)のオリジナルデータセットを学習させて、学習済みモデルを作成できる簡単なプログラムを作成してみました。

既存のOCRプログラムで日本語の手書き文字の画像認識をしてみても、思ったよりも上手く行かない経験をされる方もいるのではないかと思います。
一連のプログラムが、これから、日本語をはじめとしたOCRに挑戦したい方の参考になることがありましたら幸いです。

Japanese handwritten character OCR Edition
:How to Create an Original Trained Model.
Introduction to Continuous Japanese handwritten character Image Recognition Python Programming.

 

今回のプログラムは、以前投稿させていただいた

【コード解説】自作画像認識AI:Keras・CNN・Pythonオリジナルデータセット対応の機械学習サンプルコード

のオリジナルデータセットで自作画像認識AIを作れるプログラムを改変して作っています。そのため、AIプログラムの詳細を知りたい方は、記事ページを参照ください。Google Colaboratoryですぐに試せる、サンプルコードと学習用のPDFなども無料公開しています。

 

 

サンプル画像(データセット)・サンプルコードリンク:日本語手書き連続文字画像認識プログラム用

 

 

日本語手書き文字画像認識用オリジナルデータセット


今回の日本語手書き文字用のOCR開発チュートリアル用のサンプルデータセットです。
実際にOCRしたい画像を使うと精度が高くなりやすいのではないかと思います。
その他の文字を追加する場合には、追加したい文字の名前にした新たなフォルダを作成し、フォルダ内に該当画像を入れるだけでオリジナルデータセットを作れます。

例.フォルダ名「あ」
「あ」という名前のフォルダ内に「あ」の画像を入れる

 

すぐに使えるGoogle Colaboratoryサンプルコードリンク

Keras-CNN-Japanese-handwritten-character-text-originaldataset.ipynb | Google Colaboratory
(ファイル – ドライブにコピーを保存後にコピー環境で実行。プログラムを動かすにはGoogleアカウントでログインする必要があります)

* 2021年6月に確認時点では、macOS Big Sur バージョン 11.4(20F71)・Firefox バージョン 89.0(64ビット)のブラウザの環境では、Google Colaboratoryに画像ファイル以外のアップロードでエラーが起きるようでした。
そのため、チュートリアルで利用するオリジナルデータセットの圧縮ファイル(ZIP形式ファイル)のアップロードでエラーが出る場合には、その他のブラウザ(例.Macの場合はSafari。Mac・Windows共通のブラウザ Google Chrome など)でも試してみてください。

 

 

【プログラムのライセンス】

 

 

The MIT License

Copyright 2021 child programmer

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

【日本語手書き文字画像認識用:Pythonサンプルコード】

 

 

KerasでCNN機械学習。自作・自前画像のオリジナルデータセットで画像認識入門

 

以下の①②③の手順を順番に実行すると.h5形式の「model.h5」という名前の学習済みモデル(機械学習モデル構造+学習済みの重み)が出力されます。
その後、ローカル環境(自分のパソコン)にダウンロードして使えます。

【ステップ1】日本語手書き文字画像認識用オリジナル学習済みモデルの作成
(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)

① Googleアカウントでログインした状態で、「ファイル – ドライブにメニューを保存」し、以下の手順を進めます。
② zipファイルをGoogle Colaboratoryにアップロードし、フォルダ化
③ 用意した自前画像で学習(畳み込みニューラルネットワーク:CNN)

【ステップ2】1文字判定
(日本語:ひらがな・カタカナ・漢字・ローマ字・点、・丸。)

④ 自前画像で判定(手書き日本語画像)

* ①②③を実行後に「④ 自前画像で判定(手書き日本語画像)」を実行すると1文字判定できます。(確率情報付き)

 

 

バージョン情報(Python・各種ライブラリ)

 

 

python 3.7.10
tensoflow 2.5.0
keras 2.5.0
sklearn(scikit-learn) 0.22.2.post1
opencv(opencv-python)4.1.2
matplotlib 3.2.2

ローカル環境で、指定したバージョンのインストールが難しい場合、Python・TensorFlow・Keras以外は最新のバージョンを入れてみてください。
mata
また、Google Colaboratoryのサンプルコードではランタイム:GPUで実行しています。

【2021年9月6日にコード修正時点のバージョン】
python 3.7.11
tensoflow 2.6.0
keras 2.6.0
sklearn(scikit-learn) 0.22.2.post1
opencv(opencv-python)4.1.2
matplotlib 3.2.2

【2023年2月14日にコード修正時点のバージョン】
python 3.8.10
tensoflow 2.11.0
keras 2.11.0
sklearn(scikit-learn) 1.0.2
opencv(opencv-python)4.6.0
matplotlib 3.2.2

 

 

① Googleアカウントでログイン & プログラムのコピー

 

 

Googleアカウントでログインした状態で、「ファイル – ドライブにメニューを保存」し、以下の手順を進めます。

 

 

② zipファイルをGoogle Colaboratoryにアップロードし、フォルダ化

 

 

オリジナルデータセットをアップロードします。

 

このプログラムでは、「判別したい “ラベル情報(フォルダ名)” と “画像” をセットにしたフォルダ」をアップロードすると動くようにしてあります。

今回のプログラムを動かすために必要なデータセットの構造例(機械学習用データセットの作り方)

 

dataset(フォルダ名)
(datasetフォルダ内のフォルダ名 – ラベル情報)
(datasetフォルダ内のフォルダ名 – ラベル情報)
(datasetフォルダ内のフォルダ名 – ラベル情報)
(datasetフォルダ内のフォルダ名 – ラベル情報)
(datasetフォルダ内のフォルダ名 – ラベル情報)
(datasetフォルダ内のフォルダ名 – ラベル情報)

* サンプルデータセットでは「Japanese_text_datase」というフォルダ名にしています。

 

データセットの作り方は簡単です。各フォルダ内に、対応する日本語の画像を配置するだけです。
画像の大きさは、特に指定はありませんが、実際に画像認識させたい画像の文字を使用すると精度が上がります。 また、「ゃゅょ」などの小さい文字を、大きい文字と区別させるためにも、実際に画像認識させたい画像で学習させるといいかもしれません。今回作成する日本語対応OCRでは、各文字の外接矩形を切り抜いた画像を判定することになるので、学習させる文字の大きさをバラバラにすると、(おそらく)小さい文字と大きい文字を区別できなくなります。

 

日本語手書き文字画像認識・日本語OCR用の学習済みモデル作成プログラムを動かすために必要なデータセットの構造例(機械学習用データセットの作り方)

 

!unzip Japanese_text_dataset.zip # 解凍:ここを変更。
# 「Japanese_text_dataset」のところをアップロードしたzipファイル名に変更してください。
#  ファイルを消す場合「!rm Japanese_text_dataset.zip」

 

 

③ 用意した自前画像で学習・学習済みモデルの保存(畳み込みニューラルネットワーク:CNN)

 

 

デフォルトでは、

:画像のカラーモード – モノクロ・グレースケール
:学習時の画像の大きさ – 横の幅14・縦の高さ14ピクセル

の「model.h5」という名前の学習済みモデルが保存されます。

 

 

#1 各種インポート

import keras
import glob
import numpy as np
from sklearn.model_selection import train_test_split
# from keras.preprocessing.image import load_img, img_to_array #ここでエラーとなるので以下のコードに変更
from tensorflow.keras.utils import load_img, img_to_array
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten
from keras.utils import np_utils
# from keras.optimizers import Adam # ここでエラーとなるので以下のコードに変更
from tensorflow.keras.optimizers import Adam # 「tensorflow.」を追加
import matplotlib.pyplot as plt
import time


#2 各種設定  

train_data_path = 'Japanese_text_dataset/*' # ここを変更。
                                            # Colaboratoryにアップロードしたzipファイルを解凍後の、データセットのフォルダ名を入力
image_width = 14   # ここを変更。
                   # 必要に応じて変更してください。「14」を指定した場合、縦の高さ14ピクセルの画像に変換します
image_height = 14  # ここを変更。
                   # 必要に応じて変更してください。「14」を指定した場合、横の幅14ピクセルの画像に変換します
                   # 画像のサイズを変更すると精度が大きく変動するようでした
color_setting = 1  # ここを変更。
                   # データセット画像のカラー指定:「1」はモノクロ・グレースケール。「3」はカラーとして画像を処理


#3 データセットの読み込みとデータ形式の設定・正規化・分割 

# パス内の全てのファイル・フォルダ名を取得
folder = glob.glob(train_data_path)

# 並び替え
folder =  sorted(folder)  
print(folder) 

class_number = len(folder)
print('今回のデータで分類するクラス数は「', str(class_number), '」です。')


X_image = []  
Y_label = [] 
for index, name in enumerate(folder):
  read_data = name
  files = glob.glob(read_data + '/*.png') # ここを変更。png形式のファイルを利用する場合のサンプルです。
  print('--- 読み込んだデータセットは',  read_data, 'です。')

  for i, file in enumerate(files):  
    if color_setting == 1:
      img = load_img(file, color_mode = 'grayscale' ,target_size=(image_width, image_height))  
    elif color_setting == 3:
      img = load_img(file, color_mode = 'rgb' ,target_size=(image_width, image_height))
    array = img_to_array(img)
    X_image.append(array)
    Y_label.append(index)

X_image = np.array(X_image)
Y_label = np.array(Y_label)

X_image = X_image.astype('float32') / 255
Y_label = np_utils.to_categorical(Y_label, class_number) 

train_images, valid_images, train_labels, valid_labels = train_test_split(X_image, Y_label, test_size=0.10)
x_train = train_images
y_train = train_labels
x_test = valid_images
y_test = valid_labels


#4 機械学習(人工知能)モデルの作成 – 畳み込みニューラルネットワーク(CNN)・学習の実行等

model = Sequential()
model.add(Conv2D(16, (3, 3), padding='same',
          input_shape=(image_width, image_height, color_setting), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))               
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(256, (3, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))                
model.add(Dropout(0.5))                                   
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))                                 
model.add(Dense(class_number, activation='softmax'))

model.summary()

model.compile(loss='categorical_crossentropy',
              optimizer=Adam(),
              metrics=['accuracy'])


start_time = time.time()


# ここを変更。
# 必要に応じて
# 「batch_size=」(バッチサイズ:重みとバイアスの更新を行う間隔の数)「epochs=」(学習回数)の数字を変更してみてください
history = model.fit(x_train,y_train, batch_size=10, epochs=30, verbose=1, validation_data=(x_test, y_test))



plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.grid()
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.grid()
plt.legend(['Train', 'Validation'], loc='upper left')
plt.show()

score = model.evaluate(x_test, y_test, verbose=0)
print('Loss:', score[0], '(損失関数値 - 0に近いほど正解に近い)') 
print('Accuracy:', score[1] * 100, '%', '(精度 - 100% に近いほど正解に近い)') 
print('Computation time(計算時間):{0:.3f} sec(秒)'.format(time.time() - start_time))


# 学習済みモデル(モデル構造と学習済みの重み)の保存
# 名前は自分がわかりやすい名前にしてください
model.save('model.h5') 

# モノクロ・グレー形式の学習済みモデルの例:color_setting = 1 にした場合  
#model.save('keras_cnn_japanese_handwritten_gray14*14_model.h5')

# カラー形式の学習済みモデルの例:color_setting = 3 にした場合  
#model.save('keras_cnn_japanese_handwritten_color14*14_model.h5') 

 

【出力結果例】

 

【日本語 - 手書き編】OCR用のオリジナル学習済みモデルの作成Model accuracy 出力例

 

【日本語 - 手書き編】OCR用のオリジナル学習済みモデルの作成Model loss 出力例

 

【日本語 - 手書き編】OCR用のオリジナル学習済みモデルの作成:出力結果例

 

日本語自作OCR開発:学習済みモデル

必要に応じて、学習済みモデルを自分のパソコンに保存します。
* 【ステップ4】日本語手書きOCR:横書き・縦書き文字認識 +再学 で今回作成した学習済みモデルを使います。

 

続いて、作成した日本語手書き文字認識の学習済みモデル「model.h5」を使い、1文字の画像認識をさせてみましょう。

 

【ステップ2】

【日本語 - 手書き編】1文字判定(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)機械学習

1文字判定(日本語手書き:ひらがな・カタカナ・漢字・ローマ字・点、・丸。)
【日本語 – 手書き編】1文字判定(ひらがな・カタカナ・漢字・ローマ字・、点・。丸)

 

 

この動画へのコメントと回答

 

 

データセット用の複数の画像を用意するのに効率的な方法はありますか?

 

 

【2024年8月20日時点】

以下に

【①「画像を複数枚用意する必要がある?」について】
【②「効率的な方法はありますでしょうか?」について】

について、現時点(2024年8月20日)で個人で分かる範囲ではありますが回答させていただきます。

 

【①「画像を複数枚用意する必要がある?」について】

ご質問いただいた

・「あ」という文字であれば、「あ」一文だけの画像を複数枚用意する必要があるということで間違いありませんでしょうか?

についてですが、単純にOCRの精度を上げたい場合には

・OCRしたい人の文字(筆跡)をデータセットとして利用する

といいかもしれません。
ですので、あらかじめ利用環境が想定できていれば

・想定人物らの文字(筆跡)を使う

といいかと思います。OCR予定の筆跡が、一人の場合には、一人の文字を(複数枚)、二人以上の場合には複数の画像を、同じように(複数枚)用意するといいのではないかと思います。
また、コンピュータの文字をOCRしたい場合には、

・OCR予定のフォントをデータセットとして利用する

といいかと思います。

 

【②「効率的な方法はありますでしょうか?」について】

ご質問いただいた

・複数の「あ」という画像を用意するためにはかなりの時間がかかってしまうのですが、なにか効率的な方法はありますでしょうか?

について回答させていただきます。

 

▶︎手順例1

以下の動画

チュートリアル動画:
【日本語 – 手書き編 #4】OCRに挑戦:横書き・縦書き文字認識 +再学習(平仮名・片仮名・漢字・ローマ字・点・丸)by RehabC – デジタルで、遊ぶ。(YouTube)

チュートリアルコード:
Japanese-handwritten-text-original-OCR-Basic.ipynb | Google Colaboratory

の「6分56秒」からの手順では、

・文字検出できた画像をダウンロードする手順

を解説していますので必要に応じて参考にしてみてください。
今回ご質問いただいたケースでは、1枚の紙に、様々な複数の「」を書いて、パソコン上にスキャンした画像を文字検出させると様々な「」の画像を用意できるのではないかと思います。

 

▶︎手順例2

情報を探してみると

文字画像作成機 | TOOL SITE

というサイトがあるようでした。
画像は1枚ずつ作成する必要はありますが、様々なフォントやサイズの画像を気軽に作成できそうでした。

 

▶︎手順例3

プログラミング的に実施したい場合には

・PyTorchではじめるAI開発

【PR:Amazonで詳しくみてみる】
PyTorchではじめるAI開発 | シーアンドアール研究所(2021年刊行)

の書籍の

・CHAPTER 08:OCRにおける文字認識 – SECTION 024 モデルを学習させる(P275)

のチャプターに

・一般的なTTFフォントデータから文字画像を作成する方法

が解説されています。
ただ現時点での自分の能力では、理解が追いついていないのでプログラムを実装できませんのでご了承ください。

 

上述のように、いくつかの方法例を挙げさせていただきましたが、現実的には

・とりあえず少量の「あ」のデータセットを作成して学習させてみて、OCRした結果、誤答した画像を追加

していけばいいのではないかと思います。
その際には、

・間違えた1枚の画像を様々な画像サイズにして、様々な位置でスクリーンショットを作成

すると効率的にデータセットを増やすことができるのではないかと思います。
また、特定の筆跡に対して精度を上げたいだけであれば

・同じ画像を名前を変えてデータセットフォルダに配置

すればいいかもしれません。

 

 

by 子供プログラマー | プログラミング入門ウェブ教室

 

【日本語手書きOCR編】連続文字画像認識プログラミング入門(Python・OpenCV・Keras・CNN)| 一覧ページ