Token Classification
Token classification
トークン分類では、文内の個々のトークンにラベルを割り当てます。最も一般的なトークン分類タスクの 1 つは、固有表現認識 (NER) です。 NER は、人、場所、組織など、文内の各エンティティのラベルを見つけようとします。
このガイドでは、次の方法を説明します。
- WNUT 17 データセットで DistilBERT を微調整して、新しいエンティティを検出します。
- 微調整されたモデルを推論に使用します。
このタスクと互換性のあるすべてのアーキテクチャとチェックポイントを確認するには、タスクページ を確認することをお勧めします。
始める前に、必要なライブラリがすべてインストールされていることを確認してください。
pip install transformers datasets evaluate seqeval
モデルをアップロードしてコミュニティと共有できるように、Hugging Face アカウントにログインすることをお勧めします。プロンプトが表示されたら、トークンを入力してログインします。
Load WNUT 17 dataset
まず、🤗 データセット ライブラリから WNUT 17 データセットをロードします。
次に、例を見てみましょう。
{'id': '0',
, 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0],
, 'tokens': ['@paulwalk', 'It', "'s", 'the', 'view', 'from', 'where', 'I', "'m", 'living', 'for', 'two', 'weeks', '.', 'Empire', 'State', 'Building', '=', 'ESB', '.', 'Pretty', 'bad', 'storm', 'here', 'last', 'evening', '.']
,} ner_tags内の各数字はエンティティを表します。数値をラベル名に変換して、エンティティが何であるかを調べます。
[ , "O", , "B-corporation", , "I-corporation", , "B-creative-work", , "I-creative-work", , "B-group", , "I-group", , "B-location", , "I-location", , "B-person", , "I-person", , "B-product", , "I-product", ,]
各 ner_tag の前に付く文字は、エンティティのトークンの位置を示します。
B-はエンティティの始まりを示します。I-は、トークンが同じエンティティ内に含まれていることを示します (たとえば、Stateトークンは次のようなエンティティの一部です)Empire State Building)。0は、トークンがどのエンティティにも対応しないことを示します。
Preprocess
次のステップでは、DistilBERT トークナイザーをロードしてtokensフィールドを前処理します。
上の tokensフィールドの例で見たように、入力はすでにトークン化されているようです。しかし、実際には入力はまだトークン化されていないため、単語をサブワードにトークン化するにはis_split_into_words=True を設定する必要があります。例えば:
['[CLS]', '@', 'paul', '##walk', 'it', "'", 's', 'the', 'view', 'from', 'where', 'i', "'", 'm', 'living', 'for', 'two', 'weeks', '.', 'empire', 'state', 'building', '=', 'es', '##b', '.', 'pretty', 'bad', 'storm', 'here', 'last', 'evening', '.', '[SEP]']
ただし、これによりいくつかの特別なトークン [CLS] と [SEP] が追加され、サブワードのトークン化により入力とラベルの間に不一致が生じます。 1 つのラベルに対応する 1 つの単語を 2 つのサブワードに分割できるようになりました。次の方法でトークンとラベルを再調整する必要があります。
word_idsメソッドを使用して、すべてのトークンを対応する単語にマッピングします。- 特別なトークン
[CLS]と[SEP]にラベル-100を割り当て、それらが PyTorch 損失関数によって無視されるようにします (CrossEntropyLoss)。 - 特定の単語の最初のトークンのみにラベルを付けます。同じ単語の他のサブトークンに
-100を割り当てます。
トークンとラベルを再調整し、シーケンスを DistilBERT の最大入力長以下に切り詰める関数を作成する方法を次に示します。
データセット全体に前処理関数を適用するには、🤗 Datasets map 関数を使用します。 batched=True を設定してデータセットの複数の要素を一度に処理することで、map 関数を高速化できます。
次に、DataCollatorWithPadding を使用してサンプルのバッチを作成します。データセット全体を最大長までパディングするのではなく、照合中にバッチ内の最長の長さまで文を 動的にパディング する方が効率的です。
Evaluate
まず NER ラベルを取得してから、真の予測と真のラベルを compute に渡してスコアを計算する関数を作成します。
これでcompute_metrics関数の準備が整いました。トレーニングをセットアップするときにこの関数に戻ります。
Train
モデルのトレーニングを開始する前に、id2labelとlabel2idを使用して、予想される ID とそのラベルのマップを作成します。
これでモデルのトレーニングを開始する準備が整いました。 AutoModelForTokenClassification を使用して、予期されるラベルの数とラベル マッピングを指定して DistilBERT を読み込みます。
この時点で残っているステップは 3 つだけです。
- TrainingArguments でトレーニング ハイパーパラメータを定義します。唯一の必須パラメータは、モデルの保存場所を指定する
output_dirです。push_to_hub=Trueを設定して、このモデルをハブにプッシュします (モデルをアップロードするには、Hugging Face にサインインする必要があります)。各エポックの終了時に、Trainer は連続スコアを評価し、トレーニング チェックポイントを保存します。 - トレーニング引数を、モデル、データセット、トークナイザー、データ照合器、および
compute_metrics関数とともに Trainer に渡します。 - train() を呼び出してモデルを微調整します。
トレーニングが完了したら、 push_to_hub() メソッドを使用してモデルをハブに共有し、誰もがモデルを使用できるようにします。
トークン分類のモデルを微調整する方法のより詳細な例については、対応するセクションを参照してください。 PyTorch ノートブック または TensorFlow ノートブック。
Inference
モデルを微調整したので、それを推論に使用できるようになりました。
推論を実行したいテキストをいくつか取得します。
推論用に微調整されたモデルを試す最も簡単な方法は、それを pipeline() で使用することです。モデルを使用して NER のpipelineをインスタンス化し、テキストをそれに渡します。
[{'entity': 'B-location',
, 'score': 0.42658573,
, 'index': 2,
, 'word': 'golden',
, 'start': 4,
, 'end': 10},
, {'entity': 'I-location',
, 'score': 0.35856336,
, 'index': 3,
, 'word': 'state',
, 'start': 11,
, 'end': 16},
, {'entity': 'B-group',
, 'score': 0.3064001,
, 'index': 4,
, 'word': 'warriors',
, 'start': 17,
, 'end': 25},
, {'entity': 'B-location',
, 'score': 0.65523505,
, 'index': 13,
, 'word': 'san',
, 'start': 80,
, 'end': 83},
, {'entity': 'B-location',
, 'score': 0.4668663,
, 'index': 14,
, 'word': 'francisco',
, 'start': 84,
, 'end': 93}] 必要に応じて、pipelineの結果を手動で複製することもできます。
テキストをトークン化して PyTorch テンソルを返します。
入力をモデルに渡し、logitsを返します。
最も高い確率でクラスを取得し、モデルの id2label マッピングを使用してそれをテキスト ラベルに変換します。
['O', , 'O', , 'B-location', , 'I-location', , 'B-group', , 'O', , 'O', , 'O', , 'O', , 'O', , 'O', , 'O', , 'O', , 'B-location', , 'B-location', , 'O', , 'O']