Изучение шарнирных встраиваний TF-Hub CORD-19

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть на GitHub Скачать блокнот См. Модель TF Hub

CORD-19 Поворотный текст встраивания модуля из TF-концентратор (HTTPS: //tfhub.dev/ tensorflow / шнур-19 / поворотно-128d / 3) было создан для поддержки исследователей, анализирующих текст на естественном языке, связанный с COVID-19. Эти вложения были подготовлены на названия, авторов, рефераты, тексты для тела, и справочные названия статей в CORD-19 набора данных .

В этом колабе мы:

  • Анализируйте семантически похожие слова в пространстве вложения
  • Обучите классификатор на наборе данных SciCite, используя вложения CORD-19

Настраивать

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

import tensorflow as tf

import tensorflow_datasets as tfds
import tensorflow_hub as hub

from tqdm import trange

Проанализируйте вложения

Давайте начнем с анализа вложения путем вычисления и построения корреляционной матрицы между различными терминами. Если встраивание научилось успешно улавливать значение разных слов, векторы встраивания семантически похожих слов должны быть близко друг к другу. Давайте взглянем на некоторые термины, связанные с 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)

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

module = hub.load('https://tfhub.dev/tensorflow/cord-19/swivel-128d/3')
embeddings = module(queries)

plot_correlation(queries, embeddings)
2021-08-18 11:10:03.886919: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:03.893914: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:03.894880: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:03.896867: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-08-18 11:10:03.897437: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:03.898419: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:03.899326: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:04.499928: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:04.500992: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:04.501940: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-18 11:10:04.502845: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1510] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 14648 MB memory:  -> device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0
2021-08-18 11:10:04.859902: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)

PNG

Мы видим, что встраивание успешно уловило значение различных терминов. Каждое слово похоже на другие слова своего кластера (например, «коронавирус» сильно коррелирует с «SARS» и «MERS»), в то время как они отличаются от терминов других кластеров (например, сходство между «SARS» и «Испания» составляет близко к 0).

Теперь посмотрим, как мы можем использовать эти вложения для решения конкретной задачи.

SciCite: классификация намерений цитирования

В этом разделе показано, как можно использовать встраивание для последующих задач, таких как классификация текста. Мы будем использовать набор данных SciCite из TensorFlow Datasets классифицировать цитирования намерений в научных работах. Учитывая предложение с цитатой из академической статьи, определите, является ли основная цель цитирования справочной информацией, использованием методов или сравнением результатов.

builder = tfds.builder(name='scicite')
builder.download_and_prepare()
train_data, validation_data, test_data = builder.as_dataset(
    split=('train', 'validation', 'test'),
    as_supervised=True)

Давайте посмотрим на несколько помеченных примеров из обучающей выборки.

Обучение классификатора намерений citaton

Мы обучим классификатор на SciCite набора данных с использованием Keras. Давайте построим модель, которая использует вложения CORD-19 с классификационным слоем наверху.

Гиперпараметры

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
keras_layer (KerasLayer)     (None, 128)               17301632  
_________________________________________________________________
dense (Dense)                (None, 3)                 387       
=================================================================
Total params: 17,302,019
Trainable params: 387
Non-trainable params: 17,301,632
_________________________________________________________________

Обучите и оцените модель

Давайте обучим и оценим модель, чтобы увидеть производительность задачи SciCite.

EPOCHS =   35
BATCH_SIZE = 32

history = model.fit(train_data.shuffle(10000).batch(BATCH_SIZE),
                    epochs=EPOCHS,
                    validation_data=validation_data.batch(BATCH_SIZE),
                    verbose=1)
Epoch 1/35
257/257 [==============================] - 4s 9ms/step - loss: 0.9212 - accuracy: 0.5792 - val_loss: 0.7661 - val_accuracy: 0.6812
Epoch 2/35
257/257 [==============================] - 2s 5ms/step - loss: 0.7001 - accuracy: 0.7191 - val_loss: 0.6689 - val_accuracy: 0.7358
Epoch 3/35
257/257 [==============================] - 3s 6ms/step - loss: 0.6263 - accuracy: 0.7574 - val_loss: 0.6223 - val_accuracy: 0.7533
Epoch 4/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5897 - accuracy: 0.7724 - val_loss: 0.5993 - val_accuracy: 0.7511
Epoch 5/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5685 - accuracy: 0.7778 - val_loss: 0.5844 - val_accuracy: 0.7555
Epoch 6/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5549 - accuracy: 0.7831 - val_loss: 0.5767 - val_accuracy: 0.7675
Epoch 7/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5456 - accuracy: 0.7870 - val_loss: 0.5703 - val_accuracy: 0.7718
Epoch 8/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5387 - accuracy: 0.7907 - val_loss: 0.5673 - val_accuracy: 0.7675
Epoch 9/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5335 - accuracy: 0.7905 - val_loss: 0.5599 - val_accuracy: 0.7784
Epoch 10/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5296 - accuracy: 0.7923 - val_loss: 0.5582 - val_accuracy: 0.7762
Epoch 11/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5254 - accuracy: 0.7916 - val_loss: 0.5568 - val_accuracy: 0.7740
Epoch 12/35
257/257 [==============================] - 3s 5ms/step - loss: 0.5222 - accuracy: 0.7922 - val_loss: 0.5553 - val_accuracy: 0.7751
Epoch 13/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5200 - accuracy: 0.7944 - val_loss: 0.5530 - val_accuracy: 0.7795
Epoch 14/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5178 - accuracy: 0.7941 - val_loss: 0.5550 - val_accuracy: 0.7762
Epoch 15/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5157 - accuracy: 0.7939 - val_loss: 0.5517 - val_accuracy: 0.7773
Epoch 16/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5142 - accuracy: 0.7956 - val_loss: 0.5500 - val_accuracy: 0.7817
Epoch 17/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5123 - accuracy: 0.7977 - val_loss: 0.5498 - val_accuracy: 0.7871
Epoch 18/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5112 - accuracy: 0.7968 - val_loss: 0.5476 - val_accuracy: 0.7838
Epoch 19/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5100 - accuracy: 0.7974 - val_loss: 0.5485 - val_accuracy: 0.7871
Epoch 20/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5089 - accuracy: 0.7977 - val_loss: 0.5491 - val_accuracy: 0.7817
Epoch 21/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5073 - accuracy: 0.7981 - val_loss: 0.5479 - val_accuracy: 0.7828
Epoch 22/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5064 - accuracy: 0.7984 - val_loss: 0.5471 - val_accuracy: 0.7817
Epoch 23/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5054 - accuracy: 0.7981 - val_loss: 0.5463 - val_accuracy: 0.7838
Epoch 24/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5050 - accuracy: 0.8019 - val_loss: 0.5465 - val_accuracy: 0.7882
Epoch 25/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5046 - accuracy: 0.7984 - val_loss: 0.5467 - val_accuracy: 0.7849
Epoch 26/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5038 - accuracy: 0.7997 - val_loss: 0.5456 - val_accuracy: 0.7838
Epoch 27/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5033 - accuracy: 0.8003 - val_loss: 0.5456 - val_accuracy: 0.7828
Epoch 28/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5026 - accuracy: 0.7996 - val_loss: 0.5461 - val_accuracy: 0.7849
Epoch 29/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5019 - accuracy: 0.8025 - val_loss: 0.5447 - val_accuracy: 0.7828
Epoch 30/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5014 - accuracy: 0.8007 - val_loss: 0.5465 - val_accuracy: 0.7849
Epoch 31/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5005 - accuracy: 0.8011 - val_loss: 0.5434 - val_accuracy: 0.7860
Epoch 32/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5004 - accuracy: 0.8018 - val_loss: 0.5444 - val_accuracy: 0.7882
Epoch 33/35
257/257 [==============================] - 2s 5ms/step - loss: 0.5000 - accuracy: 0.8003 - val_loss: 0.5457 - val_accuracy: 0.7882
Epoch 34/35
257/257 [==============================] - 2s 5ms/step - loss: 0.4995 - accuracy: 0.8025 - val_loss: 0.5461 - val_accuracy: 0.7882
Epoch 35/35
257/257 [==============================] - 2s 5ms/step - loss: 0.4991 - accuracy: 0.8006 - val_loss: 0.5432 - val_accuracy: 0.7893
from matplotlib import pyplot as plt
def display_training_curves(training, validation, title, subplot):
  if subplot%10==1: # set up the subplots on the first call
    plt.subplots(figsize=(10,10), facecolor='#F0F0F0')
    plt.tight_layout()
  ax = plt.subplot(subplot)
  ax.set_facecolor('#F8F8F8')
  ax.plot(training)
  ax.plot(validation)
  ax.set_title('model '+ title)
  ax.set_ylabel(title)
  ax.set_xlabel('epoch')
  ax.legend(['train', 'valid.'])
display_training_curves(history.history['accuracy'], history.history['val_accuracy'], 'accuracy', 211)
display_training_curves(history.history['loss'], history.history['val_loss'], 'loss', 212)

PNG

Оцените модель

И посмотрим, как модель работает. Будут возвращены два значения. Потеря (число, которое представляет нашу ошибку, чем ниже значение, тем лучше) и точность.

results = model.evaluate(test_data.batch(512), verbose=2)

for name, value in zip(model.metrics_names, results):
  print('%s: %.3f' % (name, value))
4/4 - 2s - loss: 0.5345 - accuracy: 0.7891
loss: 0.534
accuracy: 0.789

Мы видим, что потери быстро уменьшаются, в то время как особенно быстро увеличивается точность. Давайте изобразим несколько примеров, чтобы проверить, как прогноз соотносится с истинными метками:

prediction_dataset = next(iter(test_data.batch(20)))

prediction_texts = [ex.numpy().decode('utf8') for ex in prediction_dataset[0]]
prediction_labels = [label2str(x) for x in prediction_dataset[1]]

predictions = [
    label2str(x) for x in np.argmax(model.predict(prediction_texts), axis=-1)]


pd.DataFrame({
    TEXT_FEATURE_NAME: prediction_texts,
    LABEL_NAME: prediction_labels,
    'prediction': predictions
})

Мы видим, что для этой случайной выборки модель в большинстве случаев предсказывает правильную метку, что указывает на то, что она может довольно хорошо встраивать научные предложения.

Что дальше?

Теперь, когда вы узнали немного больше о встраиваниях CORD-19 Swivel от TF-Hub, мы призываем вас принять участие в конкурсе CORD-19 Kaggle, чтобы внести свой вклад в получение научной информации из академических текстов, связанных с COVID-19.