Как решить классификацию медицинских выписок с помощью машинного обучения и опубликовать модель и панель мониторинга данных для следующего

Введение

Это решение демонстрирует, как обучить и развернуть предварительно обученную модель Huggingface в AWS SageMaker, а также опубликовать панель мониторинга AWS QuickSight, которая визуализирует производительность модели по сравнению с проверочным набором данных и исследовательский анализ данных для предварительно обработанного обучающего набора данных. Используя эту архитектуру для предлагаемого решения, мы пытаемся решить классификацию медицинских выписок с помощью машинного обучения, что в основном решает проблему биомедицинского НЛП. В этом решении мы также обсуждаем разработку функций и обработку несбалансированных наборов данных с помощью весов классов во время обучения, написав собственный тренажер Huggingface в PyTorch.

Значение использования Huggingface с SageMaker заключается в том, чтобы упростить обучение модели на основе трансформера в SageMaker и облегчить их развертывание в рабочей среде. Кроме того, использование QuickSight Dashboard объединяет анализ данных и моделей под одной крышей, что упрощает мониторинг и настройку. Предлагаемый конвейер для информационных панелей очень удобен, когда проекту требуется панель на стороне сервера для мониторинга модели и данных администратором или командой разработчиков.

Архитектура

Видео Демонстрация

Ниже представлено демонстрационное видео предлагаемой архитектуры.

Постановка задачи

Прогнозирование диагноза предназначено для автоматического прогнозирования диагноза, необходимого пациенту с определенным анамнезом.

Анамнез представляет собой необработанный текстовый файл с заметками врача о пациенте, включая его возраст, жалобы, описанные на автостраде, историю болезни пациента и так далее. Он неструктурирован — разные разделы анамнеза одного больного могут отсутствовать у другого.

Целевые метки представлены названием необходимой диагностической процедуры.

Ценность решения может заключаться в том, чтобы помочь врачу найти оптимальное решение для заказа диагностики. Пациент может сэкономить время и деньги, а врач может более эффективно обслуживать пациента, экономя время на ненужной диагностике. Более того, в сложных случаях алгоритм может помочь врачу быстрее поставить диагноз, что в ряде случаев может быть крайне ценным, вплоть до спасения жизни.

Теоретически некоторые закономерности, найденные алгоритмом, могут помочь исследователям-медикам найти идею лечения некоторых заболеваний, основанную на их неочевидных взаимосвязях с некоторыми симптомами.

Набор данных и хранилище

Все наборы данных хранятся в сегменте S3 (medical-transcription-repo)в наборе данных. каталог. Этот набор данных содержит образцы медицинских транскрипций для различных медицинских специальностей.

Предварительно обработанные и разработанные наборы данных хранятся в одном и том же сегменте S3 в другом каталоге (s3://medical-transcription-repo/preprocess/). То же самое касается и хранилища моделей (s3://medical-transcription-repo/models/).

Точно так же в каталоге корзины preprocesss3 мы храним обучающие данные и наборы данных проверки для дальнейшего использования.

- dataset
     - dataset.csv
- preprocess
     - pre-processed
           - eval
              - validation.csv
           -pre-processed.csv
     - train
           - dataset-info.json
     -test
           - dataset-infor.json
- models
      - huggingface-dd-mm-yyyy:hh-mm-ss
           - output
              - model.tar.gz
              - output.tar.gz

Источник набора данных

Данные медицинской транскрипции взяты с сайта mtsamples.com. Этот набор данных предлагает решение, предоставляя медицинские образцы транскрипции.

Обучение модели машинного обучения, развертывание и вывод

AWS SageMaker

Для обучения и развертывания модели в SageMaker использовались следующие сервисы:

  • экземпляры ноутбука (ml.t2.medium )
  • Обучающие задания (ml.p3.2xlarge )
  • Конечная точка вывода (ml.t2.medium )

Предварительная обработка и проектирование функций

Исходный набор данных состоит из 40 классов, которые нужно классифицировать, но некоторые наборы классов были удалены из-за отсутствия достаточного количества обучающих примеров для этих классов, что в конечном итоге привело к проблеме классификации 23 классов. Затем предварительно обработанный набор данных загружается в корзину s3 для дальнейшего создания информационной панели EDA в AWS QuickSight.

Затем набор данных разбивается на обучающий и проверочный наборы и разбивается на текстовые данные. Предварительно обученный токенизатор distilbert-base-uncased используется для токенизации входных данных.

from transformers import AutoTokenizer
# tokenizer used in preprocessing
tokenizer_name = 'distilbert-base-uncased'
# download tokenizer
tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
# tokenizer helper function
def tokenize(batch):
    return tokenizer(batch['text'],padding=True, truncation=True)
# tokenize dataset
train_dataset = dataset['train'].map(tokenize, batched=True)
test_dataset = dataset['test'].map(tokenize, batched=True)
# set format for pytorch
train_dataset =  train_dataset.rename_column("target", "labels")
train_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])
test_dataset = test_dataset.rename_column("target", "labels")
test_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])

Токенизированные обучающие и проверочные наборы загружаются в корзину s3.

import botocore
from datasets.filesystems import S3FileSystem
s3 = S3FileSystem()  
prefix = 'preprocess'
# save train_dataset to s3
training_input_path = f's3://{bucket}/{prefix}/train'
train_dataset.save_to_disk(training_input_path,fs=s3)
# save test_dataset to s3
test_input_path = f's3://{bucket}/{prefix}/test'
test_dataset.save_to_disk(test_input_path,fs=s3)

Оценка весов классов

Что касается дисбаланса классов, необходимо учитывать один аспект: каждая партия имеет достаточно сигнала, чтобы обеспечить некоторое покрытие всех классов, даже несбалансированных. В противном случае он может дегенерировать во время тренировок.

В этом случае мы используем веса классов для обработки несбалансированного набора данных.

from sklearn.utils import class_weight
class_weights = dict(enumerate(class_weight.compute_class_weight(‘balanced’,
               classes=np.unique(df[‘target’]),
               y=df[‘target’])))

Индивидуальный трейнер Huggingface

Для обучения модели используется предварительно обученная модель distilbert-base-uncased и пользовательская функция потерь для обработки несбалансированного набора данных.

from transformers import Trainer, TrainingArguments, AutoTokenizer
# create Trainer instance
# Subclass Trainer and override the compute_loss method
class MedModelTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        labels = inputs.get("labels")
        # forward pass
        outputs = model(**inputs)
        logits = outputs.get("logits")
        # compute custom loss
        loss_fct = torch.nn.CrossEntropyLoss(weight=torch.tensor(list(class_weights.values())))
        loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
        return (loss, outputs) if return_outputs else loss
trainer = MedModelTrainer(
    model=model,
    args=training_args,
    compute_metrics=compute_metrics,
    train_dataset=train_dataset,
    eval_dataset=test_dataset,
    tokenizer=tokenizer,
)
# train model
trainer.train()

Создание оценщика и запуск задания обучения

Hugging Face Deep DLC (контейнеры глубокого обучения) упрощают обучение моделей трансформеров в SageMaker. Ниже приведены некоторые из причин, по которым вам следует использовать DLC Hugging Face для обучения и развертывания вашей следующей модели машинного обучения:
* Одна команда — это все, что вам нужно.
* Ускорить переход машинного обучения от исследований к производство.
* Встроенная производительность.

В среде обучения SageMaker этот оценщик выполняет сценарий обучения Hugging Face.

Используя предварительно созданный контейнер Hugging Face Docker, оценщик запускает среду Hugging Face, управляемую SageMaker, и выполняет сценарий обучения Hugging Face, предоставленный пользователем с помощью аргумента entry_point.

from sagemaker.huggingface import HuggingFace, TrainingCompilerConfig
# initialize the Amazon Training Compiler
compiler_config=TrainingCompilerConfig()
# hyperparameters, which are passed into the training job
hyperparameters={'epochs': 10,
                 'train_batch_size': 64,
                 'eval_batch_size': 32,
                 'learning_rate': 3e-5, 
                 'model_name':'distilbert-base-uncased'
                 }
huggingface_estimator = HuggingFace(entry_point='train.py',
                            source_dir='./scripts',
                            instance_type='ml.p3.2xlarge',
                            instance_count=1,
                            role=role,
                            transformers_version='4.11.0',
                            pytorch_version='1.9.0',
                            py_version='py38', output_path='s3://{}/models'.format(bucket),
                            hyperparameters = hyperparameters,
                            compiler_config = compiler_config
                                   )

Запуск задания обучения с загруженными наборами данных в качестве входных данных.

huggingface_estimator.fit({'train': training_input_path, 'test': test_input_path})

Развертывание конечной точки

Чтобы развернуть нашу конечную точку, мы вызываем deploy() для нашего объекта оценки HuggingFace, передавая желаемое количество экземпляров и тип экземпляра.

predictor = huggingface_estimator.deploy(1,"ml.t2.medium")

Для вывода вы можете использовать обученную модель Hugging Face или одну из предварительно обученных моделей Hugging Face, чтобы развернуть задание вывода с помощью SageMaker. Благодаря этому сотрудничеству вам потребуется всего одна строка кода для развертывания как обученных, так и предварительно обученных моделей с помощью SageMaker.

eval_df = pd.read_csv('test.csv')
eval_df['pred'] = 0
eval_df['score'] = 0.0
max_length = 512
for i in range(len(eval_df)):
    sentiment_input= {"inputs": eval_df['text'].iloc[i][:max_length]}
    eval_df['pred'][i] = int(predictor.predict(sentiment_input)[0]['label'].split('_')[1])
    eval_df['score'][i] = float(predictor.predict(sentiment_input)[0]['score'])

Набор проверки с предсказанием модели хранится в корзине s3 для разработки панели мониторинга производительности модели в AWS QuickSight.

eval_df.to_csv("model-performance.csv", index=False)
s3 = boto3.resource('s3')
s3.meta.client.upload_file('model-performance.csv', bucket, 'preprocess/pre-processed/eval/model-performance.csv')

Исходный код

Исходный код для следующей предлагаемой архитектуры приведен ниже:

Архитектура для размещения панели инструментов QuickSight для мониторинга модели HuggingFace, развернутой в SageMaker вместе с данными EDA

AWS QuickSight

Quicksight — это облачный бессерверный сервис бизнес-аналитики, предоставляемый AWS.

Приборная панель EDA визуализируется поверх предварительно обработанных данных медицинской выписки. Анализ фокусируется на распределении медицинских специальностей, их подгрупп, отношениях между ними, облаке слов для контекста транскрипции и т. д.

Панель мониторинга «Производительность модели» визуализируется для прогнозирования модели по проверочному набору данных медицинской транскрипции. Анализ фокусируется на правильности предсказания модели; разница между распределением целевого класса и прогнозируемого класса; Точность, точность, отзыв и оценка f1 модели по сравнению с проверочным набором и т. д.

Расчетное поле для графика корректности

ifelse(pred=target, "Correct", "Wrong")

Расчетное поле для Точности ( % )

(countIf(Correctness, Correctness="Correct")/ count(Correctness)) * 100

Расчетное поле для Точности ( % )

((countIf(pred, pred=0 AND target=0)/countIf(pred, pred=0) +
countIf(pred, pred=1 AND target=1)/countIf(pred, pred=1) +
countIf(pred, pred=2 AND target=2)/countIf(pred, pred=2) +
countIf(pred, pred=3 AND target=3)/countIf(pred, pred=3) +
countIf(pred, pred=4 AND target=4)/countIf(pred, pred=4) +
countIf(pred, pred=5 AND target=5)/countIf(pred, pred=5) +
countIf(pred, pred=6 AND target=6)/countIf(pred, pred=6) +
countIf(pred, pred=7 AND target=7)/countIf(pred, pred=7) +
countIf(pred, pred=8 AND target=8)/countIf(pred, pred=8) +
countIf(pred, pred=9 AND target=9)/countIf(pred, pred=9) +
countIf(pred, pred=10 AND target=10)/countIf(pred, pred=10) +
countIf(pred, pred=11 AND target=11)/countIf(pred, pred=11) +
countIf(pred, pred=11 AND target=11)/countIf(pred, pred=11) +
countIf(pred, pred=12 AND target=12)/countIf(pred, pred=12) +
countIf(pred, pred=13 AND target=13)/countIf(pred, pred=13) +
countIf(pred, pred=14 AND target=14)/countIf(pred, pred=14) +
countIf(pred, pred=15 AND target=15)/countIf(pred, pred=15) +
countIf(pred, pred=16 AND target=16)/countIf(pred, pred=16) +
countIf(pred, pred=17 AND target=17)/countIf(pred, pred=17) +
countIf(pred, pred=18 AND target=18)/countIf(pred, pred=18) +
countIf(pred, pred=19 AND target=19)/countIf(pred, pred=19) +
countIf(pred, pred=20 AND target=20)/countIf(pred, pred=20) +
countIf(pred, pred=21 AND target=21)/countIf(pred, pred=21) +
countIf(pred, pred=22 AND target=22)/countIf(pred, pred=22)) /23) *100

Расчетное поле для отзыва ( % )

((countIf(pred, pred=0 AND target=0)/countIf(target, target=0) +
countIf(pred, pred=1 AND target=1)/countIf(target, target=1) +
countIf(pred, pred=2 AND target=2)/countIf(target, target=2) +
countIf(pred, pred=3 AND target=3)/countIf(target, target=3) +
countIf(pred, pred=4 AND target=4)/countIf(target, target=4) +
countIf(pred, pred=5 AND target=5)/countIf(target, target=5) +
countIf(pred, pred=6 AND target=6)/countIf(target, target=6) +
countIf(pred, pred=7 AND target=7)/countIf(target, target=7) +
countIf(pred, pred=8 AND target=8)/countIf(target, target=8) +
countIf(pred, pred=9 AND target=9)/countIf(target, target=9) +
countIf(pred, pred=10 AND target=10)/countIf(target, target=10) +
countIf(pred, pred=11 AND target=11)/countIf(target, target=11) +
countIf(pred, pred=11 AND target=11)/countIf(target, target=11) +
countIf(pred, pred=12 AND target=12)/countIf(target, target=12) +
countIf(pred, pred=13 AND target=13)/countIf(target, target=13) +
countIf(pred, pred=14 AND target=14)/countIf(target, target=14) +
countIf(pred, pred=15 AND target=15)/countIf(target, target=15) +
countIf(pred, pred=16 AND target=16)/countIf(target, target=16) +
countIf(pred, pred=17 AND target=17)/countIf(target, target=17) +
countIf(pred, pred=18 AND target=18)/countIf(target, target=18) +
countIf(pred, pred=19 AND target=19)/countIf(target, target=19) +
countIf(pred, pred=20 AND target=20)/countIf(target, target=20) +
countIf(pred, pred=21 AND target=21)/countIf(target, target=21) +
countIf(pred, pred=22 AND target=22)/countIf(target, target=22)) /23) *100

Расчетное поле для f1-оценки ( % )

2 * (Precision*Recall ) / (Precision + Recall)

Заключение

Предлагаемая облачная архитектура AWS предоставляет решение для обучения и развертывания предварительно обученных моделей NLP на основе преобразователя, доступных в Huggingface, для производства с помощью AWS SageMaker. AWS QuickSight используется для публикации информационных панелей для визуализации EDA для базового набора данных и производительности модели машинного обучения по сравнению с проверочным набором, что успешно объединяет анализ данных и модели под одной крышей.

Объемы улучшений

  • Информационная панель производительности модели может быть улучшена, чтобы добавить оценки точности и отзыва для каждого класса.
  • Добавление матрицы путаницы на панель мониторинга производительности модели.
  • Обучение модели для более высоких эпох для хорошей сходимости.
  • Попробуйте различные предварительно обученные модели, такие как Bert и RoBerta, для повышения производительности модели.
  • Улучшение методов разработки функций, таких как сокращение целевых классов или использование методов Minority Oversampling для повышения производительности.

Ссылка