diff --git a/graph_embeddings_pg.ipynb b/graph_embeddings_pg.ipynb new file mode 100644 index 0000000..5af00ee --- /dev/null +++ b/graph_embeddings_pg.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%conda install pyg -c pyg -c conda-forge\n", + "%conda install pytorch torchvision torchaudio -c pytorch\n", + "%pip install networkx seaborn -Uq" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "\n", + "from tqdm import tqdm\n", + "\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "AttributeError", + "evalue": "'Graph' object has no attribute 'edge_index'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/3_/gmvd1nkx285133z5yh3chz2c0000gp/T/ipykernel_16599/2356794267.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mnx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdraw_networkx_edge_labels\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpubmed_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpos\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0medge_labels\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlabels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mpubmed_graph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_index\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'Graph' object has no attribute 'edge_index'" + ] + } + ], + "source": [ + "# pubmed = pd.read_csv('~/workspace/cogtext/data/pubmed_abstracts.')\n", + "\n", + "# pubmed = pd.DataFrame(np.random.random((100,2)), columns=['label','pmid','vector'])\n", + "# pubmed.head()\n", + "\n", + "pubmed_graph = nx.random_geometric_graph(5,5)\n", + "\n", + "for (u, v) in pubmed_graph.edges():\n", + " pubmed_graph.edges[u,v]['weight'] = np.random.randint(0,10)\n", + "\n", + "pos = nx.spring_layout(pubmed_graph)\n", + "nx.draw(pubmed_graph, pos)\n", + "labels = nx.get_edge_attributes(pubmed_graph, 'weight')\n", + "nx.draw_networkx_edge_labels(pubmed_graph, pos,edge_labels=labels)\n", + "plt.show()\n", + "pubmed_graph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create an edge between two nodes if their corresponding corpora share documents >= min_docs. The weight of the edge will be set to the pointwise mutual information between the two labels.\n", + "\n", + "log(xy) - log(x) - log(y) + log(D)\n", + "xy is the number of articles shared between the two labels\n", + "x is the number of articles in the x corpus\n", + "and D is the total number of articles" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch_geometric.nn import Node2Vec\n", + "\n", + "data = \n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "model = Node2Vec(data.edge_index, embedding_dim=128, \n", + " walk_length=20, # lenght of rw\n", + " context_size=10, walks_per_node=20,\n", + " num_negative_samples=1, \n", + " p=200, q=1, # bias parameters\n", + " sparse=True).to(device)\n", + "\n", + "loader = model.loader(batch_size=128, shuffle=True, num_workers=4)\n", + "\n", + "for idx, (pos_rw, neg_rw) in enumerate(loader):\n", + " print(idx, pos_rw.shape, neg_rw.shape)\n", + " \n", + "edge_tuples = [tuple(x) for x in data.edge_index.numpy().transpose()]\n", + "G = nx.from_edgelist(edge_tuples)\n", + "pos = nx.spring_layout(G, center=[0.5, 0.5])\n", + "nx.set_node_attributes(G, pos, 'pos')" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "fd70b4c63b8ac7010e057e1e7961ebae705e9dba34aa5a2e9dfe5bc9196414e5" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit ('pyg': conda)", + "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.7" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/graph_embeddings_pg.ipynb b/graph_embeddings_pg.ipynb new file mode 100644 index 0000000..5af00ee --- /dev/null +++ b/graph_embeddings_pg.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%conda install pyg -c pyg -c conda-forge\n", + "%conda install pytorch torchvision torchaudio -c pytorch\n", + "%pip install networkx seaborn -Uq" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "\n", + "from tqdm import tqdm\n", + "\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "AttributeError", + "evalue": "'Graph' object has no attribute 'edge_index'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/3_/gmvd1nkx285133z5yh3chz2c0000gp/T/ipykernel_16599/2356794267.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mnx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdraw_networkx_edge_labels\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpubmed_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpos\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0medge_labels\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlabels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mpubmed_graph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_index\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'Graph' object has no attribute 'edge_index'" + ] + } + ], + "source": [ + "# pubmed = pd.read_csv('~/workspace/cogtext/data/pubmed_abstracts.')\n", + "\n", + "# pubmed = pd.DataFrame(np.random.random((100,2)), columns=['label','pmid','vector'])\n", + "# pubmed.head()\n", + "\n", + "pubmed_graph = nx.random_geometric_graph(5,5)\n", + "\n", + "for (u, v) in pubmed_graph.edges():\n", + " pubmed_graph.edges[u,v]['weight'] = np.random.randint(0,10)\n", + "\n", + "pos = nx.spring_layout(pubmed_graph)\n", + "nx.draw(pubmed_graph, pos)\n", + "labels = nx.get_edge_attributes(pubmed_graph, 'weight')\n", + "nx.draw_networkx_edge_labels(pubmed_graph, pos,edge_labels=labels)\n", + "plt.show()\n", + "pubmed_graph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create an edge between two nodes if their corresponding corpora share documents >= min_docs. The weight of the edge will be set to the pointwise mutual information between the two labels.\n", + "\n", + "log(xy) - log(x) - log(y) + log(D)\n", + "xy is the number of articles shared between the two labels\n", + "x is the number of articles in the x corpus\n", + "and D is the total number of articles" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch_geometric.nn import Node2Vec\n", + "\n", + "data = \n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "model = Node2Vec(data.edge_index, embedding_dim=128, \n", + " walk_length=20, # lenght of rw\n", + " context_size=10, walks_per_node=20,\n", + " num_negative_samples=1, \n", + " p=200, q=1, # bias parameters\n", + " sparse=True).to(device)\n", + "\n", + "loader = model.loader(batch_size=128, shuffle=True, num_workers=4)\n", + "\n", + "for idx, (pos_rw, neg_rw) in enumerate(loader):\n", + " print(idx, pos_rw.shape, neg_rw.shape)\n", + " \n", + "edge_tuples = [tuple(x) for x in data.edge_index.numpy().transpose()]\n", + "G = nx.from_edgelist(edge_tuples)\n", + "pos = nx.spring_layout(G, center=[0.5, 0.5])\n", + "nx.set_node_attributes(G, pos, 'pos')" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "fd70b4c63b8ac7010e057e1e7961ebae705e9dba34aa5a2e9dfe5bc9196414e5" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit ('pyg': conda)", + "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.7" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sentence_transformer_pg.py b/sentence_transformer_pg.py index 99d5fa5..f219adc 100644 --- a/sentence_transformer_pg.py +++ b/sentence_transformer_pg.py @@ -15,8 +15,8 @@ model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu') embeddings = model.encode([ - 'this is about a cat', - 'but this one is not about animals', + 'my cat is crazy', + 'this one is not about animals', 'this is about a dog', 'but this one is about animals', 'this one is about humans', diff --git a/graph_embeddings_pg.ipynb b/graph_embeddings_pg.ipynb new file mode 100644 index 0000000..5af00ee --- /dev/null +++ b/graph_embeddings_pg.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Collecting package metadata (current_repodata.json): done\n", + "Solving environment: done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%conda install pyg -c pyg -c conda-forge\n", + "%conda install pytorch torchvision torchaudio -c pytorch\n", + "%pip install networkx seaborn -Uq" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "\n", + "from tqdm import tqdm\n", + "\n", + "\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "AttributeError", + "evalue": "'Graph' object has no attribute 'edge_index'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/3_/gmvd1nkx285133z5yh3chz2c0000gp/T/ipykernel_16599/2356794267.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0mnx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdraw_networkx_edge_labels\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpubmed_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpos\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0medge_labels\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlabels\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mpubmed_graph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medge_index\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'Graph' object has no attribute 'edge_index'" + ] + } + ], + "source": [ + "# pubmed = pd.read_csv('~/workspace/cogtext/data/pubmed_abstracts.')\n", + "\n", + "# pubmed = pd.DataFrame(np.random.random((100,2)), columns=['label','pmid','vector'])\n", + "# pubmed.head()\n", + "\n", + "pubmed_graph = nx.random_geometric_graph(5,5)\n", + "\n", + "for (u, v) in pubmed_graph.edges():\n", + " pubmed_graph.edges[u,v]['weight'] = np.random.randint(0,10)\n", + "\n", + "pos = nx.spring_layout(pubmed_graph)\n", + "nx.draw(pubmed_graph, pos)\n", + "labels = nx.get_edge_attributes(pubmed_graph, 'weight')\n", + "nx.draw_networkx_edge_labels(pubmed_graph, pos,edge_labels=labels)\n", + "plt.show()\n", + "pubmed_graph" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create an edge between two nodes if their corresponding corpora share documents >= min_docs. The weight of the edge will be set to the pointwise mutual information between the two labels.\n", + "\n", + "log(xy) - log(x) - log(y) + log(D)\n", + "xy is the number of articles shared between the two labels\n", + "x is the number of articles in the x corpus\n", + "and D is the total number of articles" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch_geometric.nn import Node2Vec\n", + "\n", + "data = \n", + "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "model = Node2Vec(data.edge_index, embedding_dim=128, \n", + " walk_length=20, # lenght of rw\n", + " context_size=10, walks_per_node=20,\n", + " num_negative_samples=1, \n", + " p=200, q=1, # bias parameters\n", + " sparse=True).to(device)\n", + "\n", + "loader = model.loader(batch_size=128, shuffle=True, num_workers=4)\n", + "\n", + "for idx, (pos_rw, neg_rw) in enumerate(loader):\n", + " print(idx, pos_rw.shape, neg_rw.shape)\n", + " \n", + "edge_tuples = [tuple(x) for x in data.edge_index.numpy().transpose()]\n", + "G = nx.from_edgelist(edge_tuples)\n", + "pos = nx.spring_layout(G, center=[0.5, 0.5])\n", + "nx.set_node_attributes(G, pos, 'pos')" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "fd70b4c63b8ac7010e057e1e7961ebae705e9dba34aa5a2e9dfe5bc9196414e5" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit ('pyg': conda)", + "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.7" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sentence_transformer_pg.py b/sentence_transformer_pg.py index 99d5fa5..f219adc 100644 --- a/sentence_transformer_pg.py +++ b/sentence_transformer_pg.py @@ -15,8 +15,8 @@ model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu') embeddings = model.encode([ - 'this is about a cat', - 'but this one is not about animals', + 'my cat is crazy', + 'this one is not about animals', 'this is about a dog', 'but this one is about animals', 'this one is about humans', diff --git a/text_embeddings_pg.ipynb b/text_embeddings_pg.ipynb new file mode 100644 index 0000000..1552784 --- /dev/null +++ b/text_embeddings_pg.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Downloading: 100%|██████████| 28.0/28.0 [00:00<00:00, 7.90kB/s]\n", + "Downloading: 100%|██████████| 483/483 [00:00<00:00, 239kB/s]\n", + "Downloading: 100%|██████████| 226k/226k [00:00<00:00, 329kB/s]\n", + "Downloading: 100%|██████████| 455k/455k [00:01<00:00, 358kB/s]\n", + "Downloading: 100%|██████████| 256M/256M [01:28<00:00, 3.02MB/s]\n" + ] + } + ], + "source": [ + "from transformers import AutoTokenizer, AutoModelForMaskedLM\n", + "from transformers import TFDistilBertModel, DistilBertConfig\n", + "\n", + "tokenizer = AutoTokenizer.from_pretrained('distilbert-base-uncased')\n", + "model = AutoModelForMaskedLM.from_pretrained('distilbert-base-uncased')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from transformers import DistilBertTokenizerFast\n", + "\n", + "# Instantiate DistilBERT tokenizer...we use the Fast version to optimize runtime\n", + "tokenizer = DistilBertTokenizerFast.from_pretrained('distilbert-base-uncased')\n", + "\n", + "# Define the maximum number of words to tokenize (DistilBERT can tokenize up to 512)\n", + "MAX_LENGTH = 512\n", + "BATCH_SIZE = 512\n", + "\n", + "# Define function to encode text data in batches\n", + "def batch_encode(tokenizer, texts, batch_size=BATCH_SIZE, max_length=MAX_LENGTH):\n", + " \"\"\"\"\"\"\"\"\"\n", + " A function that encodes a batch of texts and returns the texts'\n", + " corresponding encodings and attention masks that are ready to be fed \n", + " into a pre-trained transformer model.\n", + " \n", + " Input:\n", + " - tokenizer: Tokenizer object from the PreTrainedTokenizer Class\n", + " - texts: List of strings where each string represents a text\n", + " - batch_size: Integer controlling number of texts in a batch\n", + " - max_length: Integer controlling max number of words to tokenize in a given text\n", + " Output:\n", + " - input_ids: sequence of texts encoded as a tf.Tensor object\n", + " - attention_mask: the texts' attention mask encoded as a tf.Tensor object\n", + " \"\"\"\"\"\"\"\"\"\n", + " \n", + " input_ids = []\n", + " attention_mask = []\n", + " \n", + " for i in range(0, len(texts), batch_size):\n", + " batch = texts[i:i+batch_size]\n", + " inputs = tokenizer.batch_encode_plus(batch,\n", + " max_length=max_length,\n", + " padding='longest', #implements dynamic padding\n", + " truncation=True,\n", + " return_attention_mask=True,\n", + " return_token_type_ids=False\n", + " )\n", + " input_ids.extend(inputs['input_ids'])\n", + " attention_mask.extend(inputs['attention_mask'])\n", + " \n", + " \n", + " return tf.convert_to_tensor(input_ids), tf.convert_to_tensor(attention_mask)\n", + " \n", + " \n", + "# Encode X_train\n", + "X_train_ids, X_train_attention = batch_encode(tokenizer, X_train.tolist())\n", + "\n", + "# Encode X_valid\n", + "X_valid_ids, X_valid_attention = batch_encode(tokenizer, X_valid.tolist())\n", + "\n", + "# Encode X_test\n", + "X_test_ids, X_test_attention = batch_encode(tokenizer, X_test.tolist())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from transformers import TFDistilBertModel, DistilBertConfig\n", + "\n", + "DISTILBERT_DROPOUT = 0.2\n", + "DISTILBERT_ATT_DROPOUT = 0.2\n", + " \n", + "# Configure DistilBERT's initialization\n", + "config = DistilBertConfig(dropout=DISTILBERT_DROPOUT, \n", + " attention_dropout=DISTILBERT_ATT_DROPOUT, \n", + " output_hidden_states=True)\n", + " \n", + "# The bare, pre-trained DistilBERT transformer model outputting raw hidden-states \n", + "# and without any specific head on top.\n", + "distilBERT = TFDistilBertModel.from_pretrained('distilbert-base-uncased', config=config)\n", + "\n", + "# Make DistilBERT layers untrainable\n", + "for layer in distilBERT.layers:\n", + " layer.trainable = False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "MAX_LENGTH = 128\n", + "LAYER_DROPOUT = 0.2\n", + "LEARNING_RATE = 5e-5\n", + "RANDOM_STATE = 42\n", + "\n", + "def build_model(transformer, max_length=MAX_LENGTH):\n", + " \"\"\"\"\"\"\"\"\"\n", + " Template for building a model off of the BERT or DistilBERT architecture\n", + " for a binary classification task.\n", + " \n", + " Input:\n", + " - transformer: a base Hugging Face transformer model object (BERT or DistilBERT)\n", + " with no added classification head attached.\n", + " - max_length: integer controlling the maximum number of encoded tokens \n", + " in a given sequence.\n", + " \n", + " Output:\n", + " - model: a compiled tf.keras.Model with added classification layers \n", + " on top of the base pre-trained model architecture.\n", + " \"\"\"\"\"\"\"\"\"\"\n", + " \n", + " # Define weight initializer with a random seed to ensure reproducibility\n", + " weight_initializer = tf.keras.initializers.GlorotNormal(seed=RANDOM_STATE) \n", + " \n", + " # Define input layers\n", + " input_ids_layer = tf.keras.layers.Input(shape=(max_length,), \n", + " name='input_ids', \n", + " dtype='int32')\n", + " input_attention_layer = tf.keras.layers.Input(shape=(max_length,), \n", + " name='input_attention', \n", + " dtype='int32')\n", + " \n", + " # DistilBERT outputs a tuple where the first element at index 0\n", + " # represents the hidden-state at the output of the model's last layer.\n", + " # It is a tf.Tensor of shape (batch_size, sequence_length, hidden_size=768).\n", + " last_hidden_state = transformer([input_ids_layer, input_attention_layer])[0]\n", + " \n", + " # We only care about DistilBERT's output for the [CLS] token, \n", + " # which is located at index 0 of every encoded sequence. \n", + " # Splicing out the [CLS] tokens gives us 2D data.\n", + " cls_token = last_hidden_state[:, 0, :]\n", + " \n", + " ## ##\n", + " ## Define additional dropout and dense layers here ##\n", + " ## ##\n", + " \n", + " # Define a single node that makes up the output layer (for binary classification)\n", + " output = tf.keras.layers.Dense(1, \n", + " activation='sigmoid',\n", + " kernel_initializer=weight_initializer, \n", + " kernel_constraint=None,\n", + " bias_initializer='zeros'\n", + " )(cls_token)\n", + " \n", + " # Define the model\n", + " model = tf.keras.Model([input_ids_layer, input_attention_layer], output)\n", + " \n", + " # Compile the model\n", + " model.compile(tf.keras.optimizers.Adam(lr=LEARNING_RATE), \n", + " loss=focal_loss(),\n", + " metrics=['accuracy'])\n", + " \n", + " return model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "EPOCHS = 6\n", + "BATCH_SIZE = 64\n", + "NUM_STEPS = len(X_train.index) // BATCH_SIZE\n", + "\n", + "# Train the model\n", + "train_history1 = model.fit(\n", + " x = [X_train_ids, X_train_attention],\n", + " y = y_train.to_numpy(),\n", + " epochs = EPOCHS,\n", + " batch_size = BATCH_SIZE,\n", + " steps_per_epoch = NUM_STEPS,\n", + " validation_data = ([X_valid_ids, X_valid_attention], y_valid.to_numpy()),\n", + " verbose=2\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "FT_EPOCHS = 4\n", + "BATCH_SIZE = 64\n", + "NUM_STEPS = len(X_train.index)\n", + "\n", + "# Unfreeze distilBERT layers and make available for training\n", + "for layer in distilBERT.layers:\n", + " layer.trainable = True\n", + " \n", + "# Recompile model after unfreezing\n", + "model.compile(optimizer=tf.keras.optimizers.Adam(lr=2e-5), \n", + " loss=focal_loss(),\n", + " metrics=['accuracy'])\n", + "\n", + "# Train the model\n", + "train_history2 = model.fit(\n", + " x = [X_train_ids, X_train_attention],\n", + " y = y_train.to_numpy(),\n", + " epochs = FT_EPOCHS,\n", + " batch_size = BATCH_SIZE,\n", + " steps_per_epoch = NUM_STEPS,\n", + " validation_data = ([X_valid_ids, X_valid_attention], y_valid.to_numpy()),\n", + " verbose=2\n", + ")" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "4d4c55ad0dd25f9ca95e4d49a929aa3f71bfb37020ae570a9996c3e164818202" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit ('py3': conda)", + "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.7" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}