このページは Cloud Translation API によって翻訳されました。
Switch to English

TFハブCORD-19スイベル埋め込みの探索

TensorFlow.orgで表示 GoogleColabで実行 GitHubで表示ノートブックをダウンロードTFハブモデルを参照してください

TF-HubのCORD-19Swivelテキスト埋め込みモジュール(https://tfhub.dev/tensorflow/cord-19/swivel-128d/1)は、関連する自然言語テキストを分析する研究者をサポートするために構築されました。 COVID-19(新型コロナウイルス感染症)(#文字数制限がない場合、初出時にかっこ書きを追加。これらの埋め込みは、 CORD-19データセット内の記事のタイトル、著者、要約、本文、および参照タイトルについてトレーニングされました。

このコラボでは、次のことを行います。

  • 埋め込みスペースで意味的に類似した単語を分析する
  • CORD-19埋め込みを使用して、SciCiteデータセットで分類器をトレーニングします

セットアップ

import functools
import itertools
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd

import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
tf.logging.set_verbosity('ERROR')

import tensorflow_datasets as tfds
import tensorflow_hub as hub

try:
  from google.colab import data_table
  def display_df(df):
    return data_table.DataTable(df, include_index=False)
except ModuleNotFoundError:
  # If google-colab is not available, just display the raw DataFrame
  def display_df(df):
    return df

埋め込みを分析します

異なる項間の相関行列を計算してプロットすることにより、埋め込みを分析することから始めましょう。埋め込みが異なる単語の意味をうまく捉えることを学んだ場合、意味的に類似した単語の埋め込みベクトルは互いに接近している必要があります。 COVID-19関連の用語をいくつか見てみましょう。

# Use the inner product between two embedding vectors as the similarity measure
def plot_correlation(labels, features):
  corr = np.inner(features, features)
  corr /= np.max(corr)
  sns.heatmap(corr, xticklabels=labels, yticklabels=labels)


with tf.Graph().as_default():
  # Load the module
  query_input = tf.placeholder(tf.string)
  module = hub.Module('https://tfhub.dev/tensorflow/cord-19/swivel-128d/1')
  embeddings = module(query_input)

  with tf.train.MonitoredTrainingSession() as sess:

    # Generate embeddings for some terms
    queries = [
        # Related viruses
        "coronavirus", "SARS", "MERS",
        # Regions
        "Italy", "Spain", "Europe",
        # Symptoms
        "cough", "fever", "throat"
    ]

    features = sess.run(embeddings, feed_dict={query_input: queries})
    plot_correlation(queries, features)

png

埋め込みがさまざまな用語の意味をうまく捉えていることがわかります。各単語は、そのクラスターの他の単語と類似しています(つまり、「コロナウイルス」は「SARS」と「MERS」と高度に相関しています)が、他のクラスターの用語とは異なります(つまり、「SARS」と「スペイン」の類似性は0に近い)。

次に、これらの埋め込みを使用して特定のタスクを解決する方法を見てみましょう。

SciCite:引用意図の分類

このセクションでは、テキスト分類などのダウンストリームタスクに埋め込みを使用する方法を示します。 TensorFlowデータセットSciCiteデータセットを使用して、学術論文の引用インテントを分類します。学術論文からの引用を含む文を前提として、引用の主な目的が背景情報、方法の使用、または結果の比較のいずれであるかを分類します。

TFDSからデータセットを設定する

Downloading and preparing dataset scicite/1.0.0 (download: 22.12 MiB, generated: Unknown size, total: 22.12 MiB) to /home/kbuilder/tensorflow_datasets/scicite/1.0.0...
Shuffling and writing examples to /home/kbuilder/tensorflow_datasets/scicite/1.0.0.incompleteHWK5SE/scicite-train.tfrecord
Shuffling and writing examples to /home/kbuilder/tensorflow_datasets/scicite/1.0.0.incompleteHWK5SE/scicite-validation.tfrecord
Shuffling and writing examples to /home/kbuilder/tensorflow_datasets/scicite/1.0.0.incompleteHWK5SE/scicite-test.tfrecord
Dataset scicite downloaded and prepared to /home/kbuilder/tensorflow_datasets/scicite/1.0.0. Subsequent calls will reuse this data.

トレーニングセットからいくつかのラベル付きの例を見てみましょう

シタトンインテント分類器のトレーニング

Estimatorを使用して、 SciCiteデータセットで分類器をトレーニングします。データセットをモデルに読み込むようにinput_fnsを設定しましょう

def preprocessed_input_fn(for_eval):
  data = THE_DATASET.get_data(for_eval=for_eval)
  data = data.map(THE_DATASET.example_fn, num_parallel_calls=1)
  return data


def input_fn_train(params):
  data = preprocessed_input_fn(for_eval=False)
  data = data.repeat(None)
  data = data.shuffle(1024)
  data = data.batch(batch_size=params['batch_size'])
  return data


def input_fn_eval(params):
  data = preprocessed_input_fn(for_eval=True)
  data = data.repeat(1)
  data = data.batch(batch_size=params['batch_size'])
  return data


def input_fn_predict(params):
  data = preprocessed_input_fn(for_eval=True)
  data = data.batch(batch_size=params['batch_size'])
  return data

分類レイヤーが上にあるCORD-19埋め込みを使用するモデルを作成しましょう。

def model_fn(features, labels, mode, params):
  # Embed the text
  embed = hub.Module(params['module_name'], trainable=params['trainable_module'])
  embeddings = embed(features['feature'])

  # Add a linear layer on top
  logits = tf.layers.dense(
      embeddings, units=THE_DATASET.num_classes(), activation=None)
  predictions = tf.argmax(input=logits, axis=1)

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(
        mode=mode,
        predictions={
            'logits': logits,
            'predictions': predictions,
            'features': features['feature'],
            'labels': features['label']
        })

  # Set up a multi-class classification head
  loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
      labels=labels, logits=logits)
  loss = tf.reduce_mean(loss)

  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=params['learning_rate'])
    train_op = optimizer.minimize(loss, global_step=tf.train.get_or_create_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  elif mode == tf.estimator.ModeKeys.EVAL:
    accuracy = tf.metrics.accuracy(labels=labels, predictions=predictions)
    precision = tf.metrics.precision(labels=labels, predictions=predictions)
    recall = tf.metrics.recall(labels=labels, predictions=predictions)

    return tf.estimator.EstimatorSpec(
        mode=mode,
        loss=loss,
        eval_metric_ops={
            'accuracy': accuracy,
            'precision': precision,
            'recall': recall,
        })

ハイパーパラメーター

モデルのトレーニングと評価

モデルをトレーニングして評価し、SciCiteタスクのパフォーマンスを確認しましょう。

estimator = tf.estimator.Estimator(functools.partial(model_fn, params=params))
metrics = []

for step in range(0, STEPS, EVAL_EVERY):
  estimator.train(input_fn=functools.partial(input_fn_train, params=params), steps=EVAL_EVERY)
  step_metrics = estimator.evaluate(input_fn=functools.partial(input_fn_eval, params=params))
  print('Global step {}: loss {:.3f}, accuracy {:.3f}'.format(step, step_metrics['loss'], step_metrics['accuracy']))
  metrics.append(step_metrics)
Global step 0: loss 0.796, accuracy 0.670
Global step 200: loss 0.701, accuracy 0.732
Global step 400: loss 0.682, accuracy 0.719
Global step 600: loss 0.650, accuracy 0.747
Global step 800: loss 0.620, accuracy 0.762
Global step 1000: loss 0.609, accuracy 0.762
Global step 1200: loss 0.605, accuracy 0.762
Global step 1400: loss 0.585, accuracy 0.783
Global step 1600: loss 0.586, accuracy 0.768
Global step 1800: loss 0.577, accuracy 0.774
Global step 2000: loss 0.584, accuracy 0.765
Global step 2200: loss 0.565, accuracy 0.778
Global step 2400: loss 0.570, accuracy 0.776
Global step 2600: loss 0.556, accuracy 0.789
Global step 2800: loss 0.563, accuracy 0.778
Global step 3000: loss 0.557, accuracy 0.784
Global step 3200: loss 0.566, accuracy 0.774
Global step 3400: loss 0.552, accuracy 0.782
Global step 3600: loss 0.551, accuracy 0.785
Global step 3800: loss 0.547, accuracy 0.788
Global step 4000: loss 0.549, accuracy 0.784
Global step 4200: loss 0.548, accuracy 0.785
Global step 4400: loss 0.553, accuracy 0.783
Global step 4600: loss 0.543, accuracy 0.786
Global step 4800: loss 0.548, accuracy 0.783
Global step 5000: loss 0.547, accuracy 0.785
Global step 5200: loss 0.539, accuracy 0.791
Global step 5400: loss 0.546, accuracy 0.782
Global step 5600: loss 0.548, accuracy 0.781
Global step 5800: loss 0.540, accuracy 0.791
Global step 6000: loss 0.542, accuracy 0.790
Global step 6200: loss 0.539, accuracy 0.792
Global step 6400: loss 0.545, accuracy 0.788
Global step 6600: loss 0.552, accuracy 0.781
Global step 6800: loss 0.549, accuracy 0.783
Global step 7000: loss 0.540, accuracy 0.788
Global step 7200: loss 0.543, accuracy 0.782
Global step 7400: loss 0.541, accuracy 0.787
Global step 7600: loss 0.532, accuracy 0.790
Global step 7800: loss 0.537, accuracy 0.792

global_steps = [x['global_step'] for x in metrics]
fig, axes = plt.subplots(ncols=2, figsize=(20,8))

for axes_index, metric_names in enumerate([['accuracy', 'precision', 'recall'],
                                            ['loss']]):
  for metric_name in metric_names:
    axes[axes_index].plot(global_steps, [x[metric_name] for x in metrics], label=metric_name)
  axes[axes_index].legend()
  axes[axes_index].set_xlabel("Global Step")

png

特に精度が急激に向上する一方で、損失が急速に減少することがわかります。いくつかの例をプロットして、予測が実際のラベルにどのように関連しているかを確認しましょう。

predictions = estimator.predict(functools.partial(input_fn_predict, params))
first_10_predictions = list(itertools.islice(predictions, 10))

display_df(
  pd.DataFrame({
      TEXT_FEATURE_NAME: [pred['features'].decode('utf8') for pred in first_10_predictions],
      LABEL_NAME: [THE_DATASET.class_names()[pred['labels']] for pred in first_10_predictions],
      'prediction': [THE_DATASET.class_names()[pred['predictions']] for pred in first_10_predictions]
  }))

このランダムサンプルの場合、モデルはほとんどの場合正しいラベルを予測し、科学的な文をかなりうまく埋め込むことができることを示していることがわかります。

次は何ですか?

TF-HubからのCORD-19Swivelの埋め込みについてもう少し詳しく知ることができたので、CORD-19 Kaggleコンテストに参加して、COVID-19関連の学術テキストから科学的洞察を得ることに貢献することをお勧めします。