From ccd69532091af7fcf0c1f45421a78a91ceda8968 Mon Sep 17 00:00:00 2001 From: Dmitri Soshnikov <dmitri@soshnikov.com> Date: Mon, 23 May 2022 12:12:45 +0300 Subject: [PATCH] Add NER lesson and lab --- README.md | 2 +- lessons/5-NLP/19-NER/NER-TF.ipynb | 481 ++++++++++++++++++++++++ lessons/5-NLP/19-NER/README.md | 69 +++- lessons/5-NLP/19-NER/images/bot-ner.png | Bin 0 -> 38663 bytes lessons/5-NLP/19-NER/lab/README.md | 47 +++ lessons/6-Other/22-DeepRL/README.md | 2 +- 6 files changed, 598 insertions(+), 3 deletions(-) create mode 100644 lessons/5-NLP/19-NER/NER-TF.ipynb create mode 100644 lessons/5-NLP/19-NER/images/bot-ner.png create mode 100644 lessons/5-NLP/19-NER/lab/README.md diff --git a/README.md b/README.md index f10e688..b931f87 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ For a gentle introduction to *AI in the Cloud* topics you may consider taking th <tr><td>16</td><td>Recurrent Neural Networks</td><td><a href="lessons/5-NLP/16-RNN/README.md">Text</a></td><td><a href="lessons/5-NLP/16-RNN/RNNPyTorch.ipynb">PyTorch</a></td><td><a href="lessons/5-NLP/16-RNN/RNNTF.ipynb">TensorFlow</a></td><td></td></tr> <tr><td>17</td><td>Generative Recurrent Networks</td><td><a href="lessons/5-NLP/17-GenerativeNetworks/README.md">Text</a></td><td><a href="lessons/5-NLP/17-GenerativeNetworks/GenerativePyTorch.md">PyTorch</a></td><td><a href="lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.md">TensorFlow</a></td><td><a href="lessons/5-NLP/17-GenerativeNetworks/lab/README.md">Lab</a></td></tr> <tr><td>18</td><td>Transformers. BERT.</td><td><a href="lessons/5-NLP/18-Transformers/README.md">Text</a></td><td><a href="lessons/5-NLP/18-Transformers/TransformersPyTorch.md">PyTorch</a></td><td><a href="lessons/5-NLP/18-Transformers/TransformersTF.md">TensorFlow</a></td><td></td></tr> -<tr><td>19</td><td>Named Entity Recognition</td><td>Text</td><td>PyTorch</td><td>TensorFlow</td><td></td></tr> +<tr><td>19</td><td>Named Entity Recognition</td><td><a href="lessons/5-NLP/19-NER/README.md">Text</a></td><td></td><td><a href="lessons/5-NLP/19-NER/NER-TF.ipynb">TensorFlow</a></td><a href="lessons/5-NLP/19-NER/lab/README.md">Lab</a><td></td></tr> <tr><td>20</td><td>Large Language Models, Prompt Programming and Few-Shot Tasks</td><td>Text</td><td>PyTorch</td><td>TensorFlow</td><td></td></tr> <tr><td>VI</td><td colspan="4"><b>Other AI Techniques</b></td><td></td></tr> <tr><td>21</td><td>Genetic Algorithms</td><td><a href="lessons/6-Other/21-GeneticAlgorithms/README.md">Text</a><td colspan="2"><a href="lessons/6-Other/21-GeneticAlgorithms/Genetic.ipynb">Notebook</a></td><td></td></tr> diff --git a/lessons/5-NLP/19-NER/NER-TF.ipynb b/lessons/5-NLP/19-NER/NER-TF.ipynb new file mode 100644 index 0000000..46ed324 --- /dev/null +++ b/lessons/5-NLP/19-NER/NER-TF.ipynb @@ -0,0 +1,481 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Named Entity Recognition (NER)\n", + "\n", + "This notebook is from [AI for Beginners Curriculum](http://aka.ms/ai-beginners).\n", + "\n", + "In this example, we will learn how to train NER model on [Annotated Corpus for Named Entity Recognition](https://www.kaggle.com/datasets/abhinavwalia95/entity-annotated-corpus) Dataset from Kaggle. Before procedding, please donwload [ner_dataset.csv](https://www.kaggle.com/datasets/abhinavwalia95/entity-annotated-corpus?resource=download&select=ner_dataset.csv) file into current directory." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "from tensorflow import keras\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Preparing the Dataset \n", + "\n", + "We will start by reading the dataset into a dataframe. If you want to learn more about using Pandas, visit a [lesson on data processing](https://github.com/microsoft/Data-Science-For-Beginners/tree/main/2-Working-With-Data/07-python) in our [Data Science for Beginners](http://aka.ms/datascience-beginners)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>Sentence #</th>\n", + " <th>Word</th>\n", + " <th>POS</th>\n", + " <th>Tag</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>Sentence: 1</td>\n", + " <td>Thousands</td>\n", + " <td>NNS</td>\n", + " <td>O</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>NaN</td>\n", + " <td>of</td>\n", + " <td>IN</td>\n", + " <td>O</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>NaN</td>\n", + " <td>demonstrators</td>\n", + " <td>NNS</td>\n", + " <td>O</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>NaN</td>\n", + " <td>have</td>\n", + " <td>VBP</td>\n", + " <td>O</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>NaN</td>\n", + " <td>marched</td>\n", + " <td>VBN</td>\n", + " <td>O</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Sentence # Word POS Tag\n", + "0 Sentence: 1 Thousands NNS O\n", + "1 NaN of IN O\n", + "2 NaN demonstrators NNS O\n", + "3 NaN have VBP O\n", + "4 NaN marched VBN O" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('ner_dataset.csv',encoding='unicode-escape')\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's get unique tags and create lookup dictionaries that we can use to convert tags into class numbers:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['O', 'B-geo', 'B-gpe', 'B-per', 'I-geo', 'B-org', 'I-org', 'B-tim',\n", + " 'B-art', 'I-art', 'I-per', 'I-gpe', 'I-tim', 'B-nat', 'B-eve',\n", + " 'I-eve', 'I-nat'], dtype=object)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tags = df.Tag.unique()\n", + "tags" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'O'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "id2tag = dict(enumerate(tags))\n", + "tag2id = { v : k for k,v in id2tag.items() }\n", + "\n", + "id2tag[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need to do the same with vocabulary. For simplicity, we will create vocabulary without taking word frequency into account; in real life you might want to use Keras vectorizer, and limit the number of words." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "vocab = set(df['Word'].apply(lambda x: x.lower()))\n", + "id2word = { i+1 : v for i,v in enumerate(vocab) }\n", + "id2word[0] = '<UNK>'\n", + "vocab.add('<UNK>')\n", + "word2id = { v : k for k,v in id2word.items() }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need to create a dataset of sentences for training. Let's loop through the original dataset and separate all individual sentences into `X` (lists of words) and `Y` (list of tokens):" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "X,Y = [],[]\n", + "s,t = [],[]\n", + "for i,row in df[['Sentence #','Word','Tag']].iterrows():\n", + " if pd.isna(row['Sentence #']):\n", + " s.append(row['Word'])\n", + " t.append(row['Tag'])\n", + " else:\n", + " if len(s)>0:\n", + " X.append(s)\n", + " Y.append(t)\n", + " s,t = [row['Word']],[row['Tag']]\n", + "X.append(s)\n", + "Y.append(t)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now vectorize all words and tokens:" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([10386,\n", + " 23515,\n", + " 4134,\n", + " 29620,\n", + " 7954,\n", + " 13583,\n", + " 21193,\n", + " 12222,\n", + " 27322,\n", + " 18258,\n", + " 5815,\n", + " 15880,\n", + " 5355,\n", + " 25242,\n", + " 31327,\n", + " 18258,\n", + " 27067,\n", + " 23515,\n", + " 26444,\n", + " 14412,\n", + " 358,\n", + " 26551,\n", + " 5011,\n", + " 30558],\n", + " [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def vectorize(seq):\n", + " return [word2id[x.lower()] for x in seq]\n", + "\n", + "def tagify(seq):\n", + " return [tag2id[x] for x in seq]\n", + "\n", + "Xv = list(map(vectorize,X))\n", + "Yv = list(map(tagify,Y))\n", + "\n", + "Xv[0], Yv[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For simplicity, we will pad all sentences with 0 tokens to the maximum length. In real life, we might want to use more clever strategy, and pad sequences only within one minibatch." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "X_data = keras.preprocessing.sequence.pad_sequences(Xv,padding='post')\n", + "Y_data = keras.preprocessing.sequence.pad_sequences(Yv,padding='post')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Defining Token Classification Network\n", + "\n", + "We will use two-layer bidirectional LSTM network for token classification. In order to apply dense classifier to each of the output of the last LSTM layer, we will use `TimeDistributed` construction, which replicates the same dense layer to each of the outputs of LSTM at each step: " + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"sequential_3\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " embedding_4 (Embedding) (None, 104, 300) 9545400 \n", + " \n", + " bidirectional_6 (Bidirectio (None, 104, 200) 320800 \n", + " nal) \n", + " \n", + " bidirectional_7 (Bidirectio (None, 104, 200) 240800 \n", + " nal) \n", + " \n", + " time_distributed_3 (TimeDis (None, 104, 17) 3417 \n", + " tributed) \n", + " \n", + "=================================================================\n", + "Total params: 10,110,417\n", + "Trainable params: 10,110,417\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "maxlen = X_data.shape[1]\n", + "vocab_size = len(vocab)\n", + "num_tags = len(tags)\n", + "model = keras.models.Sequential([\n", + " keras.layers.Embedding(vocab_size, 300, input_length=maxlen),\n", + " keras.layers.Bidirectional(keras.layers.LSTM(units=100, activation='tanh', return_sequences=True)),\n", + " keras.layers.Bidirectional(keras.layers.LSTM(units=100, activation='tanh', return_sequences=True)),\n", + " keras.layers.TimeDistributed(keras.layers.Dense(num_tags, activation='softmax'))\n", + "])\n", + "model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n", + "model.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note here that we are explicity specifying `maxlen` for our dataset - in case we want the network to be able to handle variable length sequences, we need to be a bit more clever when defining the network.\n", + "\n", + "Let's now train the model. For speed, we will only train for one epoch, but you may try training for longer time. Also, you may want to separate some part of the dataset as training dataset, to observe validation accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1499/1499 [==============================] - 740s 488ms/step - loss: 0.0667 - acc: 0.9841\n" + ] + }, + { + "data": { + "text/plain": [ + "<keras.callbacks.History at 0x16f0bb2a310>" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.fit(X_data,Y_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Testing the Result\n", + "\n", + "Let's now see how our entity recognition model works on a sample sentence: " + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [], + "source": [ + "sent = 'John Smith went to Paris to attend a conference in cancer development institute'\n", + "words = sent.lower().split()\n", + "v = keras.preprocessing.sequence.pad_sequences([[word2id[x] for x in words]],padding='post',maxlen=maxlen)\n", + "res = model(v)[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "john -> B-per\n", + "smith -> I-per\n", + "went -> O\n", + "to -> O\n", + "paris -> B-geo\n", + "to -> O\n", + "attend -> O\n", + "a -> O\n", + "conference -> O\n", + "in -> O\n", + "cancer -> B-org\n", + "development -> I-org\n", + "institute -> I-org\n" + ] + } + ], + "source": [ + "r = np.argmax(res.numpy(),axis=1)\n", + "for i,w in zip(r,words):\n", + " print(f\"{w} -> {id2tag[i]}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Takeaway\n", + "\n", + "Even simple LSTM model shows reasonable results at NER. However, to get much better results, you may want to use large pre-trained language models such as BERT. Training BERT for NER using Huggingface Transformers library is described [here](https://huggingface.co/course/chapter7/2?fw=pt)." + ] + } + ], + "metadata": { + "interpreter": { + "hash": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f" + }, + "kernelspec": { + "display_name": "Python 3.8.12 ('py38')", + "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.8.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lessons/5-NLP/19-NER/README.md b/lessons/5-NLP/19-NER/README.md index f6e0339..380b458 100644 --- a/lessons/5-NLP/19-NER/README.md +++ b/lessons/5-NLP/19-NER/README.md @@ -1 +1,68 @@ -Placeholder \ No newline at end of file +# Named Entity Recognition + +Up to now, we have mostly been concentrating on one NLP task - classification. However, there are also other NLP tasks that can be accomplished with neural networks. One of those tasks is **[Named Entity Recognition](https://en.wikipedia.org/wiki/Named-entity_recognition)** (NER), which deals with recognizing specific entities within text, such as places, person names, date-time intervals, chemical formulae and so on. + +## [Pre-lecture quiz](https://black-ground-0cc93280f.1.azurestaticapps.net/quiz/119) + +## Example of Using NER + +Suppose you want to develop a natural language chat bot, similar to Amazon Alexa or Google Assistant. The way intelligent chat bots work is to *understand* what the user want by doing text classification on the input sentence. The result of this classification is so-called **intent**, which determines what a chat bot should do. + + + +> Image by author + +However, a user may provide some parameters as part of the phrase. For example, when asking for a weather, she may specify a location or date. A bot should be able to understand those entities, and fill in the parameter slots accordingly before performing the action. This is exactly when NER comes in. + +Another example would be [analyzing scientific medical papers](https://soshnikov.com/science/analyzing-medical-papers-with-azure-and-text-analytics-for-health/), one of the main things we need to look for are specific medical terms, such as diseases and medical substances. While a small number of diseases can probably be extracted using substring search, more complex entities, such as chemical compounds and medication names, need more complex approach. + +## NER as Token Classification + +NER models are essentially **token classification models**, because for each of the input tokens we need to decide whether it belongs to an entity or not, and if it does - to which entity class. + +Consider the following paper title: + +**Tricuspid valve regurgitation** and **lithium carbonate** **toxicity** in a newborn infant. + +Entities here are: +* Tricuspid valve regurgitation is a disease (`DIS`) +* Lithium carbonate is a chemical substance (`CHEM`) +* Toxicity is also a disease (`DIS`) + +Notice that one entity can span several tokens. And, as in this case, we need to distinguish between two consecutive entities. Thus it is common to use two classes for each entity - one specifying the first token of the entity (often `B-` prefix is used, for beginning), and another - the continuation of an entity (`I-`, for inner token). We also use `O` as a class to represent all other tokens. Such token tagging is called [BIO tagging](https://en.wikipedia.org/wiki/Inside%E2%80%93outside%E2%80%93beginning_(tagging)) (or IOB). When tagged, our title will look like this: + +Token | Tag +------|----- +Tricuspid | B-DIS +valve | I-DIS +regurgitation | I-DIS +and | O +lithium | B-CHEM +carbonate | I-CHEM +toxicity | B-DIS +in | O +a | O +newborn | O +infant | O +. | O + +Since we need to build one-to-one correspondence between tokens and this classes, we can train rightmost **many-to-many** neural network model from this picture: + + + +> *Image from blog post [Unreasonable Effectiveness of Recurrent Neural Networks](http://karpathy.github.io/2015/05/21/rnn-effectiveness/) by [Andrej Karpaty](http://karpathy.github.io/). NER token classification models correspond to right-most network architecture on this picture.* + +## Training NER models + +Since NER model is essentially a token classification model, we can use RNNs that we are already familiar with for this task. In this case, each block of recurrent network will return the token ID. Example notebook shows how to train LSTM for token classification. + +## ✍️ Example Notebooks: NER + +Continue your learning in the following notebooks: + +* [NER with TensorFlow](NER-TF.ipynb) + +## [Assignment](lab/README.md) + +In the assignment for this lesson, you will have to train medical entity recognition model. You can start with training LSTM model as described in this lesson, and proceed with using BERT transformer model. Read [the instructions](lab/README.md) to get all the details. + diff --git a/lessons/5-NLP/19-NER/images/bot-ner.png b/lessons/5-NLP/19-NER/images/bot-ner.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5c982566076065559362a5af407a758a5a4b35 GIT binary patch literal 38663 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 literal 0 HcmV?d00001 diff --git a/lessons/5-NLP/19-NER/lab/README.md b/lessons/5-NLP/19-NER/lab/README.md new file mode 100644 index 0000000..44e54da --- /dev/null +++ b/lessons/5-NLP/19-NER/lab/README.md @@ -0,0 +1,47 @@ +# NER + +Lab Assignment from [AI for Beginners Curriculum](https://github.com/microsoft/ai-for-beginners). + +## Task + +In this lab, you need to train named entity recognition model for medical terms. + +## The Dataset + +To train NER model, we need properly labeled dataset with medical entities. [BC5CDR dataset](https://biocreative.bioinformatics.udel.edu/tasks/biocreative-v/track-3-cdr/) contains labeled diseases and chemicals entities from more than 1500 papers. You may download the dataset after registering at their web site. + +BC5CDR Dataset looks like this: + +``` +6794356|t|Tricuspid valve regurgitation and lithium carbonate toxicity in a newborn infant. +6794356|a|A newborn with massive tricuspid regurgitation, atrial flutter, congestive heart failure, and a high serum lithium level is described. This is the first patient to initially manifest tricuspid regurgitation and atrial flutter, and the 11th described patient with cardiac disease among infants exposed to lithium compounds in the first trimester of pregnancy. Sixty-three percent of these infants had tricuspid valve involvement. Lithium carbonate may be a factor in the increasing incidence of congenital heart disease when taken during early pregnancy. It also causes neurologic depression, cyanosis, and cardiac arrhythmia when consumed prior to delivery. +6794356 0 29 Tricuspid valve regurgitation Disease D014262 +6794356 34 51 lithium carbonate Chemical D016651 +6794356 52 60 toxicity Disease D064420 +... +``` + +In this dataset, there are paper title and abstract in the first two lines, and then there are individual entities, with beginning and end positions within title+abstract block. In addition to entity type, you get the ontology ID of this entity within some medical ontology. + +You will need to write some Python code to convert this into BIO encoding. + +## The Network + +First attempt at NER can be done by using LSTM network, as in our example you have seen during the lesson. However, in NLP tasks, [transformer architecture](https://en.wikipedia.org/wiki/Transformer_(machine_learning_model)), and specifically [BERT language models](https://en.wikipedia.org/wiki/BERT_(language_model)) show much better results. Pre-trained BERT models understand the general structure of a language, and can be fine-tuned for specific tasks with relatively small datasets and computational costs. + +Since we are planning to apply NER to medical scenario, it makes sense to use BERT model trained on medical texts. Microsoft Research has released a pre-trained a model called [PubMedBERT][PubMedBERT] ([publication][PubMedBERT-Pub]), which was fine-tuned using texts from [PubMed](https://pubmed.ncbi.nlm.nih.gov/) repository. + +The *de facto* standard for training transformer models is [Hugging Face Transformers](https://huggingface.co/) library. It also contains a repository of community-maintained pre-trained models, including PubMedBERT. To load and use this model, we just need a couple of lines of code: + +```python +model_name = "microsoft/BiomedNLP-PubMedBERT-base-uncased-abstract" +classes = ... # number of classes: 2*entities+1 +tokenizer = AutoTokenizer.from_pretrained(model_name) +model = BertForTokenClassification.from_pretrained(model_name, classes) +``` + +This gives us the `model` itself, built for token classification task using `classes` number of classes, as well as `tokenizer` object that can split input text into tokens. You will need to convert the dataset into BIO format, taking PubMedBERT tokenization into account. You can use [this bit of Python code](https://gist.github.com/shwars/580b55684be3328eb39ecf01b9cbbd88) as an inspiration. + +## Takeaway + +This task is very close to the actual task you are likely go have if you want to gain more insights into large volumes on natural language texts. In our case, we can apply our trained model to the [dataset of COVID-related papers](https://www.kaggle.com/allen-institute-for-ai/CORD-19-research-challenge) and see which insights we will be able to get. [This blog post](https://soshnikov.com/science/analyzing-medical-papers-with-azure-and-text-analytics-for-health/) and [this paper](https://www.mdpi.com/2504-2289/6/1/4) describe the research the can be done on this corpus of papers using NER. diff --git a/lessons/6-Other/22-DeepRL/README.md b/lessons/6-Other/22-DeepRL/README.md index 15ecb6c..6f3266f 100644 --- a/lessons/6-Other/22-DeepRL/README.md +++ b/lessons/6-Other/22-DeepRL/README.md @@ -94,7 +94,7 @@ Reinforcement Learning nowadays is a fast growing field of research. Some of the * Teaching computer to play board games, such as Chess and Go. Recent state-of-the-art programs like **Alpha Zero** was trained from scratch by two agents playing against each other, and improving at each step. * In industry, RL is used to create control systems from simulation. A service called [Bonsai](https://azure.microsoft.com/services/project-bonsai/) is specifically designed for that. -## Assignment: [Train a Mountain Car](labs/README.md) +## Assignment: [Train a Mountain Car](lab/README.md) Your goal during this assignment would be to train a different Gym environment - [Mountain Car](https://www.gymlibrary.ml/environments/classic_control/mountain_car/). -- GitLab