สำรวจ TF-Hub CORD-19 การฝังแบบหมุนได้

ดูบน TensorFlow.org ทำงานใน Google Colab ดูบน GitHub ดาวน์โหลดโน๊ตบุ๊ค ดูรุ่น TF Hub

สาย-19 ข้อความหมุนฝังโมดูลจาก TF-Hub (https: //tfhub.dev/ tensorflow / สาย-19 / หมุน 128d / 3) เป็น สร้างขึ้นเพื่อสนับสนุนนักวิจัยในการวิเคราะห์ข้อความภาษาธรรมชาติที่เกี่ยวข้องกับ COVID-19 embeddings เหล่านี้ได้รับการฝึกฝนในชื่อผู้เขียนบทคัดย่อตำราร่างกายและชื่ออ้างอิงของบทความใน ชุดข้อมูลที่ CORD-19

ใน colab นี้ เราจะ:

  • วิเคราะห์คำที่มีความหมายคล้ายกันในพื้นที่ฝัง
  • ฝึกลักษณนามในชุดข้อมูล 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

เราจะเห็นได้ว่าการฝังนั้นประสบความสำเร็จในการจับความหมายของคำศัพท์ต่างๆ แต่ละคำมีความคล้ายคลึงกับคำอื่นๆ ในกลุ่มของมัน (เช่น "coronavirus" มีความสัมพันธ์อย่างมากกับ "SARS" และ "MERS") ในขณะที่คำเหล่านั้นแตกต่างจากคำในกลุ่มอื่นๆ (เช่น ความคล้ายคลึงกันระหว่าง "SARS" และ "Spain" คือ ใกล้ถึง 0).

ตอนนี้เรามาดูกันว่าเราจะใช้การฝังเหล่านี้เพื่อแก้ปัญหาเฉพาะได้อย่างไร

SciCite: การจัดประเภทเจตนาอ้างอิง

ส่วนนี้แสดงวิธีการใช้การฝังสำหรับงานดาวน์สตรีม เช่น การจัดประเภทข้อความ เราจะใช้ ชุดข้อมูล SciCite จาก TensorFlow ชุดข้อมูลในเจตนารมณ์อ้างอิงประเภทในเอกสารทางวิชาการ ให้ประโยคที่มีการอ้างอิงจากบทความทางวิชาการ ให้จำแนกว่าเจตนาหลักของการอ้างอิงนั้นเป็นข้อมูลพื้นฐาน การใช้วิธีการ หรือการเปรียบเทียบผลลัพธ์

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 embeddings จาก TF-Hub แล้ว เราขอแนะนำให้คุณเข้าร่วมการแข่งขัน CORD-19 Kaggle เพื่อให้ได้รับข้อมูลเชิงลึกทางวิทยาศาสตร์จากข้อความทางวิชาการที่เกี่ยวข้องกับ COVID-19