Skip to content

Instantly share code, notes, and snippets.

@MachineLearningIsEasy
Created October 28, 2021 12:32
Show Gist options
  • Save MachineLearningIsEasy/c82093fbcd61b6cccb36bc0418808142 to your computer and use it in GitHub Desktop.
Save MachineLearningIsEasy/c82093fbcd61b6cccb36bc0418808142 to your computer and use it in GitHub Desktop.
Using BERT in classification
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "XXcdygSLmF7y"
},
"source": [
"![logo.png](data:image/png;base64,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)\n",
"\n",
"[перейти](https://www.bigdataschool.ru/)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "IZ6SNYq_tVVC"
},
"source": [
"# Классификация с BERT\n",
"\n",
"План блокнота:\n",
"\n",
"- загрузка датасета IMDB;\n",
"- загрузка BERT из TensorflowHUB;\n",
"- построение нейронной сети для классификации на основе BERT;\n",
"- обучение сети;\n",
"- сохраняем сеть, выполняем классификацию.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2PHBpLPuQdmK"
},
"source": [
"## Статья о BERT\n",
"\n",
"[BERT](https://arxiv.org/abs/1810.04805) и другие архитектуры нейронных сетей Transformer были безумно успешными в различных задачах NLP. Они вычисляют представления текста в векторном пространстве. Семейство моделей BERT использует архитектуру кодировщика Transformer для обработки каждого токена текста в полном контексте всех токенов до и после.\n",
"\n",
"Модели BERT обычно предварительно обучаются на большом корпусе текста, а затем настраиваются для специфической задачи.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SCjmX4zTCkRK"
},
"source": [
"## Настройка среды"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "q-YbjCkzw0yU",
"outputId": "896f4500-6d47-4638-c3ca-421d0e1479b5"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[K |████████████████████████████████| 4.4 MB 38.5 MB/s \n",
"\u001b[?25h"
]
}
],
"source": [
"# A dependency of the preprocessing for BERT inputs\n",
"!pip install -q -U tensorflow-text"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "b-P1ZOA0FkVJ",
"outputId": "3909ca9d-4bb6-44be-ffd7-3dd1aeb90813"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[?25l\r",
"\u001b[K |▏ | 10 kB 22.8 MB/s eta 0:00:01\r",
"\u001b[K |▍ | 20 kB 27.9 MB/s eta 0:00:01\r",
"\u001b[K |▋ | 30 kB 30.6 MB/s eta 0:00:01\r",
"\u001b[K |▊ | 40 kB 33.7 MB/s eta 0:00:01\r",
"\u001b[K |█ | 51 kB 37.0 MB/s eta 0:00:01\r",
"\u001b[K |█▏ | 61 kB 35.9 MB/s eta 0:00:01\r",
"\u001b[K |█▎ | 71 kB 33.5 MB/s eta 0:00:01\r",
"\u001b[K |█▌ | 81 kB 33.4 MB/s eta 0:00:01\r",
"\u001b[K |█▊ | 92 kB 34.6 MB/s eta 0:00:01\r",
"\u001b[K |█▉ | 102 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██ | 112 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██▎ | 122 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██▍ | 133 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██▋ | 143 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██▉ | 153 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███ | 163 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███▏ | 174 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███▍ | 184 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███▌ | 194 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███▊ | 204 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████ | 215 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████ | 225 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████▎ | 235 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████▌ | 245 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████▋ | 256 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████▉ | 266 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████ | 276 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████▏ | 286 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████▍ | 296 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████▋ | 307 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████▊ | 317 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████ | 327 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████▏ | 337 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████▎ | 348 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████▌ | 358 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████▊ | 368 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████▉ | 378 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████ | 389 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████▎ | 399 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████▍ | 409 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████▋ | 419 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████▉ | 430 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████ | 440 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████▏ | 450 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████▍ | 460 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████▌ | 471 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████▊ | 481 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████ | 491 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████ | 501 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████▎ | 512 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████▌ | 522 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████▋ | 532 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████▉ | 542 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████ | 552 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████▏ | 563 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████▍ | 573 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████▋ | 583 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████▊ | 593 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████ | 604 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████▏ | 614 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████▎ | 624 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████▌ | 634 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████▊ | 645 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████▉ | 655 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████ | 665 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████▎ | 675 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████▍ | 686 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████▋ | 696 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████▉ | 706 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████ | 716 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████▏ | 727 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████▍ | 737 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████▌ | 747 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████▊ | 757 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████ | 768 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████ | 778 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████▎ | 788 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████▌ | 798 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████▋ | 808 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████▉ | 819 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████ | 829 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████▏ | 839 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████▍ | 849 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████▋ | 860 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████▊ | 870 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████ | 880 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████▏ | 890 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████▎ | 901 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████▌ | 911 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████▊ | 921 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████▉ | 931 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████ | 942 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████▎ | 952 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████▍ | 962 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████▋ | 972 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████▉ | 983 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████ | 993 kB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████▏ | 1.0 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████▍ | 1.0 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████▋ | 1.0 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████▊ | 1.0 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████ | 1.0 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████▏ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████▎ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████▌ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████▊ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████▉ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████▎ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████▍ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████▋ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████▉ | 1.1 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████▏ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████▍ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████▌ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████▊ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████▎ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████▌ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████▋ | 1.2 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████▉ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████▏ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████▍ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████▋ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████▊ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████▏ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████▎ | 1.3 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████▌ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████▊ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████▉ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████▎ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████▍ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████▋ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████▉ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████▏ | 1.4 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████▍ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████▌ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████▊ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████▎ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████▌ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████▋ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████▉ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████ | 1.5 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████▏ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████▍ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████▋ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████▊ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████▏ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████▎ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████▌ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████▊ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |█████████████████████████████▉ | 1.6 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████████ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████████▎ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████████▍ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████████▋ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |██████████████████████████████▉ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████████ | 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████████▏| 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████████▍| 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████████▌| 1.7 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |███████████████████████████████▊| 1.8 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████████| 1.8 MB 35.4 MB/s eta 0:00:01\r",
"\u001b[K |████████████████████████████████| 1.8 MB 35.4 MB/s \n",
"\u001b[K |████████████████████████████████| 99 kB 9.7 MB/s \n",
"\u001b[K |████████████████████████████████| 1.1 MB 39.0 MB/s \n",
"\u001b[K |████████████████████████████████| 352 kB 44.8 MB/s \n",
"\u001b[K |████████████████████████████████| 43 kB 1.8 MB/s \n",
"\u001b[K |████████████████████████████████| 37.1 MB 51 kB/s \n",
"\u001b[K |████████████████████████████████| 211 kB 58.1 MB/s \n",
"\u001b[K |████████████████████████████████| 1.2 MB 36.3 MB/s \n",
"\u001b[K |████████████████████████████████| 636 kB 34.7 MB/s \n",
"\u001b[K |████████████████████████████████| 90 kB 9.5 MB/s \n",
"\u001b[?25h Building wheel for py-cpuinfo (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
" Building wheel for seqeval (setup.py) ... \u001b[?25l\u001b[?25hdone\n"
]
}
],
"source": [
"!pip install -q tf-models-official"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "_XgTpm9ZxoN9"
},
"outputs": [],
"source": [
"import os\n",
"import shutil\n",
"\n",
"import tensorflow as tf\n",
"import tensorflow_hub as hub\n",
"import tensorflow_text as text\n",
"from official.nlp import optimization # to create AdamW optimizer\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"tf.get_logger().setLevel('ERROR')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "q6MugfEgDRpY"
},
"source": [
"## Тональность отзывов IMDB\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Vnvd4mrtPHHV"
},
"source": [
"### Загрузка IMDB dataset\n",
"\n",
"Загрузим данные, посмотрим на их структуру"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "pOdqCMoQDRJL",
"outputId": "e3ffcbc5-71a6-4cf4-ee04-77d9fe8ed3bf"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading data from https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz\n",
"84131840/84125825 [==============================] - 3s 0us/step\n",
"84140032/84125825 [==============================] - 3s 0us/step\n"
]
}
],
"source": [
"url = 'https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz'\n",
"\n",
"dataset = tf.keras.utils.get_file('aclImdb_v1.tar.gz', url,\n",
" untar=True, cache_dir='.',\n",
" cache_subdir='')\n",
"\n",
"dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')\n",
"\n",
"train_dir = os.path.join(dataset_dir, 'train')\n",
"\n",
"# remove unused folders to make it easier to load the data\n",
"remove_dir = os.path.join(train_dir, 'unsup')\n",
"shutil.rmtree(remove_dir)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "MbQq7ZU20aYL",
"outputId": "95948c01-d1d4-4d1a-d0f8-b943fed081a6"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"labeledBow.feat pos\t\turls_neg.txt urls_unsup.txt\n",
"neg\t\t unsupBow.feat\turls_pos.txt\n"
]
}
],
"source": [
"!ls aclImdb/train"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lN9lWCYfPo7b"
},
"source": [
"Используя `text_dataset_from_directory` создадим объект `tf.data.Dataset`.\n",
"\n",
"IMDB dataset уже разделен на выборки train и test. Выделим выборку для валидации. Разобьем выборку для обучения в пропорции 80:20."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6IwI_2bcIeX8",
"outputId": "d2cd206a-25ba-486e-abc1-18328242d8ed"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 25000 files belonging to 2 classes.\n",
"Using 20000 files for training.\n",
"Found 25000 files belonging to 2 classes.\n",
"Using 5000 files for validation.\n",
"Found 25000 files belonging to 2 classes.\n"
]
}
],
"source": [
"AUTOTUNE = tf.data.AUTOTUNE\n",
"batch_size = 32\n",
"seed = 42\n",
"\n",
"raw_train_ds = tf.keras.preprocessing.text_dataset_from_directory(\n",
" 'aclImdb/train',\n",
" batch_size=batch_size,\n",
" validation_split=0.2,\n",
" subset='training',\n",
" seed=seed)\n",
"\n",
"class_names = raw_train_ds.class_names\n",
"train_ds = raw_train_ds.cache().prefetch(buffer_size=AUTOTUNE)\n",
"\n",
"val_ds = tf.keras.preprocessing.text_dataset_from_directory(\n",
" 'aclImdb/train',\n",
" batch_size=batch_size,\n",
" validation_split=0.2,\n",
" subset='validation',\n",
" seed=seed)\n",
"\n",
"val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)\n",
"\n",
"test_ds = tf.keras.preprocessing.text_dataset_from_directory(\n",
" 'aclImdb/test',\n",
" batch_size=batch_size)\n",
"\n",
"test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HGm10A5HRGXp"
},
"source": [
"Примеры"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "JuxDkcvVIoev",
"outputId": "8615615d-1799-47fa-a520-b5ac755b759b"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Review: b'\"Pandemonium\" is a horror movie spoof that comes off more stupid than funny. Believe me when I tell you, I love comedies. Especially comedy spoofs. \"Airplane\", \"The Naked Gun\" trilogy, \"Blazing Saddles\", \"High Anxiety\", and \"Spaceballs\" are some of my favorite comedies that spoof a particular genre. \"Pandemonium\" is not up there with those films. Most of the scenes in this movie had me sitting there in stunned silence because the movie wasn\\'t all that funny. There are a few laughs in the film, but when you watch a comedy, you expect to laugh a lot more than a few times and that\\'s all this film has going for it. Geez, \"Scream\" had more laughs than this film and that was more of a horror film. How bizarre is that?<br /><br />*1/2 (out of four)'\n",
"Label : 0 (neg)\n",
"Review: b\"David Mamet is a very interesting and a very un-equal director. His first movie 'House of Games' was the one I liked best, and it set a series of films with characters whose perspective of life changes as they get into complicated situations, and so does the perspective of the viewer.<br /><br />So is 'Homicide' which from the title tries to set the mind of the viewer to the usual crime drama. The principal characters are two cops, one Jewish and one Irish who deal with a racially charged area. The murder of an old Jewish shop owner who proves to be an ancient veteran of the Israeli Independence war triggers the Jewish identity in the mind and heart of the Jewish detective.<br /><br />This is were the flaws of the film are the more obvious. The process of awakening is theatrical and hard to believe, the group of Jewish militants is operatic, and the way the detective eventually walks to the final violent confrontation is pathetic. The end of the film itself is Mamet-like smart, but disappoints from a human emotional perspective.<br /><br />Joe Mantegna and William Macy give strong performances, but the flaws of the story are too evident to be easily compensated.\"\n",
"Label : 0 (neg)\n",
"Review: b'Great documentary about the lives of NY firefighters during the worst terrorist attack of all time.. That reason alone is why this should be a must see collectors item.. What shocked me was not only the attacks, but the\"High Fat Diet\" and physical appearance of some of these firefighters. I think a lot of Doctors would agree with me that,in the physical shape they were in, some of these firefighters would NOT of made it to the 79th floor carrying over 60 lbs of gear. Having said that i now have a greater respect for firefighters and i realize becoming a firefighter is a life altering job. The French have a history of making great documentary\\'s and that is what this is, a Great Documentary.....'\n",
"Label : 1 (pos)\n"
]
}
],
"source": [
"for text_batch, label_batch in train_ds.take(1):\n",
" for i in range(3):\n",
" print(f'Review: {text_batch.numpy()[i]}')\n",
" label = label_batch.numpy()[i]\n",
" print(f'Label : {label} ({class_names[label]})')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dX8FtlpGJRE6"
},
"source": [
"## Загзурим модели из TensorFlow Hub\n",
"\n",
"Доступные BERT модели.\n",
"\n",
" - [BERT-Base](https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3), (https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3)(https://tfhub.dev/google/collections/bert/1).\n",
" - [Small BERTs](https://tfhub.dev/google/collections/bert/1).\n",
" - [ALBERT](https://tfhub.dev/google/collections/albert/1).\n",
" - [BERT Experts](https://tfhub.dev/google/collections/experts/bert/1).\n",
" - [Electra](https://tfhub.dev/google/collections/electra/1) [[base](https://tfhub.dev/tensorflow/talkheads_ggelu_bert_en_base/1), [large](https://tfhub.dev/tensorflow/talkheads_ggelu_bert_en_large/1)] \n",
"\n",
"\n",
"\n",
"Начнем с Small BERT.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "y8_ctG55-uTX",
"outputId": "8eb09fd7-f7a4-4e5b-dd81-00c2a6e27f11"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BERT model selected : https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1\n",
"Preprocess model auto-selected: https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3\n"
]
}
],
"source": [
"#@title Choose a BERT model to fine-tune\n",
"\n",
"bert_model_name = 'small_bert/bert_en_uncased_L-4_H-512_A-8' #@param [\"bert_en_uncased_L-12_H-768_A-12\", \"bert_en_cased_L-12_H-768_A-12\", \"bert_multi_cased_L-12_H-768_A-12\", \"small_bert/bert_en_uncased_L-2_H-128_A-2\", \"small_bert/bert_en_uncased_L-2_H-256_A-4\", \"small_bert/bert_en_uncased_L-2_H-512_A-8\", \"small_bert/bert_en_uncased_L-2_H-768_A-12\", \"small_bert/bert_en_uncased_L-4_H-128_A-2\", \"small_bert/bert_en_uncased_L-4_H-256_A-4\", \"small_bert/bert_en_uncased_L-4_H-512_A-8\", \"small_bert/bert_en_uncased_L-4_H-768_A-12\", \"small_bert/bert_en_uncased_L-6_H-128_A-2\", \"small_bert/bert_en_uncased_L-6_H-256_A-4\", \"small_bert/bert_en_uncased_L-6_H-512_A-8\", \"small_bert/bert_en_uncased_L-6_H-768_A-12\", \"small_bert/bert_en_uncased_L-8_H-128_A-2\", \"small_bert/bert_en_uncased_L-8_H-256_A-4\", \"small_bert/bert_en_uncased_L-8_H-512_A-8\", \"small_bert/bert_en_uncased_L-8_H-768_A-12\", \"small_bert/bert_en_uncased_L-10_H-128_A-2\", \"small_bert/bert_en_uncased_L-10_H-256_A-4\", \"small_bert/bert_en_uncased_L-10_H-512_A-8\", \"small_bert/bert_en_uncased_L-10_H-768_A-12\", \"small_bert/bert_en_uncased_L-12_H-128_A-2\", \"small_bert/bert_en_uncased_L-12_H-256_A-4\", \"small_bert/bert_en_uncased_L-12_H-512_A-8\", \"small_bert/bert_en_uncased_L-12_H-768_A-12\", \"albert_en_base\", \"electra_small\", \"electra_base\", \"experts_pubmed\", \"experts_wiki_books\", \"talking-heads_base\"]\n",
"\n",
"map_name_to_handle = {\n",
" 'bert_en_uncased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3',\n",
" 'bert_en_cased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_cased_L-12_H-768_A-12/3',\n",
" 'bert_multi_cased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_multi_cased_L-12_H-768_A-12/3',\n",
" 'small_bert/bert_en_uncased_L-2_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-2_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-2_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-2_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-2_H-768_A-12/1',\n",
" 'small_bert/bert_en_uncased_L-4_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-4_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-4_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-4_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-768_A-12/1',\n",
" 'small_bert/bert_en_uncased_L-6_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-6_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-6_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-6_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-6_H-768_A-12/1',\n",
" 'small_bert/bert_en_uncased_L-8_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-8_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-8_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-8_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-8_H-768_A-12/1',\n",
" 'small_bert/bert_en_uncased_L-10_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-10_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-10_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-10_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-768_A-12/1',\n",
" 'small_bert/bert_en_uncased_L-12_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-128_A-2/1',\n",
" 'small_bert/bert_en_uncased_L-12_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-256_A-4/1',\n",
" 'small_bert/bert_en_uncased_L-12_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-512_A-8/1',\n",
" 'small_bert/bert_en_uncased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-12_H-768_A-12/1',\n",
" 'albert_en_base':\n",
" 'https://tfhub.dev/tensorflow/albert_en_base/2',\n",
" 'electra_small':\n",
" 'https://tfhub.dev/google/electra_small/2',\n",
" 'electra_base':\n",
" 'https://tfhub.dev/google/electra_base/2',\n",
" 'experts_pubmed':\n",
" 'https://tfhub.dev/google/experts/bert/pubmed/2',\n",
" 'experts_wiki_books':\n",
" 'https://tfhub.dev/google/experts/bert/wiki_books/2',\n",
" 'talking-heads_base':\n",
" 'https://tfhub.dev/tensorflow/talkheads_ggelu_bert_en_base/1',\n",
"}\n",
"\n",
"map_model_to_preprocess = {\n",
" 'bert_en_uncased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'bert_en_cased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_cased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-2_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-2_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-2_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-2_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-4_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-4_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-4_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-4_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-6_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-6_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-6_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-6_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-8_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-8_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-8_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-8_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-10_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-10_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-10_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-10_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-12_H-128_A-2':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-12_H-256_A-4':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-12_H-512_A-8':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'small_bert/bert_en_uncased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'bert_multi_cased_L-12_H-768_A-12':\n",
" 'https://tfhub.dev/tensorflow/bert_multi_cased_preprocess/3',\n",
" 'albert_en_base':\n",
" 'https://tfhub.dev/tensorflow/albert_en_preprocess/3',\n",
" 'electra_small':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'electra_base':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'experts_pubmed':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'experts_wiki_books':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
" 'talking-heads_base':\n",
" 'https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3',\n",
"}\n",
"\n",
"tfhub_handle_encoder = map_name_to_handle[bert_model_name]\n",
"tfhub_handle_preprocess = map_model_to_preprocess[bert_model_name]\n",
"\n",
"print(f'BERT model selected : {tfhub_handle_encoder}')\n",
"print(f'Preprocess model auto-selected: {tfhub_handle_preprocess}')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7WrcxxTRDdHi"
},
"source": [
"## Модель препроцессинга\n",
"\n",
"Текст на входе в нейронную сеть нужно преобразовать в токены и далее в векторные представления перед подачей в BERT. TensorFlow Hub предоставляет соответствующую модель предварительной обработки для каждой из рассмотренных выше моделей BERT, которая реализует это преобразование с помощью операций TF из библиотеки TF.text. Нет необходимости запускать чистый код Python вне вашей модели TensorFlow для предварительной обработки текста.\n",
"\n",
"Модель предварительной обработки должна быть той, на которую ссылается документация модели BERT, которую вы можете прочитать по указанному выше URL-адресу. Для моделей BERT из раскрывающегося списка выше модель предварительной обработки выбирается автоматически.\n",
"\n",
"Примечание. Вы загрузите модель предварительной обработки в [hub.KerasLayer] (https://www.tensorflow.org/hub/api_docs/python/hub/KerasLayer), чтобы составить свою точно настроенную модель. Это предпочтительный API для загрузки SavedModel в стиле TF2 из TF Hub в модель Keras."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0SQi-jWd_jzq"
},
"outputs": [],
"source": [
"bert_preprocess_model = hub.KerasLayer(tfhub_handle_preprocess)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "x4naBiEE_cZX"
},
"source": [
"Выполним препроцессинг текста"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "r9-zCzJpnuwS",
"outputId": "a2cd0182-7905-47e1-805c-8e440828ba29"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Keys : ['input_word_ids', 'input_mask', 'input_type_ids']\n",
"Shape : (1, 128)\n",
"Word Ids : [ 101 2023 2003 2107 2019 6429 3185 999 102 0 0 0]\n",
"Input Mask : [1 1 1 1 1 1 1 1 1 0 0 0]\n",
"Type Ids : [0 0 0 0 0 0 0 0 0 0 0 0]\n"
]
}
],
"source": [
"text_test = ['this is such an amazing movie!']\n",
"text_preprocessed = bert_preprocess_model(text_test)\n",
"\n",
"print(f'Keys : {list(text_preprocessed.keys())}')\n",
"print(f'Shape : {text_preprocessed[\"input_word_ids\"].shape}')\n",
"print(f'Word Ids : {text_preprocessed[\"input_word_ids\"][0, :12]}')\n",
"print(f'Input Mask : {text_preprocessed[\"input_mask\"][0, :12]}')\n",
"print(f'Type Ids : {text_preprocessed[\"input_type_ids\"][0, :12]}')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EqL7ihkN_862"
},
"source": [
"Наблюдаем 3 выхода (`input_words_id`, `input_mask` and `input_type_ids`).\n",
"\n",
"Обратите внимание:\n",
"- Вход ограничен 128 токенами. \n",
"- `input_type_ids` равно (0) так как на входе одно предложение. \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DKnLPSEmtp9i"
},
"source": [
"## Используем BERT"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tXxYpK8ixL34"
},
"outputs": [],
"source": [
"bert_model = hub.KerasLayer(tfhub_handle_encoder)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "_OoF9mebuSZc"
},
"outputs": [],
"source": [
"bert_results = bert_model(text_preprocessed)\n",
"\n",
"print(f'Loaded BERT: {tfhub_handle_encoder}')\n",
"print(f'Pooled Outputs Shape:{bert_results[\"pooled_output\"].shape}')\n",
"print(f'Pooled Outputs Values:{bert_results[\"pooled_output\"][0, :12]}')\n",
"print(f'Sequence Outputs Shape:{bert_results[\"sequence_output\"].shape}')\n",
"print(f'Sequence Outputs Values:{bert_results[\"sequence_output\"][0, :12]}')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sm61jDrezAll"
},
"source": [
"The BERT models return a map with 3 important keys: `pooled_output`, `sequence_output`, `encoder_outputs`:\n",
"\n",
"- `pooled_output` represents each input sequence as a whole. The shape is `[batch_size, H]`. You can think of this as an embedding for the entire movie review.\n",
"- `sequence_output` represents each input token in the context. The shape is `[batch_size, seq_length, H]`. You can think of this as a contextual embedding for every token in the movie review.\n",
"- `encoder_outputs` are the intermediate activations of the `L` Transformer blocks. `outputs[\"encoder_outputs\"][i]` is a Tensor of shape `[batch_size, seq_length, 1024]` with the outputs of the i-th Transformer block, for `0 <= i < L`. The last value of the list is equal to `sequence_output`.\n",
"\n",
"For the fine-tuning you are going to use the `pooled_output` array."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pDNKfAXbDnJH"
},
"source": [
"## Строим нейросеть\n",
"\n",
"Препроцессинговая модель -> Bert -> Dropout -> Dense\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "aksj743St9ga"
},
"outputs": [],
"source": [
"def build_classifier_model():\n",
" text_input = tf.keras.layers.Input(shape=(), dtype=tf.string, name='text')\n",
" preprocessing_layer = hub.KerasLayer(tfhub_handle_preprocess, name='preprocessing')\n",
" encoder_inputs = preprocessing_layer(text_input)\n",
" encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True, name='BERT_encoder')\n",
" outputs = encoder(encoder_inputs)\n",
" net = outputs['pooled_output']\n",
" net = tf.keras.layers.Dropout(0.1)(net)\n",
" net = tf.keras.layers.Dense(1, activation=None, name='classifier')(net)\n",
" return tf.keras.Model(text_input, net)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Zs4yhFraBuGQ"
},
"source": [
"Выполним inference"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "mGMF8AZcB2Zy"
},
"outputs": [],
"source": [
"classifier_model = build_classifier_model()\n",
"bert_raw_result = classifier_model(tf.constant(text_test))\n",
"print(tf.sigmoid(bert_raw_result))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZTUzNV2JE2G3"
},
"source": [
"Модель требует обучения\n",
"\n",
"Посмотрим на структуру"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0EmzyHZXKIpm"
},
"outputs": [],
"source": [
"tf.keras.utils.plot_model(classifier_model)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WbUWoZMwc302"
},
"source": [
"## Обучаем модель\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WpJ3xcwDT56v"
},
"source": [
"### Функция потерь (loss)\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "OWPOZE-L3AgE"
},
"outputs": [],
"source": [
"loss = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n",
"metrics = tf.metrics.BinaryAccuracy()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "77psrpfzbxtp"
},
"source": [
"### Оптимизатор\n",
"Для дообучения лучше использовать тот же оптимизатор, на котором обучалась BERT (Adam, https://arxiv.org/abs/1711.05101)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "P9eP2y9dbw32"
},
"outputs": [],
"source": [
"epochs = 5\n",
"steps_per_epoch = tf.data.experimental.cardinality(train_ds).numpy()\n",
"num_train_steps = steps_per_epoch * epochs\n",
"num_warmup_steps = int(0.1*num_train_steps)\n",
"\n",
"init_lr = 3e-5\n",
"optimizer = optimization.create_optimizer(init_lr=init_lr,\n",
" num_train_steps=num_train_steps,\n",
" num_warmup_steps=num_warmup_steps,\n",
" optimizer_type='adamw')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SqlarlpC_v0g"
},
"source": [
"### Компилируем модель и обучаем\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-7GPDhR98jsD"
},
"outputs": [],
"source": [
"classifier_model.compile(optimizer=optimizer,\n",
" loss=loss,\n",
" metrics=metrics)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "HtfDFAnN_Neu"
},
"outputs": [],
"source": [
"print(f'Training model with {tfhub_handle_encoder}')\n",
"history = classifier_model.fit(x=train_ds,\n",
" validation_data=val_ds,\n",
" epochs=epochs)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uBthMlTSV8kn"
},
"source": [
"### Оцениваем качество сети\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "slqB-urBV9sP"
},
"outputs": [],
"source": [
"loss, accuracy = classifier_model.evaluate(test_ds)\n",
"\n",
"print(f'Loss: {loss}')\n",
"print(f'Accuracy: {accuracy}')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uttWpgmSfzq9"
},
"source": [
"### Смотрим на метрики и функцию потерь\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "fiythcODf0xo"
},
"outputs": [],
"source": [
"history_dict = history.history\n",
"print(history_dict.keys())\n",
"\n",
"acc = history_dict['binary_accuracy']\n",
"val_acc = history_dict['val_binary_accuracy']\n",
"loss = history_dict['loss']\n",
"val_loss = history_dict['val_loss']\n",
"\n",
"epochs = range(1, len(acc) + 1)\n",
"fig = plt.figure(figsize=(10, 6))\n",
"fig.tight_layout()\n",
"\n",
"plt.subplot(2, 1, 1)\n",
"# \"bo\" is for \"blue dot\"\n",
"plt.plot(epochs, loss, 'r', label='Training loss')\n",
"# b is for \"solid blue line\"\n",
"plt.plot(epochs, val_loss, 'b', label='Validation loss')\n",
"plt.title('Training and validation loss')\n",
"# plt.xlabel('Epochs')\n",
"plt.ylabel('Loss')\n",
"plt.legend()\n",
"\n",
"plt.subplot(2, 1, 2)\n",
"plt.plot(epochs, acc, 'r', label='Training acc')\n",
"plt.plot(epochs, val_acc, 'b', label='Validation acc')\n",
"plt.title('Training and validation accuracy')\n",
"plt.xlabel('Epochs')\n",
"plt.ylabel('Accuracy')\n",
"plt.legend(loc='lower right')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Rtn7jewb6dg4"
},
"source": [
"## Сохраняем сеть для inference\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ShcvqJAgVera"
},
"outputs": [],
"source": [
"dataset_name = 'imdb'\n",
"saved_model_path = './{}_bert'.format(dataset_name.replace('/', '_'))\n",
"\n",
"classifier_model.save(saved_model_path, include_optimizer=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "gUEWVskZjEF0"
},
"outputs": [],
"source": [
"reloaded_model = tf.saved_model.load(saved_model_path)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oyTappHTvNCz"
},
"source": [
"Тестим сеть на кастомных примеров"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VBWzH6exlCPS"
},
"outputs": [],
"source": [
"def print_my_examples(inputs, results):\n",
" result_for_printing = \\\n",
" [f'input: {inputs[i]:<30} : score: {results[i][0]:.6f}'\n",
" for i in range(len(inputs))]\n",
" print(*result_for_printing, sep='\\n')\n",
" print()\n",
"\n",
"\n",
"examples = [\n",
" 'this is such an amazing movie!',\n",
" 'The movie was great!',\n",
" 'The movie was meh.',\n",
" 'The movie was okish.',\n",
" 'The movie was terrible...'\n",
"]\n",
"\n",
"reloaded_results = tf.sigmoid(reloaded_model(tf.constant(examples)))\n",
"original_results = tf.sigmoid(classifier_model(tf.constant(examples)))\n",
"\n",
"print('Results from the saved model:')\n",
"print_my_examples(examples, reloaded_results)\n",
"print('Results from the model in memory:')\n",
"print_my_examples(examples, original_results)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3cOmih754Y_M"
},
"source": [
"Сохраняем для использования в [TF Serving](https://www.tensorflow.org/tfx/guide/serving)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0FdVD3973S-O"
},
"outputs": [],
"source": [
"serving_results = reloaded_model \\\n",
" .signatures['serving_default'](tf.constant(examples))\n",
"\n",
"serving_results = tf.sigmoid(serving_results['classifier'])\n",
"\n",
"print_my_examples(examples, serving_results)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4DmhXTlQzg4q"
},
"source": [
"# Задание\n",
"\n",
"Построить нейросеть для классификации тегов вопросов на stavkoverflow\n",
"https://www.tensorflow.org/tutorials/load_data/text"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "2_bert_classification.ipynb",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment