ディープニューラルネットワークを使用してNER固有表現抽出の問題を解決する

ディープニューラルネットワークを使用してNER固有表現抽出の問題を解決する

この記事は次のように構成されています。

  1. 固有表現抽出 (NER) とは
  2. どのように識別しますか?

cs224d 7日目: プロジェクト2 - DNNを使用してNER問題を解決する

コース プロジェクトの説明 住所

NERとは何ですか?

固有表現抽出 (NER) とは、主に人名、地名、機関名、固有名詞など、テキスト内の特定の意味を持つエンティティを識別することを指します。固有表現認識は、情報抽出、質問応答システム、構文解析、機械翻訳などの応用分野における重要な基本ツールであり、構造化された情報を抽出する上で重要なステップです。 BosonNLPより抜粋

どのように識別しますか?

まず問題解決のロジックを説明し、次にメインコードを説明します。興味のある方は、完全なコードを見るためにここを参照してください。

このコードは、NER 問題を処理するために、Tensorflow の下で 1 つの隠し層のみを持つ DNN を構築します。

1. 問題の特定:

NER は分類問題です。

単語が与えられたら、文脈に基づいて次の 4 つのカテゴリのどれに属するかを判断する必要があります。次の 4 つのカテゴリのいずれにも属さない場合、カテゴリは 0 となり、エンティティではないことを意味します。したがって、これは 5 つのカテゴリに分割する必要がある問題です。

  1. • 人(PER)
  2. • 組織(ORG)
  3. • 場所 (LOC)
  4. • その他(MISC)

トレーニング データには 2 つの列があり、最初の列は単語、2 番目の列はラベルです。

  1. EU 組織
  2. 拒否する
  3. ドイツ語その他
  4. ピーター・パー
  5. ブリュッセル LOC

2. モデル:

次に、ディープニューラルネットワークを使用してトレーニングします。

モデルは次のとおりです。

入力層の x^(t) は、x_t を中心としたウィンドウ サイズ 3 のコンテキストです。x_t はワンホット ベクトルです。x_t と L を適用すると、対応する単語ベクトルになり、単語ベクトルの長さは d = 50 になります。

隠し層が 1 つだけのニューラル ネットワークを構築します。隠し層の次元は 100、y^ は予測値、次元は 5 です。

クロスエントロピーを使用してエラーを計算します。

J は各パラメータに関して微分されます。

次の導出式が得られます。

TensorFlow では、導出は自動的に実装されます。ここでは、Adam 最適化アルゴリズムを使用して勾配を更新し、収束するまで継続的に反復して損失を小さくしていきます。

3. 具体的な実施

def test_NER() では、max_epochs の反復を実行します。毎回、トレーニング データを使用してモデルをトレーニングし、train_loss と train_acc のペアを取得します。次に、このモデルを使用して検証データを予測し、val_loss と予測のペアを取得します。最小の val_loss を選択し、対応するパラメーターの重みを保存します。最後に、これらのパラメーターを使用して、テスト データのカテゴリ ラベルを予測します。

  1. テスト_NER()を定義します:
  2. config = 設定()
  3. tf.Graph().as_default() を使用する場合:
  4. model = NERModel(config) # メインクラス
  5.  
  6. 初期化 = tf.initialize_all_variables()
  7. セーバー = tf.train.Saver()
  8.  
  9. tf.Session() をセッションとして使用:
  10. best_val_loss = float ( 'inf' ) # 最良値、その損失、反復回数、エポック
  11. ベストバリューエポック = 0  
  12.  
  13. セッションの実行(初期化)
  14. xrange(config.max_epochs) のエポックの場合:
  15. 'Epoch {}'を印刷します。.format(epoch)
  16. 開始 = 時間.時間()
  17. ###
  18. train_loss、train_acc = model.run_epoch(セッション、model.X_train、
  19. model.y_train) # 1.訓練データを反復処理に投入し、損失と精度を取得します
  20. val_loss, predictions = model.predict(session, model.X_dev, model.y_dev) # 2.このモデルを使用して開発データを予測し、損失と予測を取得します
  21. 'トレーニング損失: {}'を印刷します。.format(train_loss)
  22. 'トレーニング acc: {}'を印刷します。.format(train_acc)
  23. '検証損失: {}'を印刷します。.format(val_loss)
  24. if val_loss < best_val_loss: # valデータの損失を使用して最小損失を見つける
  25. ベストバリューロス = バリューロス
  26. best_val_epoch = エポック
  27. os.path.exists( "./weights" )が存在しない場合は:
  28. os.makedirs( "./weights" )
  29.  
  30. saver.save(session, './weights/ner.weights' ) # 最小損失に対応する重みを保存します
  31. epoch - best_val_epoch > config.early_stoppingの場合:
  32. 壊す 
  33. ###
  34. 混乱 = calculate_confusion(config, predictions, model.y_dev) # 3. devラベルデータを入れて予測の混乱を計算する
  35. print_confusion(混乱、モデル.num_to_tag)
  36. '合計時間: {}'を印刷します。.format(time.time() - start)
  37.  
  38. saver.restore(session, './weights/ner.weights' ) # 保存した重みを再度読み込み、テストデータを使用して予測を行い、予測結果を取得します
  39. 'テスト'を印刷する 
  40. '=-=-='を印刷 
  41. '予測をq2_test.predictedに書き込んでいます' と印刷します 
  42. _、予測 = model.predict(セッション、model.X_test、model.y_test)
  43. save_predictions(predictions, "q2_test.predicted" ) # 予測結果を保存する
  44.  
  45. __name__ == "__main__"の場合:
  46. テスト_NER()

4. モデルはどのようにトレーニングされますか?

まず、データのトレーニング、検証、テストをインポートします。

  1. # トレーニングセットをロードする 
  2. docs = du.load_dataset( 'data/ner/train' )
  3.  
  4. # 開発セットをロードする(ハイパーパラメータの調整用)  
  5. docs = du.load_dataset( 'data/ner/dev' )
  6.  
  7. # テストセットをロードする(ダミーラベルのみ)  
  8. docs = du.load_dataset( 'data/ner/test.masked' )

単語をワンホットベクトルに変換した後、単語ベクトルに変換します。

  1. デフadd_embedding( self ):
  2. # 埋め込み検索は現在CPUにのみ実装されています 
  3. tf.device( '/cpu:0' ) の場合:
  4.  
  5. embedding = tf.get_variable( 'Embedding' , [len( self .wv), self .config.embed_size]) # 代入におけるL  
  6. window = tf.nn.embedding_lookup(embedding, self .input_placeholder) # ウィンドウサイズのコンテキストの単語ベクトルをLで直接取得します 
  7. ウィンドウ = tf.reshape(
  8. ウィンドウ、[- 1 self .config.window_size * self .config.embed_size])
  9.  
  10. 返品期間

最初のレイヤーを初期化するために xavier を使用し、L2 正則化とドロップアウトを使用してオーバーフィッティングを減らすなど、ニューラル レイヤーを構築します。

  1. def add_model(自己、 ウィンドウ):
  2.  
  3. tf.variable_scope( 'Layer1' , initializer=xavier_weight_init()) をスコープとして: # 最初のレイヤーを初期化するには、initializer=xavier を使用します 
  4. W = tf.get_variable( # *** レイヤーにはW、b1、hがあります 
  5. 'W' , [ self .config.window_size * self .config.embed_size,
  6. 自己.config.hidden_​​size])
  7. b1 = tf.get_variable( 'b1' , [ self.config.hidden_​​size ])
  8. h = tf.nn.tanh(tf.matmul(ウィンドウ、W) + b1)
  9. もし  self .config.l2: # W の L2 正規化 
  10. tf.add_to_collection( 'total_loss' , 0.5 * self.config.l2 * tf.nn.l2_loss(W)) # 0.5 * self.config.l2 * tf.nn.l2_loss(W)  
  11.  
  12. スコープとして tf.variable_scope( 'Layer2' , initializer=xavier_weight_init()) を使用します。
  13. U = tf.get_variable( 'U' , [ self .config.hidden_​​size, self .config.label_size])
  14. b2 = tf.get_variable( 'b2' , [ self.config.label_size ])
  15. y = tf.matmul(h, U) + b2
  16. もし 自己.config.l2:
  17. tf.add_to_collection( 'total_loss' 0.5 * self .config.l2 * tf.nn.l2_loss(U))
  18. output = tf.nn.dropout(y, self .dropout_placeholder) # 出力を返す。両方のvariable_scopesにドロップアウトがある 
  19.  
  20. 出力を返す

L2 正則化とドロップアウトとは何か、またオーバーフィッティングの問題を軽減する方法の詳細については、これらを簡潔かつ明確にまとめたこのブログ投稿をお読みください。

クロスエントロピーを使用して損失を計算します。

  1. def add_loss_op(自己, y):
  2.  
  3. cross_entropy = tf.reduce_mean( # 1. 重要なステップ: クロスエントロピーを使用して損失を定義する 
  4. tf.nn.softmax_cross_entropy_with_logits(y, self .labels_placeholder)) # yはモデル予測値、クロスエントロピーを計算する 
  5. tf.add_to_collection( 'total_loss' , cross_entropy) # 指定された名前のコレクションに値を保存します。  
  6. # コレクションはセットではないため、コレクションに値を複数回追加することが可能です。  
  7. loss = tf.add_n(tf.get_collection( 'total_loss' )) # すべての入力テンソルを要素ごとに追加します。 inputs: 同じ形状とタイプのテンソルのリスト 
  8.  
  9. リターンロス

次に、Adam Optimizer を使用して損失を最小限に抑えます。

  1. def add_training_op(自己、 損失 ):
  2.  
  3. オプティマイザー = tf.train.AdamOptimizer( self .config.lr)
  4. global_step = tf.Variable( 0 、名前 = 'global_step' 、トレーニング可能 = False )
  5. train_op = optimizer.minimize(loss, global_step=global_step) # 2. 重要なステップ: AdamOptimizerを使用して損失を最小化するため、より重要なのは損失です 
  6.  
  7. train_opを返す

各トレーニングの後、損失を最小限に抑える対応する重みが得られます。

このようにして、NER分類の問題は解決されます。もちろん、精度やその他の問題を改善するためには、引き続き文献を参照して研究する必要があります。次回はまずRNNを実装します。

<<:  ニューラルネットワークにおけるBPアルゴリズムの原理とPython実装のソースコード解析

>>:  IT運用保守プラットフォームアルゴリズムの背後にある2つの「神の助け」

ブログ    
ブログ    
ブログ    

推薦する

...

...

ニューロンクラスタリングはAIの学習戦略をシミュレートできる

人間や機械がタスクをよりうまく実行できるようになるたびに、証拠の痕跡が残ります。パフォーマンス向上の...

今後10年の予測レポート:高齢化が進み、幼児市場が縮小、AIが様々な製品に浸透

IDCはこのほど、2019年および今後10年間の中国の情報通信分野と技術応用に関するトップ10予測を...

テンセントクラウドが高性能アプリケーションサービスHAIを開始、すべての開発者が独自のAIアプリケーションを開発可能に

AIGC アプリケーション開発のハードルを下げることによってのみ、次の AIGC 驚異的アプリケーシ...

ガートナー:AIと自動化は次世代SASEの重要な機能となる

近年、セキュア アクセス サービス エッジ (SASE) テクノロジーは急速に発展し、産業界で広く使...

「突破」に注目! 2021年6月のドローン業界の重要な動向の概要

ドローンは無人航空機であり、センサー、インテリジェント制御、情報処理、電力システムなどの技術を統合し...

生成 AI: サイバーセキュリティにとってのメリットか、それとも危険か?

脅威の状況が絶えず変化する中、高度なサイバー攻撃に対する防御手段として、生成型人工知能 (GAI) ...

十分なデータを使用してモデルをトレーニングしたかどうかをどのように確認しますか?

[51CTO.com クイック翻訳]ディープニューラルネットワーク (DNN) には大量のトレーニ...

...

...

GANは音声を使って画像を生成できるようになった

[[432735]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

Googleは、自社のBardを含むチャットボットの使用には注意するよう従業員に警告している。

ロイター通信は6月19日、事情に詳しい4人の関係者の話として、グーグルの親会社アルファベットはチャッ...

2021年の人工知能と機械学習の5つのトレンド

人工知能と機械学習は長い間私たちの世界を変えてきましたが、2020年のコロナウイルスのパンデミックは...