TensorFlow2 を使用してアラビア語の手書き文字データセットを認識する方法を説明します

TensorFlow2 を使用してアラビア語の手書き文字データセットを認識する方法を説明します

[[405478]]

このチュートリアルでは、TensorFlow (Keras API) を使用して、データセット上のアラビア語の手書き文字を認識する必要があるマルチ分類タスク用のディープラーニング モデルを実装します。

データセットのダウンロードアドレス: https://www.kaggle.com/mloey1/ahcd1

データセットの紹介

このデータセットは、19 歳から 40 歳までの 60 人の参加者が書いた 16,800 文字で構成されており、参加者の 90% は右利きです。

図7(a)と7(b)に示すように、各参加者は「alef」から「yeh」までの各文字を両方の形式で10回書きました。フォームは 300 dpi の解像度でスキャンされました。各ブロックは Matlab 2016a を使用して自動的にセグメント化され、各ブロックの座標が決定されました。データベースは、トレーニング セット (クラスごとに 13,440 文字、480 画像) とテスト セット (クラスごとに 3,360 文字、120 画像) の 2 つのセットに分かれています。データ ラベルの範囲は 1 ~ 28 カテゴリです。ここで、すべてのデータセットは CSV ファイルであり、画像のピクセル値とそれに対応するラベルを表し、対応する画像データは提供されません。

モジュールのインポート

  1. numpyをnpとしてインポートする
  2. pandasをpdとしてインポートする
  3. # データフレームで display() の使用を許可します
  4. IPython.displayからdisplayをインポートする
  5. # 画像の読み込みと処理に必要なライブラリをインポートする
  6. csvをインポート
  7. PIL インポート画像から
  8. scipy.ndimageから回転をインポートする

データの読み取り

  1. # トレーニングデータ画像
  2. letters_training_images_file_path = "../input/ahcd1/csvTrainImages 13440x1024.csv"  
  3. # トレーニングデータラベル
  4. letters_training_labels_file_path = "../input/ahcd1/csvTrainLabel 13440x1.csv"  
  5. # テストデータの画像とラベル
  6. letters_testing_images_file_path = "../input/ahcd1/csvTestImages 3360x1024.csv"  
  7. letters_testing_labels_file_path = "../input/ahcd1/csvTestLabel 3360x1.csv"  
  8.  
  9. # データを読み込む
  10. training_letters_images = pd.read_csv(letters_training_images_file_path、ヘッダー=なし)
  11. training_letters_labels = pd.read_csv(letters_training_labels_file_path、ヘッダー=なし)
  12. テスト用文字画像 = pd.read_csv(文字画像ファイルパス、ヘッダー=なし)
  13. テスト文字ラベル = pd.read_csv(文字テストラベルファイルパス、ヘッダー=なし)
  14.  
  15. print( "%d 32x32 ピクセルのトレーニング用アラビア文字画像。" %training_letters_images.shape[0])
  16. print( "%d 32x32 ピクセルのアラビア文字のテスト画像。" %testing_letters_images.shape[0])
  17. トレーニングレター画像.head()

アラビア文字の 32 x 32 ピクセルのトレーニング画像 13440 枚。アラビア文字の 32 x 32 ピクセルのテスト画像 3360 枚。

トレーニングデータの先頭を表示する

  1. np.unique (トレーニング文字ラベル)
  2. 配列([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28], dtype=int32)

次に、csv 値を画像に変換し、対応する画像のピクセル値を表示する必要があります。

  1. def convert_values_to_image(image_values, display= False ):
  2. image_array = np.asarray(image_values)
  3. image_array = image_array.reshape(32,32).astype( 'uint8' )
  4. # 元のデータセットは反転されているので、np.flip を使用して反転し、rotate を使用して回転させて、より良い画像を取得します。
  5. 画像配列 = np.flip(画像配列、0)
  6. image_array = 回転(image_array, -90)
  7. new_image = Image.fromarray(image_array)
  8. display == Trueの場合:
  9. 新しい画像を表示()
  10. new_imageを返す
  11. 値を画像に変換する(training_letters_images.loc[0], True )

これは文字fです。

次に、データの前処理、主に画像の正規化を実行します。画像内の各ピクセルを 255 で割り、[0, 1] に正規化することで、画像を再スケーリングします。

  1. トレーニングレターイメージのスケール = トレーニングレターイメージ.values.astype ( 'float32' ) /255
  2. トレーニング文字ラベル =トレーニング文字ラベル.値.astype ( 'int32' )
  3. テスト文字画像のスケール =テスト文字画像.値.astype ( 'float32' )/255
  4. テスト文字ラベル =テスト文字ラベル.値.astype ( 'int32' )
  5. print( "スケーリング後の文字のトレーニング画像" )
  6. 印刷(training_letters_images_scaled.shape)
  7. トレーニング文字画像スケール[0:5]

出力は次のようになります

  1. スケーリング後の文字トレーニング画像
  2. (13440, 1024)

ラベル csv ファイルから、これはマルチクラス分類問題であることがわかります。次のステップは、分類ラベルをエンコードすることです。カテゴリ ベクトルを行列型に変換することをお勧めします。

出力形式は次のとおりです: 1 ~ 28、0 ~ 27 のカテゴリに変換されます。 「alef」から「yeh」までの文字には、分類番号0から27が付けられています。 to_categoricalは、カテゴリベクトルをバイナリ(0と1のみ)の行列型表現に変換します。

ここでは、keras ワンホットエンコーディングを使用してこれらのカテゴリ値をエンコードします。

ワンホットエンコーディングは、整数をバイナリ行列に変換します。この配列には 1 つの「1」のみが含まれ、残りの要素は「0」になります。

  1. keras.utilsからto_categoricalをインポートする
  2.  
  3. # ワンホットエンコーディング
  4. クラス数 = 28
  5.  
  6. トレーニング文字ラベルエンコード = to_categorical(トレーニング文字ラベル-1、num_classes=クラス数)
  7. テスト文字ラベルエンコード = to_categorical(テスト文字ラベル-1、num_classes=クラス数)

  1. # (13440, 1024)

以下では、TensorFlow をバックエンドとして使用する場合、Keras CNN では、形状 (nb_samples、行、列、チャネル) を持つ 4D 配列を入力として必要とするため、入力画像を 32x32x1 に再形成します。

ここで、nb_samples は画像 (またはサンプル) の合計数に対応し、rows、columns、channels はそれぞれ画像あたりの行数、列数、チャネル数に対応します。

  1. # 入力文字画像を32x32x1再形成します
  2. トレーニング文字画像のスケール = トレーニング文字画像のスケール.reshape([-1, 32, 32, 1])
  3. テスト文字画像のスケール = テスト文字画像のスケール.reshape([-1, 32, 32, 1])
  4.  
  5. 印刷(トレーニング文字イメージのスケール.shape、トレーニング文字ラベルのエンコード.shape、テスト文字イメージのスケール.shape、テスト文字ラベルのエンコード.shape)
  6. # (13440, 32, 32, 1) (13440, 28) (3360, 32, 32, 1) (3360, 28)

したがって、画像は 32x32 ピクセルのグレースケール画像なので、入力画像を (nb_samples, 32, 32, 1) の形状の 4D テンソルに再形成します。

  1. #入力文字画像を32x32x1に再形成する
  2. トレーニング文字画像のスケール = トレーニング文字画像のスケール.reshape([-1, 32, 32, 1])
  3. テスト文字画像のスケール = テスト文字画像のスケール.reshape([-1, 32, 32, 1])
  4.  
  5. 印刷(トレーニング文字イメージのスケール.shape、トレーニング文字ラベルのエンコード.shape、テスト文字イメージのスケール.shape、テスト文字ラベルのエンコード.shape)

設計モデル構造

  1. keras.modelsからSequentialをインポートする
  2. keras.layersからConv2D、MaxPooling2D、GlobalAveragePooling2D、BatchNormalization、Dropout、Dense をインポートします。
  3.  
  4. def create_model(オプティマイザー= 'adam' 、カーネル初期化子= 'he_normal' 、アクティベーション= 'relu' ):
  5. #モデルを作成する
  6. モデル = シーケンシャル()
  7. モデルを追加します(Conv2D(filters=16, kernel_size=3, padding= 'same' , input_shape=(32, 32, 1), kernel_initializer=kernel_initializer, activation=activation))
  8. モデルを追加します(BatchNormalization())
  9. モデルを追加します(MaxPooling2D(pool_size=2))
  10. model.add(ドロップアウト(0.2))
  11.  
  12. モデルを追加します(Conv2D(filters=32, kernel_size=3, padding= 'same' , kernel_initializer=kernel_initializer, activation=activation))
  13. モデルを追加します(BatchNormalization())
  14. モデルを追加します(MaxPooling2D(pool_size=2))
  15. model.add(ドロップアウト(0.2))
  16.  
  17. モデルを追加します(Conv2D(filters=64, kernel_size=3, padding= 'same' , kernel_initializer=kernel_initializer, activation=activation))
  18. モデルを追加します(BatchNormalization())
  19. モデルを追加します(MaxPooling2D(pool_size=2))
  20. model.add(ドロップアウト(0.2))
  21.  
  22. モデルを追加します(Conv2D(filters=128, kernel_size=3, padding= 'same' , kernel_initializer=kernel_initializer, activation=activation))
  23. モデルを追加します(BatchNormalization())
  24. モデルを追加します(MaxPooling2D(pool_size=2))
  25. model.add(ドロップアウト(0.2))
  26. モデルを追加します(GlobalAveragePooling2D())
  27.  
  28. #完全に接続された最終層
  29. model.add (Dense(28, activation= 'softmax' ))
  30.  
  31. # モデルをコンパイルする
  32. model.compile(損失= 'categorical_crossentropy' 、メトリック=[ 'accuracy' ]、オプティマイザー=オプティマイザー)
  33. リターンモデル

「モデル構造」

  • 最初の隠れ層は畳み込み層です。このレイヤーには、サイズが 3×3 の 16 個の特徴マップと relu という活性化関数があります。これは入力レイヤーであり、上記の構造を持つ画像が必要です。
  • 2 番目のレイヤーはバッチ正規化レイヤーで、トレーニング データとテスト データの特徴分布の変化を解決します。BN レイヤーは、入力活性化関数の入力を正規化するために活性化関数の前に追加されます。これにより、入力データのオフセットと拡大の問題が解決されます。
  • 3 番目のレイヤーは MaxPooling レイヤーです。最大プーリング層は入力をダウンサンプリングするために使用され、モデルが特徴について仮定を立てることを可能にし、過剰適合を減らします。また、学習するパラメータの数も減り、トレーニング時間も短縮されます。
  • 次のレイヤーはドロップアウトを使用した正規化レイヤーです。過剰適合を減らすために、レイヤー内のニューロンの 20% をランダムに除外するように構成されています。
  • 他の隠し層には、サイズ 3×3 の 32 個の特徴と、画像からより多くの特徴をキャプチャするための relu 活性化関数が含まれています。
  • 他の隠れ層には64個と128個の特徴、サイズ3×3、およびrelu活性化関数が含まれています。
  • 畳み込み層、MaxPooling、BatchNormalization、Regularization、および GlobalAveragePooling2D 層が 3 回繰り返されます。
  • 最後の層は(出力クラスの数)を持つ出力層であり、複数のクラスがあるため、ソフトマックス活性化関数を使用します。各ニューロンはそのクラスの確率を与えます。
  • これは多クラス分類問題であるため、カテゴリクロスエントロピーが損失関数として使用されます。ニューラル ネットワークのパフォーマンスを向上させるには、精度を指標として使用します。
  1. モデル = create_model(オプティマイザー = 'Adam' 、カーネル初期化子 = 'uniform' 、アクティベーション = 'relu' )
  2. モデル.要約()

「Keras は、Keras.utils.vis_utils モジュールでモデルの描画をサポートしています。このモジュールは、graphviz を使用して Keras モデルを描画するためのユーティリティ関数を提供します。」

  1. pydotをインポートする
  2. keras.utilsからplot_modelをインポートする
  3.  
  4. plot_model(モデル、to_file= "model.png" 、show_shapes= True )
  5. IPython.displayからImage をIPythonImageとしてインポートします。
  6. 表示(IPythonImage( 'model.png' ))

モデルをトレーニングし、batch_size=20 を使用してモデルをトレーニングし、15 エポックにわたってモデルをトレーニングします。

  1. keras.callbacksからModelCheckpoint をインポートします
  2.  
  3. # チェックポイントを使用して、後で使用するためにモデルの重みを保存します。
  4. チェックポインター = ModelCheckpoint(ファイルパス = 'weights.hdf5' 、詳細 = 1、save_best_only = True )
  5. history = model.fit(training_letters_images_scaled、training_letters_labels_encoded、validation_data=(testing_letters_images_scaled、testing_letters_labels_encoded)、epochs=15、batch_size=20、verbose=1、callbacks=[checkpointer])

トレーニング結果は次のとおりです。

最後に、Epochs は損失と精度の曲線をプロットします。

  1. matplotlib.pyplot をpltとしてインポートします。
  2.  
  3. def plot_loss_accuracy(履歴):
  4. # 損失
  5. plt.figure(図サイズ=[8,6])
  6. plt.plot(history.history[ '損失' ], 'r' ,線幅=3.0)
  7. plt.plot(history.history[ 'val_loss' ], 'b' 、線幅=3.0)
  8. plt.legend([ 'トレーニング損失' , '検証損失' ],fontsize=18)
  9. plt.xlabel( 'エポック' 、フォントサイズ=16)
  10. plt.ylabel( '損失' 、フォントサイズ=16)
  11. plt.title( '損失曲線' 、フォントサイズ=16)
  12.  
  13. # 正確さ
  14. plt.figure(図サイズ=[8,6])
  15. plt.plot(history.history[ '精度' ], 'r' ,線幅=3.0)
  16. plt.plot(history.history[ 'val_accuracy' ], 'b' 、線幅=3.0)
  17. plt.legend([ 'トレーニング精度' , '検証精度' ],fontsize=18)
  18. plt.xlabel( 'エポック' 、フォントサイズ=16)
  19. plt.ylabel( '精度' 、フォントサイズ=16)
  20. plt.title( '精度曲線' , fontsize=16)
  21.  
  22. plot_loss_accuracy(履歴)

「最適な検証損失を持つモデルをロードする」

  1. # 最適な検証損失を持つモデルをロードする
  2. モデルをロードして重み付けする( 'weights.hdf5' )
  3. メトリック = model.evaluate(testing_letters_images_scaled、testing_letters_labels_encoded、verbose=1)
  4. print( "テスト精度: {}" .format(metrics[1]))
  5. print( "テスト損失: {}" .format(metrics[0]))

出力は次のようになります。

  1. 3360/3360 [================================] - 0s 87us/ステップ
  2. テスト精度: 0.9678571224212646
  3. テスト損失: 0.11759862171020359

混同行列を印刷します。

  1. sklearn.metricsからclassification_reportをインポート
  2.  
  3. def get_predicted_classes(モデル、データ、ラベル=なし):
  4. image_predictions = model.predict(データ)
  5. 予測クラス = np.argmax(画像予測、軸=1)
  6. true_classes = np.argmax(ラベル、軸=1)
  7. 予測クラス、真のクラス、画像予測を返す
  8.  
  9. get_classification_report(y_true, y_pred): を定義します。
  10. 印刷(分類レポート(y_true, y_pred))
  11.  
  12.  
  13. y_pred、y_true、im​​age_predictions = get_predicted_classes(モデル、testing_letters_images_scaled、testing_letters_labels_encoded)
  14. get_classification_report(y_true, y_pred)

出力は次のようになります。

  1.           精度再現率 F1スコア サポート
  2.  
  3. 0 1.00 0.98 0.99 120
  4. 1 1.00 0.98 0.99 120
  5. 2 0.80 0.98 0.88 120
  6. 3 0.98 0.88 0.93 120
  7. 4 0.99 0.97 0.98 120
  8. 5 0.92 0.99 0.96 120
  9. 6 0.94 0.97 0.95 120
  10. 7 0.94 0.95 0.95 120
  11. 8 0.96 0.88 0.92 120
  12. 9 0.90 1.00 0.94 120
  13. 10 0.94 0.90 0.92 120
  14. 11 0.98 1.00 0.99 120
  15. 12 0.99 0.98 0.99 120
  16. 13 0.96 0.97 0.97 120
  17. 14 1.00 0.93 0.97 120
  18. 15 0.94 0.99 0.97 120
  19. 16 1.00 0.93 0.96 120
  20. 17 0.97 0.97 0.97 120
  21. 18 1.00 0.93 0.96 120
  22. 19 0.92 0.95 0.93 120
  23. 20 0.97 0.93 0.94 120
  24. 21 0.99 0.96 0.97 120
  25. 22 0.99 0.98 0.99 120
  26. 23 0.98 0.99 0.99 120
  27. 24 0.95 0.88 0.91 120
  28. 25 0.94 0.98 0.96 120
  29. 26 0.95 0.97 0.96 120
  30. 27 0.98 0.99 0.99 120
  31.  
  32. 精度 0.96 3360
  33. マクロ平均0.96 0.96 0.96 3360
  34. 戦闘平均0.96 0.96 0.96 3360

最後に、関連する予測の絵をいくつかランダムに描きます

  1. インデックス = np.random.randint(0, testing_letters_labels.shape[0],サイズ=49)
  2. y_pred = np.argmax(model.predict(training_letters_images_scaled)、軸=1)
  3.  
  4. i , idx をenumerate(インデックス)指定します:
  5. plt.サブプロット(7,7,i+1)
  6.          
  7. image_array = トレーニング文字画像のスケール[idx][:,:,0]
  8. 画像配列 = np.flip(画像配列、0)
  9. image_array = rotate(image_array, -90)
  10.         
  11. plt.imshow(image_array, cmap= 'グレー' )
  12. plt.title( "予測: {} - ラベル: {}" .format(y_pred[idx], (training_letters_labels[idx] -1)))
  13. plt.xticks([])
  14. plt.yticks([])
  15. plt.show()

<<:  GPUベースの人工知能と機械学習アプリケーション

>>:  ハイパーオートメーションはビジネスの未来か?企業にとって何ができるのでしょうか?

ブログ    

推薦する

大規模言語モデルの新しいレビューが発表されました。51ページの論文では、LLM分野の専門技術について説明しています。

大規模言語モデル (LLM) は、自然言語処理 (NLP) の分野で目覚ましい進歩を可能にし、幅広い...

...

マイクロソフト、進化拡散法を用いたタンパク質生成のための新しい AI フレームワーク EvoDiff をオープンソース化

進化により、細胞プロセスを正確に制御する多様な機能性タンパク質が生み出されました。近年、この多様性か...

...

データは今日のビジネスに競争上の優位性をもたらすことができるのでしょうか?

データは今やさまざまな産業に統合され、世界市場のハイライトとなっています。現在の経済成長はデータと切...

初心者にも優しい!楽しくて簡単に始められる AI プロジェクト 10 選 (Python ソース コード付き)

ビッグデータダイジェスト制作出典: piprogramming編纂者:清寧人工知能は私たちの生活の一...

地球外文明の探査における人工知能技術の応用

近年、人工知能(AI)は急速に発展し、さまざまな分野で画期的な進歩を遂げています。中国の著名な学者、...

...

マイクロソフトはソフトからハードへの変革に向けてカスタム AI チップを開発中。その計画とは?

噂は本当で、Microsoft は大規模な言語モデルのトレーニングに使用できるカスタム AI チップ...

「人工知能のゴッドファーザー」ジェフリー・ヒントン氏は再び警告した。AIが人間に取って代わるかもしれない

10月10日、「人工知能のゴッドファーザー」として知られるジェフリー・ヒントン氏は、人工知能は危険で...

130 の大学が人工知能専攻を追加。次の「陥没穴」専攻になるのでしょうか?

大学の専攻の盛衰は、時代の発展と技術の進歩を最もよく物語る証拠でもあります。今日のいわゆる「落とし穴...

...

...

2021年に機械学習を学ぶには?この詳細なガイドがあなたをカバーします!

「すべての人にAI」の時代を迎え、多くの人が機械学習(ML)に何らかの形で触れるようになりました。...

量子超越性のマイルストーン! Googleの量子コンピュータは47年分の計算を6秒で完了し、世界初のスーパーコンピュータを上回る

Googleは再び「量子超越性」を達成したのか?最近、Google は、同社の量子コンピュータが、世...