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ベースの人工知能と機械学習アプリケーション

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

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

疫病流行中の人間の行動にAIが混乱!データ変更による作業の「異常」は手動での制御が必要

[[327938]]ビッグデータダイジェスト制作著者: 劉俊環半年前に Taobao をオープンした...

...

...

...

自動運転車を巡る最大の論争の一つは、それが保険業界にどのような影響を与えるかということだ。

自動運転車は新しい概念ではありません。ほぼすべての大手自動車メーカーが何らかの形の自動運転車を開発し...

GPT-3 ハイパーパラメータは単一の GPU で解決できます。まず小さなモデルをトレーニングし、ワンクリックで移行します

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

AIミドルプラットフォーム - インテリジェントチャットボットプラットフォームのアーキテクチャとアプリケーション

講演者紹介:王東:北京大学大学院 CreditEase テクノロジーセンター AI ミドルプラットフ...

...

効率が1200倍にアップ! MIT、医薬品製造向けの新たなAIモデルを開発

海外メディアTech Xploreによると、MITの研究者らは最近、新しいタンパク質分子の構造を事前...

...

ドローンは農業にも活用されており、植物保護ドローンは侵入の防止と制御に非常に効果的です。

今日のドローンは、ビデオ録画だけでなく、害虫や病気の問題を防ぐための農業での使用など、幅広い用途に使...

...

機械学習がゲームにおける物理シミュレーションに革命をもたらす

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...