La journée communautaire ML est le 9 novembre ! Rejoignez - nous pour les mises à jour de tensorflow, JAX et plus En savoir plus

Exploration des encastrements pivotants TF-Hub CORD-19

Voir sur TensorFlow.org Exécuter dans Google Colab Voir sur GitHub Télécharger le cahier Voir le modèle TF Hub

Le CORD-19 Module enrobage texte pivotant de TF-Hub (https: //tfhub.dev/ tensorflow / cordon-19 / pivot-128d / 3) était conçu pour aider les chercheurs à analyser des textes en langues naturelles liés à COVID-19. Ces incorporations ont été formés sur les titres, auteurs, résumés, textes du corps, et les titres de référence des articles dans le jeu de données CORD-19 .

Dans cette collaboration, nous allons :

  • Analyser les mots sémantiquement similaires dans l'espace d'inclusion
  • Former un classificateur sur l'ensemble de données SciCite à l'aide des plongements CORD-19

Installer

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

Analyser les encastrements

Commençons par analyser le plongement en calculant et en traçant une matrice de corrélation entre différents termes. Si l'intégration a appris à capturer avec succès le sens de différents mots, les vecteurs d'intégration de mots sémantiquement similaires doivent être proches les uns des autres. Jetons un coup d'œil à certains termes liés à 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

Nous pouvons voir que l'intégration a réussi à capturer le sens des différents termes. Chaque mot est similaire aux autres mots de son groupe (c. proche de 0).

Voyons maintenant comment nous pouvons utiliser ces intégrations pour résoudre une tâche spécifique.

SciCite : classification des intentions de citation

Cette section montre comment utiliser l'intégration pour des tâches en aval telles que la classification de texte. Nous allons utiliser l' ensemble de données SciCite de tensorflow datasets pour classer les intentions de citation dans les journaux académiques. À partir d'une phrase avec une citation d'un article universitaire, indiquez si l'intention principale de la citation est une information de base, l'utilisation de méthodes ou la comparaison de résultats.

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)

Jetons un coup d'œil à quelques exemples étiquetés de l'ensemble de formation

Formation d'un classificateur d'intention citaton

Nous allons former un classificateur sur l' ensemble de données SciCite en utilisant Keras. Construisons un modèle qui utilise les plongements CORD-19 avec une couche de classification au-dessus.

Hyperparamètres

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
_________________________________________________________________

Former et évaluer le modèle

Entraînons et évaluons le modèle pour voir les performances sur la tâche 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

Évaluer le modèle

Et voyons comment le modèle fonctionne. Deux valeurs seront renvoyées. Perte (un nombre qui représente notre erreur, les valeurs inférieures sont meilleures) et précision.

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

On peut voir que la perte diminue rapidement alors que surtout la précision augmente rapidement. Traçons quelques exemples pour vérifier comment la prédiction se rapporte aux vraies étiquettes :

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
})

Nous pouvons voir que pour cet échantillon aléatoire, le modèle prédit la bonne étiquette la plupart du temps, indiquant qu'il peut assez bien intégrer des phrases scientifiques.

Et après?

Maintenant que vous en savez un peu plus sur les encastrements CORD-19 Swivel de TF-Hub, nous vous encourageons à participer au concours CORD-19 Kaggle pour contribuer à acquérir des connaissances scientifiques à partir de textes académiques liés à COVID-19.