{"cells":[{"metadata":{},"cell_type":"markdown","source":"[BERT for Humans: Tutorial+Baseline](https://www.kaggle.com/abhinand05/bert-for-humans-tutorial-baseline)の日本語訳です。(だいぶgoogle翻訳です)"},{"metadata":{},"cell_type":"markdown","source":"![](http://)<font size=4 color='#25171A'>This is a two part Notebook</font>\n\n<a href=\"#Comprehensive-BERT-Tutorial\">1. Comprehensive BERT Tutorial</a> <br>\n<a href=\"#Code-Implementation-in-Tensorflow-2.0\">2. Implementation in Tensorflow 2.0</a>\n<br>\n\n> **Note:** このノートブックの主な目的は、**このコンテストのベースラインと、BERTについての説明**を提供することです。 NLPコンペティションで仕事を始めたとき、このようなノートを見つけられなかったので、私はそのようなノートを使いたいと思いました。 初心者がこのノートブックの恩恵を受けることを願っています。 あなたが初心者であっても、このノートブックに興味があるかもしれない要素があるかもしれません。\n\n<br>"},{"metadata":{},"cell_type":"markdown","source":"<font size=4 color='red'>If you like this approach please give this kernel an UPVOTE to show your appreciation</font>"},{"metadata":{},"cell_type":"markdown","source":"# Comprehensive BERT Tutorial\n\n## Introduction\n<font size=\"3\" color='#003249'>数か月かけて初心者としてComputer Visionモデルを作成してからNLPを始めたばかりなら、このカーネルはきっとあなたにぴったりのものです.</font>\n<br>\n\nこの最新の最先端のNLPモデルBERTを理解するのに苦労しました。BERTとは何かを本当に把握するために、多くの記事を掘り下げなければなりませんでした。 このノートブックでBERTの私の理解を共有します。\n\n![](https://cdn-images-1.medium.com/max/1000/1*-oQKmzvHrzqeSQEnM9f_kQ.png)\n\n## Contents\n<a href=\"#The-BERT-Landscape\">1. The BERT Landscape</a>  \n<a href=\"#What-is-BERT?\">2. What is BERT?</a>  \n<a href=\"#Why-BERT-matters?\">3. Why BERT Matters?</a>\n<br>\n<a href=\"#How-BERT-Works?\">4. How BERT works?</a> <br>\n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#1.-Architecture-of-BERT\">4.1 Architecture of BERT</a>   \n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#2.-Preprocessing-Text-for-BERT\">4.2 Preprocessing text for BERT</a>   \n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#3.-Pre-training\">4.3 Pre-training</a>   \n<a href=\"#5.-Fine-Tuning_Techniques-for-BERT\">5. Fine Tuning Techniques for BERT</a> <br>\n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#5.1-Sequence-Classification-Tasks\">5.1 Sequence Classification Tasks</a>   \n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#5.2-Sentence-Pair-Classification-Tasks\">5.2 Sentence Pair Classification Tasks</a>   \n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#5.3-Question-Answering-Tasks\">5.3 Question Answering Tasks</a><br>\n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#5.4-Single-Sentence-Tagging-Tasks\">5.4 Single Sentence Tagging  Tasks</a><br> \n&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#5.5-Hyperparameter-Tuning\">5.5 Hyperparameter Tuning</a><br>\n<a href=\"#6.-BERT-Benchmarks-on-Question-Answering-Tasks\">6. BERT Benchmarks on Question/Answering Tasks</a> <br>\n<a href=\"#7.-Key-Takeaways\">7. Key Takeaways</a> <br>\n<a href=\"#8.-Conclusion\">8. Conclusion</a>"},{"metadata":{},"cell_type":"markdown","source":"## 1. The BERT Landscape\n\n> BERTは、さまざまな自然言語処理タスクでSOTAを達成しているDLモデルです。 BERTは **Bidirectional Encoder Representations for Transformers**の略です。 ウィキペディアとBooksCorpusで事前にトレーニングされていて、（特定の）タスク固有の微調整が必要です。\n \n **Question Answering（SQuAD v1.1）**、**Natural Language Inference（MNLI）**など、さまざまなNLPタスクでSOTAを達成し、機械学習コミュニティに大きな衝撃を与えました。\n \n BERTがNLPの状況を大きく変えたと言っても過言ではありません。 11の個々のNLPタスクで、大きなラベルのないデータセットでトレーニングされたモデルを使用し，SOTAをを達成しました。モデルの再学習もほとんど行っていません． これは、NLPモデルの設計方法の構造的変化を示しています。\n\nBERTは、GoogleのTransformerXL、OpenAIのGPT-2、XLNet、ERNIE2.0、RoBERTaなど、最近の多くのNLPアーキテクチャ、トレーニングアプローチ、および言語モデルに影響を与えました。"},{"metadata":{},"cell_type":"markdown","source":"## 2. What is BERT?\n\nBERTは基本的に、Transformerエンコーダーを積み重ねたものです（Transformer全体ではなく、エンコーダーのみです）。 双方向性の概念は、BERTとその前身であるOpenAI GPTの主な違いです。 BERTは双方向性です。これは、self-attention層が双方向でself-attentionを実行するためです。\n\nこのセッションでいくつか説明したいことがあります．\n\n1. BERTは、TransformersのBidirectional Encoder Representationsの略です。 それぞれの言葉には意味があり、理解する必要があります。 今のところ、**このtopicの重要なポイントは次のとおりです。BERTはTransformerアーキテクチャに基づいています。**\n\n2. BERTは** Wikipedia全体（25億語！）とBook Corpus（8億語）を含む、ラベルのないテキストの大規模なコーパスで事前に訓練されています**。 この事前トレーニング手順は、BERTの成功にとって非常に重要です。 大きなテキストコーパスでモデルをトレーニングすると、モデルが言語のしくみをより深く密接に理解し始めるためです。 この知識は、ほとんどすべてのNLPタスクに役立ちます。\n\n3. BERTは**deeply bidirectional**のモデルです。 双方向とは、BERTがトレーニングフェーズ中にトークンのコンテキストの左側と右側の両方から情報を学習することを意味します。\n\nこの双方向性の理解は、NLPモデルを次のレベルに引き上げるために不可欠です。 それが本当に何を意味するかを理解するための例を見てみましょう。 同じ単語を持つ2つの文がある場合もありますが、その意味は、以下に示すように前後に基づいて完全に異なる場合があります。\n\n![bidirectionalexample](https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2019/09/sent_context.png)\n\nこれらのコンテキストを考慮しないと、DLモデルが真に意味を理解することは不可能であり、何度も何度も無駄な応答を投げることがあり，良いことではありません。\n\nBut BERT fixes this. Yes it does. That was one of the game changing aspect of BERT.\n\nしかし、BERTはこれを修正します。\n\n4. 最後に、BERTの最大の利点は、**ImageNetのような衝撃**をもたらすことです。BERTの最も印象的な側面は、いくつかの追加の出力レイヤーを追加して状態を作成することで微調整でき，さまざまなNLPタスクのSOTAを達成しました．\n"},{"metadata":{},"cell_type":"markdown","source":"## 3. Why BERT matters?\n\nBERTが有能である要因を見ていきましょう．\n\n![stats](https://miro.medium.com/max/1200/0*-k_fjBnCuByNye4v)\n\nすべてのGLUEタスクが非常に有意義なTransformer（Open-GPT、BERT、BigBird）というエンコーダーに基づく汎用モデルであることは明らかではありませんが、たった一年でタスク専用モデルと人間のパフォーマンスのギャップを埋めました。"},{"metadata":{},"cell_type":"markdown","source":"## 4. How BERT Works?\nBERTを少し詳しく見て、それがなぜ言語をモデル化するのに効果的なのかを見ていきましょう。 BERTができることは既に見てきましたが、どうすればそれができますか？ このセクションでは、この関連する質問に答えます。\n\n### 1. Architecture of BERT\nBERTは、多層双方向トランスフォーマーエンコーダーです。 この論文では2つのモデルが紹介されています。\n\n* BERT base – 12 layers (transformer blocks), 12 attention heads, and 110 million parameters.\n* BERT Large – 24 layers, 16 attention heads and, 340 million parameters.\n\nBERT（別名トランスフォーマー）の構成要素を深く理解するには、必ず確認してください。\n\n[this awesome post](http://jalammar.github.io/illustrated-transformer/) – The Illustrated Transformers.\n\n*下図がBERTアーキテクチャを表しています。*\n![arch](https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2019/09/bert_encoder.png)\n\n### 2. Preprocessing Text for BERT\n\nBERTで使用される入力表現は、トークンの単一シーケンス内の単一のテキスト文と1組の文（質問、回答など）を表すことができます。\n\n* すべての入力シーケンスの最初のトークンは、特別な分類トークン**[CLS]** です。 このトークンは、分類タスクでシーケンス表現全体の集約として使用されます。 非分類タスクでは無視されます。\n\n* 単一テキスト文のタスクの場合、この**[CLS]** トークンの後には、WordPieceトークンと区切りトークン**[SEP]** が続きます。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig7.png)\n\n* 文ペアタスクの場合、2つの文のWordPieceトークンは別の[SEP]トークンで区切られます。 この入力シーケンスは、**[SEP]** トークンでも終了します。\n\n* 文Aまたは文Bを示す埋め込み文が各トークンに追加されます。 文の埋め込みは、語彙が2のトークン/単語の埋め込みに似ています。\n\n* シーケンス内の位置を示すために、位置埋め込みも各トークンに追加されます。\n\nBERT開発者は、モデルに入力する前に言語を表す特定のルールセットを設定しました。\n\n![](https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2019/09/bert_emnedding.png)\n\nまず第一に、すべての入力埋め込みは3つの埋め込みの組み合わせです。：\n\n* **位置の埋め込み(Position Embeddings)**：BERTは、位置の埋め込みを学習および使用して、文中の単語の位置を表現します。 これらは、RNNとは異なり、「シーケンス」または「順序」情報をキャプチャできないTransformerの制限を克服するために追加されます\n\n* **セグメントの埋め込み**：BERTは、タスクの入力として文のペアを受け取ることもできます（質問-回答）。 そのため、モデルが1番目と2番目の文を区別できるように、1番目と2番目の文に独自の埋め込みを学習します。 上記の例では、EAとしてマークされたすべてのトークンは文Aに属しています（EBについても同様）\n\n* **トークンの埋め込み(Token Embeddings)**：これらは、WordPieceトークンボキャブラリーから特定のトークンについて学習した埋め込みです。\n\n指定されたトークンについて、その入力表現は、**対応するトークン、セグメント、および位置の埋め込みを合計する**ことによって構築されます。\n\nこのような包括的な埋め込みスキームには、モデルに役立つ多くの情報が含まれています。\n\n前処理ステップのこれらの組み合わせにより、BERTは非常に用途が広がります。 これは、モデルのアーキテクチャに大きな変更を加えることなく、複数の種類のNLPタスクでモデルを簡単にトレーニングできることを意味します。\n\n**トークン化(Tokenization)**\nBERTはWordPieceトークン化を使用します。 語彙は、言語内のすべての個々の文字で初期化され、その後、語彙内の既存の単語の最も頻繁/可能性の高い組み合わせが繰り返し追加されます。\n\n### 3. Pre Training\nモデルは2つのタスクで同時に訓練されました:\n\n**1. Masked言語モデル(Masked Language Model)** \n\n**2. 次の文章予測(Next Sentence Prediction.)**\n\n**Note:** このノートブックでは、これらの2つの手法については説明しません。オンラインで読むことをお勧めします。\n"},{"metadata":{},"cell_type":"markdown","source":"## 5. Fine Tuning Techniques for BERT\n特定のタスクにBERTを使用するのは比較的簡単です。 BERTは、コアモデルに小さなレイヤーを追加するだけで、さまざまな言語タスクに使用できます。\n\n### 5.1 Sequence Classification Tasks\n**[CLS]** トークンの最終的なhidden stateは、入力シーケンスの固定次元プール表現として取得されます。 これは分類レイヤーに送られます。 分類レイヤーは、追加される唯一の新しいパラメーターであり、K x Hの次元を持ちます。ここで、Kは分類ラベルの数、Hはhidden stateのサイズです。 ラベル確率は、softmaxで計算されます。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig1-1.png?w=460&h=400)\n\n### 5.2 Sentence Pair Classification Tasks\nこの手順は、単一シーケンス分類タスクとまったく同じです。 唯一の違いは、2つの文が連結される入力表現です。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig2-1.png?w=443&h=398)\n\n### 5.3 Question-Answering Tasks (Goal of this competition)\n質問への回答は予測タスクです。 質問と文脈paragraphが与えられると、モデルは、質問に回答する可能性が最も高いparagraphから開始トークンと終了トークンを予測します。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig6.png?w=389&h=297)\n\n文のペアのタスクと同様に、質問は入力シーケンスの最初の文になり、paragraphは2番目の文になります。 隠された形状サイズに等しいサイズの開始ベクトルと終了ベクトルの微調整中に学習される2つの新しいパラメーターのみがあります。 トークンiが応答スパンの開始である確率は、softmax（S . K）として計算されます。ここで、Sは開始ベクトルで、Kはトークンiの最終的なトランス出力です。 同じことが終了トークンにも当てはまります。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig3.png?w=452&h=380)\n\n### 5.4 Single Sentence Tagging Tasks\n名前付きエンティティ認識などの単一文のタグ付けタスクでは、入力内のすべての単語に対してタグを予測する必要があります。 すべての入力トークンの最終的なhidden states（トランスフォーマー出力）が分類レイヤーに供給され、すべてのトークンの予測が取得されます。 WordPieceトークナイザーは一部の単語をサブワードに分割するため、単語の最初のトークンのみの予測が考慮されます。\n\n![](https://yashuseth.files.wordpress.com/2019/06/fig4.png?w=441&h=389)\n\n### 5.5 Hyperparameter Tuning\n最適なハイパーパラメーター値はタスク固有です。 しかし、著者は、次の範囲の値がすべてのタスクでうまく機能することを発見しました\n\n* **Dropout** – 0.1\n* **Batch Size** – 16, 32\n* **Learning Rate (Adam)** – 5e-5, 3e-5, 2e-5\n* **Number of epochs** – 3, 4 (yeah you read it right)\n\n著者はまた、大きなデータセット（> 100kのラベル付きサンプル）は、小さなデータセットよりもハイパーパラメーターの選択に対する感度が低いことを発見しました。"},{"metadata":{},"cell_type":"markdown","source":"## 6. BERT Benchmarks on Question Answering tasks\n> Standford Question Answering Dataset（SQuAD）は、クラウドソーシングされた10万の質問/回答ペアのコレクションです(Rajpurkar et al., 2016)。 質問と回答を含むウィキペディアからのparagraphが与えられた場合、タスクはparagraph内の\"answer text span\"を予測することです。\n\nSQUADでは、BERTラージによってパフォーマンスの大きな改善が達成されました。 最高のスコアを達成したモデルは、BERTラージモデルのアンサンブルで、TriviaQAでデータセットを増強しました。\n\n![](https://miro.medium.com/max/558/1*CYzIm-u1-JUR2jDyPRHlQg.png)"},{"metadata":{},"cell_type":"markdown","source":"## 7. Key Takeaways\n\n> 1) 巨大な規模であっても、モデルのサイズは重要です。 BERT_largeは、345百万のパラメーターを持ち、この種の最大のモデルです。 小規模なタスクでは、1億1千万の「わずか」のパラメータで同じアーキテクチャを使用するBERT_baseよりも明らかに優れています。\n\n> 2) 十分なトレーニングデータがあれば、より多くのトレーニングステップがより高い精度につながります。 たとえば、MNLIタスクでは、同じバッチサイズの500Kステップと比較して、1Mステップ（128,000ワードバッチサイズ）でトレーニングすると、BERT_baseの精度が1.0％向上します。\n\n> 3) BERTの双方向アプローチ（MLM）は、左から右へのアプローチ(left-to-right approaches)よりも収束が遅くなります（各バッチで予測されるのは単語の15％のみであるため）\n\n![](https://miro.medium.com/max/1576/0*KONsqvDohE7ytu_E.png)"},{"metadata":{},"cell_type":"markdown","source":"## 8. Conclusion\nBERTは、自然言語処理のための機械学習の使用における間違いなくブレークスルーです。 これは親しみやすく、高速な微調整が可能なため、将来的には幅広い実用的なアプリケーションが可能になるでしょう。 この要約では、過度の技術的詳細にdrれずに、論文の主要なアイデアを説明しようとしました。 さらに深く掘り下げたい場合は、記事全体とその中で参照されている補助的な記事を読むことを強くお勧めします。\n\n> **コメントセクションでこのノートブックを改善するための提案をお気軽にお寄せください（もしあれば）**"},{"metadata":{},"cell_type":"markdown","source":"<font size=5 color='green'>Please give this kernel an UPVOTE to show your appreciation, if you find it useful.</font>"},{"metadata":{},"cell_type":"markdown","source":"# Code Implementation in Tensorflow 2.0\n\n> **Note:** The code for this notebook is taken from the [translated version](https://www.kaggle.com/dimitreoliveira/using-tf-2-0-w-bert-on-nq-translated-to-tf2-0) posted by [Dimitre Oliviera](https://www.kaggle.com/dimitreoliveira)"},{"metadata":{},"cell_type":"markdown","source":"**This is a translated version of the baseline [script](https://www.kaggle.com/philculliton/using-tensorflow-2-0-w-bert-on-nq) from the Tensorflow team**\n\n**OlivieraはスクリプトをTensorflow 2.0バージョンに変換しました。これにより、TF2賞に参加でき、作業を改善するためにこのバージョンを使用できます。**\n\n**A few notes:**\n- If you want to keep using **flags** and **logging** you will have to use the **absl** lib (this is recommended by the TF team).\n- Since we won't use it with the kernels, he removed most of the **TPU** related stuff to reduce complexity.\n- Tensorflow 2 don't let us use global variables **(tf.compat.v1.trainable_variables())**.\n- If you have experience with Tensorflow 2 or have any correction/improvement, please let him know.\n\n**A few notes:**\n- **flags**と**logging**を使い続けたい場合は、**absl** libを使用する必要があります（TFチームが推奨します）。\n- カーネルでは使用しないので、複雑さを軽減するために**TPU**関連のもののほとんどを削除しました。\n- Tensorflow2ではグローバル変数を使用できません**(tf.compat.v1.trainable_variables())**\n- Tensorflow2の経験がある場合、または修正/改善がある場合は、知らせてください\n\nこのノートブックでは、TensorflowのBertベースラインを使用して、Natural Questionsテストセットの予測を作成します。 これは、事前に訓練されたモデルを使用していることに注意してください-ここでは推論のみを行っています。 GPUが必要です。これには1〜2時間かかります。\n\nThe original script can be found [here](https://github.com/google-research/language/blob/master/language/question_answering/bert_joint/run_nq.py).\nThe supporting modules were drawn from the [official Tensorflow model repository](https://github.com/tensorflow/models/tree/master/official). The bert-joint-baseline data is described [here](https://github.com/google-research/language/tree/master/language/question_answering/bert_joint).\n\n**Note:** 　このベースラインは、TF1.xから移行されたコードを使用します。 tf.compat.v1の使用が含まれていることに注意してください。tf.compat.v1は、このコンペティションのTF2.0賞の対象となることは許可されていません(https://www.kaggle.com/c/tensorflow2-question-answering/overview/prizes). It is intended to be used as a starting point, but we're excited to see how much better you can do using TF2.0!"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\n# import tf2_0_baseline_w_bert as tf2baseline # old script\nimport tf2_0_baseline_w_bert_translated_to_tf2_0 as tf2baseline # Oliviera's script\nimport bert_modeling as modeling\nimport bert_optimization as optimization\nimport bert_tokenization as tokenization\nimport json\nimport absl\nimport sys\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Tensorflow flagsは、TFシステム内で渡すことができる変数です。 以下のすべてのフラグには、フラグの内容と使用方法に関するコンテキストが提供されています。**\n\n**これらのほとんどは、下部にある特別なフラグを除き、必要に応じて変更できます。特別なフラグは、Kaggleバックエンドで動作するようにそのまま維持する必要があります。**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def del_all_flags(FLAGS):\n    flags_dict = FLAGS._flags()\n    keys_list = [keys for keys in flags_dict]\n    for keys in keys_list:\n        FLAGS.__delattr__(keys)\n\ndel_all_flags(absl.flags.FLAGS)\n\nflags = absl.flags\n\nflags.DEFINE_string(\n    \"bert_config_file\", \"/kaggle/input/bertjointbaseline/bert_config.json\",\n    \"The config json file corresponding to the pre-trained BERT model. \"\n    \"This specifies the model architecture.\")\n\nflags.DEFINE_string(\"vocab_file\", \"/kaggle/input/bertjointbaseline/vocab-nq.txt\",\n                    \"The vocabulary file that the BERT model was trained on.\")\n\nflags.DEFINE_string(\n    \"output_dir\", \"outdir\",\n    \"The output directory where the model checkpoints will be written.\")\n\nflags.DEFINE_string(\"train_precomputed_file\", None,\n                    \"Precomputed tf records for training.\")\n\nflags.DEFINE_integer(\"train_num_precomputed\", None,\n                     \"Number of precomputed tf records for training.\")\n\nflags.DEFINE_string(\n    \"output_prediction_file\", \"predictions.json\",\n    \"Where to print predictions in NQ prediction format, to be passed to\"\n    \"natural_questions.nq_eval.\")\n\nflags.DEFINE_string(\n    \"init_checkpoint\", \"/kaggle/input/bertjointbaseline/bert_joint.ckpt\",\n    \"Initial checkpoint (usually from a pre-trained BERT model).\")\n\nflags.DEFINE_bool(\n    \"do_lower_case\", True,\n    \"Whether to lower case the input text. Should be True for uncased \"\n    \"models and False for cased models.\")\n\nflags.DEFINE_integer(\n    \"max_seq_length\", 384,\n    \"The maximum total input sequence length after WordPiece tokenization. \"\n    \"Sequences longer than this will be truncated, and sequences shorter \"\n    \"than this will be padded.\")\n\nflags.DEFINE_integer(\n    \"doc_stride\", 128,\n    \"When splitting up a long document into chunks, how much stride to \"\n    \"take between chunks.\")\n\nflags.DEFINE_integer(\n    \"max_query_length\", 64,\n    \"The maximum number of tokens for the question. Questions longer than \"\n    \"this will be truncated to this length.\")\n\nflags.DEFINE_bool(\"do_train\", False, \"Whether to run training.\")\n\nflags.DEFINE_bool(\"do_predict\", True, \"Whether to run eval on the dev set.\")\n\nflags.DEFINE_integer(\"train_batch_size\", 32, \"Total batch size for training.\")\n\nflags.DEFINE_integer(\"predict_batch_size\", 8,\n                     \"Total batch size for predictions.\")\n\nflags.DEFINE_float(\"learning_rate\", 5e-5, \"The initial learning rate for Adam.\")\n\nflags.DEFINE_float(\"num_train_epochs\", 3.0,\n                   \"Total number of training epochs to perform.\")\n\nflags.DEFINE_float(\n    \"warmup_proportion\", 0.1,\n    \"Proportion of training to perform linear learning rate warmup for. \"\n    \"E.g., 0.1 = 10% of training.\")\n\nflags.DEFINE_integer(\"save_checkpoints_steps\", 1000,\n                     \"How often to save the model checkpoint.\")\n\nflags.DEFINE_integer(\"iterations_per_loop\", 1000,\n                     \"How many steps to make in each estimator call.\")\n\nflags.DEFINE_integer(\n    \"n_best_size\", 20,\n    \"The total number of n-best predictions to generate in the \"\n    \"nbest_predictions.json output file.\")\n\nflags.DEFINE_integer(\n    \"verbosity\", 1, \"How verbose our error messages should be\")\n\nflags.DEFINE_integer(\n    \"max_answer_length\", 30,\n    \"The maximum length of an answer that can be generated. This is needed \"\n    \"because the start and end predictions are not conditioned on one another.\")\n\nflags.DEFINE_float(\n    \"include_unknowns\", -1.0,\n    \"If positive, probability of including answers of type `UNKNOWN`.\")\n\nflags.DEFINE_bool(\"use_tpu\", False, \"Whether to use TPU or GPU/CPU.\")\nflags.DEFINE_bool(\"use_one_hot_embeddings\", False, \"Whether to use use_one_hot_embeddings\")\n\nabsl.flags.DEFINE_string(\n    \"gcp_project\", None,\n    \"[Optional] Project name for the Cloud TPU-enabled project. If not \"\n    \"specified, we will attempt to automatically detect the GCE project from \"\n    \"metadata.\")\n\nflags.DEFINE_bool(\n    \"verbose_logging\", False,\n    \"If true, all of the warnings related to data processing will be printed. \"\n    \"A number of warnings are expected for a normal NQ evaluation.\")\n\nflags.DEFINE_boolean(\n    \"skip_nested_contexts\", True,\n    \"Completely ignore context that are not top level nodes in the page.\")\n\nflags.DEFINE_integer(\"task_id\", 0,\n                     \"Train and dev shard to read from and write to.\")\n\nflags.DEFINE_integer(\"max_contexts\", 48,\n                     \"Maximum number of contexts to output for an example.\")\n\nflags.DEFINE_integer(\n    \"max_position\", 50,\n    \"Maximum context position for which to generate special tokens.\")\n\n\n## Special flags - do not change\n\nflags.DEFINE_string(\n    \"predict_file\", \"/kaggle/input/tensorflow2-question-answering/simplified-nq-test.jsonl\",\n    \"NQ json for predictions. E.g., dev-v1.1.jsonl.gz or test-v1.1.jsonl.gz\")\nflags.DEFINE_boolean(\"logtostderr\", True, \"Logs to stderr\")\nflags.DEFINE_boolean(\"undefok\", True, \"it's okay to be undefined\")\nflags.DEFINE_string('f', '', 'kernel')\nflags.DEFINE_string('HistoryManager.hist_file', '', 'kernel')\n\nFLAGS = flags.FLAGS\nFLAGS(sys.argv) # Parse the flags","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Here, we:**\n1. Set up Bert\n2. Read in the test set\n3. Run it past the pre-built Bert model to create embeddings\n4. Use those embeddings to make predictions\n5. Write those predictions to `predictions.json`\n\n以下のコードを自由に変更してください。 `tf2baseline。*` functionsは `tf2_0_baseline_w_bert`ユーティリティスクリプトに含まれており、ユーティリティスクリプトをフォークして更新するか、このカーネルで独自の非` tf2baseline`バージョンを作成することでカスタマイズできます。\n\n注意： `tf2_0_baseline_w_bert`ユーティリティスクリプトには、独自の埋め込みをトレーニングするためのコードが含まれています。 ここでそのコードは削除されます。"},{"metadata":{"trusted":true},"cell_type":"code","source":"bert_config = modeling.BertConfig.from_json_file(FLAGS.bert_config_file)\n\ntf2baseline.validate_flags_or_throw(bert_config)\ntf.io.gfile.makedirs(FLAGS.output_dir)\n\ntokenizer = tokenization.FullTokenizer(\n    vocab_file=FLAGS.vocab_file, do_lower_case=FLAGS.do_lower_case)\n\nrun_config = tf.estimator.RunConfig(\n    model_dir=FLAGS.output_dir,\n    save_checkpoints_steps=FLAGS.save_checkpoints_steps)\n\nnum_train_steps = None\nnum_warmup_steps = None\n\nmodel_fn = tf2baseline.model_fn_builder(\n    bert_config=bert_config,\n    init_checkpoint=FLAGS.init_checkpoint,\n    learning_rate=FLAGS.learning_rate,\n    num_train_steps=num_train_steps,\n    num_warmup_steps=num_warmup_steps,\n    use_tpu=FLAGS.use_tpu,\n    use_one_hot_embeddings=FLAGS.use_one_hot_embeddings)\n\nestimator = tf.estimator.Estimator(\n    model_fn=model_fn,\n    config=run_config,\n    params={'batch_size':FLAGS.train_batch_size})\n\n\nif FLAGS.do_predict:\n  if not FLAGS.output_prediction_file:\n    raise ValueError(\n        \"--output_prediction_file must be defined in predict mode.\")\n    \n  eval_examples = tf2baseline.read_nq_examples(\n      input_file=FLAGS.predict_file, is_training=False)\n\n  print(\"FLAGS.predict_file\", FLAGS.predict_file)\n\n  eval_writer = tf2baseline.FeatureWriter(\n      filename=os.path.join(FLAGS.output_dir, \"eval.tf_record\"),\n      is_training=False)\n  eval_features = []\n\n  def append_feature(feature):\n    eval_features.append(feature)\n    eval_writer.process_feature(feature)\n\n  num_spans_to_ids = tf2baseline.convert_examples_to_features(\n      examples=eval_examples,\n      tokenizer=tokenizer,\n      is_training=False,\n      output_fn=append_feature)\n  eval_writer.close()\n  eval_filename = eval_writer.filename\n\n  print(\"***** Running predictions *****\")\n  print(f\"  Num orig examples = %d\" % len(eval_examples))\n  print(f\"  Num split examples = %d\" % len(eval_features))\n  print(f\"  Batch size = %d\" % FLAGS.predict_batch_size)\n  for spans, ids in num_spans_to_ids.items():\n    print(f\"  Num split into %d = %d\" % (spans, len(ids)))\n\n  predict_input_fn = tf2baseline.input_fn_builder(\n      input_file=eval_filename,\n      seq_length=FLAGS.max_seq_length,\n      is_training=False,\n      drop_remainder=False)\n\n  all_results = []\n\n  for result in estimator.predict(\n      predict_input_fn, yield_single_examples=True):\n    if len(all_results) % 1000 == 0:\n      print(\"Processing example: %d\" % (len(all_results)))\n\n    unique_id = int(result[\"unique_ids\"])\n    start_logits = [float(x) for x in result[\"start_logits\"].flat]\n    end_logits = [float(x) for x in result[\"end_logits\"].flat]\n    answer_type_logits = [float(x) for x in result[\"answer_type_logits\"].flat]\n\n    all_results.append(\n        tf2baseline.RawResult(\n            unique_id=unique_id,\n            start_logits=start_logits,\n            end_logits=end_logits,\n            answer_type_logits=answer_type_logits))\n\n  print (\"Going to candidates file\")\n\n  candidates_dict = tf2baseline.read_candidates(FLAGS.predict_file)\n\n  print (\"setting up eval features\")\n\n  raw_dataset = tf.data.TFRecordDataset(eval_filename)\n  eval_features = []\n  for raw_record in raw_dataset:\n    eval_features.append(tf.train.Example.FromString(raw_record.numpy()))\n    \n  print (\"compute_pred_dict\")\n\n  nq_pred_dict = tf2baseline.compute_pred_dict(candidates_dict, eval_features,\n                                   [r._asdict() for r in all_results])\n  predictions_json = {\"predictions\": list(nq_pred_dict.values())}\n\n  print (\"writing json\")\n\n  with tf.io.gfile.GFile(FLAGS.output_prediction_file, \"w\") as f:\n    json.dump(predictions_json, f, indent=4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Now, we turn `predictions.json` into a `submission.csv` file.**"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_answers_df = pd.read_json(\"/kaggle/working/predictions.json\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The Bert model produces a `confidence` score, which the Kaggle metric does not use. You, however, can use that score to determine which answers get submitted. See the limits commented out in `create_short_answer` and `create_long_answer` below for an example.\n\nValues for `confidence` will range between `1.0` and `2.0`."},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_short_answer(entry):\n    # if entry[\"short_answers_score\"] < 1.5:\n    #     return \"\"\n    \n    answer = []    \n    for short_answer in entry[\"short_answers\"]:\n        if short_answer[\"start_token\"] > -1:\n            answer.append(str(short_answer[\"start_token\"]) + \":\" + str(short_answer[\"end_token\"]))\n    if entry[\"yes_no_answer\"] != \"NONE\":\n        answer.append(entry[\"yes_no_answer\"])\n    return \" \".join(answer)\n\ndef create_long_answer(entry):\n   # if entry[\"long_answer_score\"] < 1.5:\n   # return \"\"\n\n    answer = []\n    if entry[\"long_answer\"][\"start_token\"] > -1:\n        answer.append(str(entry[\"long_answer\"][\"start_token\"]) + \":\" + str(entry[\"long_answer\"][\"end_token\"]))\n    return \" \".join(answer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_answers_df[\"long_answer_score\"] = test_answers_df[\"predictions\"].apply(lambda q: q[\"long_answer_score\"])\ntest_answers_df[\"short_answer_score\"] = test_answers_df[\"predictions\"].apply(lambda q: q[\"short_answers_score\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_answers_df[\"long_answer_score\"].describe()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"An example of what each sample's answers look like in `prediction.json`:"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_answers_df.predictions.values[0]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"submissionの要件に一致するようにJSON回答を再フォーマットします。"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_answers_df[\"long_answer\"] = test_answers_df[\"predictions\"].apply(create_long_answer)\ntest_answers_df[\"short_answer\"] = test_answers_df[\"predictions\"].apply(create_short_answer)\ntest_answers_df[\"example_id\"] = test_answers_df[\"predictions\"].apply(lambda q: str(q[\"example_id\"]))\n\nlong_answers = dict(zip(test_answers_df[\"example_id\"], test_answers_df[\"long_answer\"]))\nshort_answers = dict(zip(test_answers_df[\"example_id\"], test_answers_df[\"short_answer\"]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"次に、それらをサンプル送信に追加します。 各サンプルには、回答のタイプごとに1つずつ、サンプル送信に`_long`と`_short`の両方のエントリがあることを思い出してください。"},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission = pd.read_csv(\"/kaggle/input/tensorflow2-question-answering/sample_submission.csv\")\n\nlong_prediction_strings = sample_submission[sample_submission[\"example_id\"].str.contains(\"_long\")].apply(lambda q: long_answers[q[\"example_id\"].replace(\"_long\", \"\")], axis=1)\nshort_prediction_strings = sample_submission[sample_submission[\"example_id\"].str.contains(\"_short\")].apply(lambda q: short_answers[q[\"example_id\"].replace(\"_short\", \"\")], axis=1)\n\nsample_submission.loc[sample_submission[\"example_id\"].str.contains(\"_long\"), \"PredictionString\"] = long_prediction_strings\nsample_submission.loc[sample_submission[\"example_id\"].str.contains(\"_short\"), \"PredictionString\"] = short_prediction_strings","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"そして最後に、submissionをCSVで出力します！"},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission.to_csv(\"submission.csv\", index=False)\nsample_submission.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<font size=4 color='#57467B'>Please give this kernel an UPVOTE to show your appreciation, if you find it useful.</font>\n<br>\n<br>\n<font size=4 color='#57467B'>Also don't forget to upvote Dimitre's kernel <a href='https://www.kaggle.com/dimitreoliveira/using-tf-2-0-w-bert-on-nq-translated-to-tf2-0'>here</a></font>"}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}