ディープニューラルネットワークを使用して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つの「神の助け」

ブログ    
ブログ    

推薦する

IIHS:自動運転車は交通事故を3分の1しか減らせない

道路安全保険協会(IIHS)が実施した調査によると、自動運転車は期待したほど事故を減らさない可能性が...

人工知能が教室に導入されると、教育プロセスにどのような変化が起こるでしょうか?

人工知能技術の応用により、コースの内容、教授法、教師と生徒の関係が変化しています。人工知能の利用によ...

このモデルはGAN、ETH超解像モデルSRFlowよりも想像能力が強い

最近、ETH チューリッヒのコンピューター ビジョン研究所の研究者が超解像度モデル SRFlow を...

...

知恵くんの“いいとこ”が明らかに!初のユニバーサルな具現化ベースモデル、ロボットは「理解はできるができない」状態に別れを告げる

先週金曜日、知会君は微博で「来週は良いものがリリースされる」と発表した。 「来週」になって間もなく、...

...

なぜ「ハイエンド」アルゴリズムエンジニアはデータ移民労働者になったのでしょうか?

まず、Zhihu の「アルゴリズム エンジニアになるのはどんな感じか」という質問に対する私の回答を共...

...

マルチモーダルな大型モデルの幻覚が 30% 減少しました。 USTCらが初の錯視補正フレームワーク「Woodpecker」を提案

視覚幻覚は、マルチモーダル大規模言語モデル (MLLM) でよく見られる典型的な問題です。簡単に言え...

人工知能の台頭によりプログラマーは消滅するのでしょうか?

ローコードおよびノー​​コード プラットフォームの爆発的な成長により、個人でも組織でも、従来はコード...

人工知能が世界を席巻し、人類はサイボーグへと向かう必要がある

テスラのCEOイーロン・マスク氏はドバイでのイベントで人工知能の将来について語った。同氏は、人間より...

...

Canalys:2027年までにPCの60%がAI機能に対応し、出荷台数は1億7500万台を超える見込み

9月26日、市場調査会社Canalysが発表した最新レポートによると、現在のAIの波の中で、企業や消...

...

携帯電話開発者の年収は153万元、機械学習は最高ではない:IEEEの最新給与レポート

私たちは皆工学を勉強していますが、どの分野を選択すべきでしょうか?給与水準は、人々が将来のキャリアを...