{ "cells": [ { "cell_type": "markdown", "id": "4c825f0a", "metadata": {}, "source": [ "# Sentiment Classification for Movie Review Dataset (English)\n", "\n", "본 핸즈온에서는 영화 리뷰에 대한 감정(0: 부정, 1: 긍정)을 요약한 Stanford Sentiment Treebank (SST) 데이터셋으로 AutoGluon 훈련을 수행합니다." ] }, { "cell_type": "code", "execution_count": 1, "id": "91702aa2", "metadata": {}, "outputs": [], "source": [ "# GPU 인스턴스를 사용하고 CloudFormation으로 실습 환경을 구성하지 않았다면, 아래 주석을 해제하고 본 코드 셀을 실행 후, 노트북을 재시작해 주세요.\n", "# !pip install mxnet-cu110==1.9.1" ] }, { "cell_type": "code", "execution_count": 1, "id": "03d55f77", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "import os\n", "import torch\n", "import mxnet as mx\n", "num_gpus = torch.cuda.device_count()\n", "\n", "if num_gpus == 0:\n", " os.environ['AUTOGLUON_TEXT_TRAIN_WITHOUT_GPU'] = '1'\n", "\n", "print(num_gpus) " ] }, { "cell_type": "code", "execution_count": 2, "id": "e30cdf62", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import warnings\n", "import matplotlib.pyplot as plt\n", "warnings.filterwarnings('ignore')\n", "np.random.seed(123)" ] }, { "cell_type": "markdown", "id": "51f3b0d7", "metadata": {}, "source": [ "
\n", "\n", "## 1. Data preparation and Training" ] }, { "cell_type": "code", "execution_count": 3, "id": "1ee9ba24", "metadata": {}, "outputs": [], "source": [ "save_path = 'ag-01-sentiment-classifcation-eng'\n", "!rm -rf $save_path" ] }, { "cell_type": "markdown", "id": "1753830e", "metadata": {}, "source": [ "샘플 데이터셋을 다운로드합니다. parquet와 csv를 지원하며, 원격에 저장된 데이터셋을 다운로드하거나 로컬에서 데이터셋을 직접 로드할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 4, "id": "f6977aab", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sentencelabel
43787very pleasing at its best moments1
16159, american chai is enough to make you put away...0
59015too much like an infomercial for ram dass 's l...0
5108a stirring visual sequence1
67052cool visual backmasking1
\n", "
" ], "text/plain": [ " sentence label\n", "43787 very pleasing at its best moments 1\n", "16159 , american chai is enough to make you put away... 0\n", "59015 too much like an infomercial for ram dass 's l... 0\n", "5108 a stirring visual sequence 1\n", "67052 cool visual backmasking 1" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from autogluon.core.utils.loaders import load_pd\n", "train_data = load_pd.load('https://autogluon-text.s3-accelerate.amazonaws.com/glue/sst/train.parquet')\n", "test_data = load_pd.load('https://autogluon-text.s3-accelerate.amazonaws.com/glue/sst/dev.parquet')\n", "subsample_size = 1000 # subsample data for faster demo, try setting this to larger values\n", "train_data = train_data.sample(n=subsample_size, random_state=0)\n", "train_data.head(5)" ] }, { "cell_type": "markdown", "id": "717c6304", "metadata": {}, "source": [ "훈련 지정 시 좀 더 세부적인 하이퍼파라메터 설정이 필요하다면, 사전 정의된 preset을 사용하시면 편리합니다. TextPredictor는 사전 훈련된 BERT, RoBERT, ELECTRA가 내장되어 있으며, 한국어를 비롯한 다국어에 대한 훈련이 필요하면 `multi_cased_bert_base_fuse_late` preset을 사용하시면 됩니다." ] }, { "cell_type": "code", "execution_count": 6, "id": "63b9d325", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['default',\n", " 'medium_quality_faster_train',\n", " 'high_quality',\n", " 'best_quality',\n", " 'multilingual']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from autogluon.text import TextPredictor, list_text_presets\n", "list_text_presets()" ] }, { "cell_type": "code", "execution_count": 7, "id": "cb016a9c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': {'model.hf_text.checkpoint_name': 'google/electra-base-discriminator'},\n", " 'medium_quality_faster_train': {'model.hf_text.checkpoint_name': 'google/electra-small-discriminator',\n", " 'optimization.learning_rate': 0.0004},\n", " 'high_quality': {'model.hf_text.checkpoint_name': 'google/electra-base-discriminator'},\n", " 'best_quality': {'model.hf_text.checkpoint_name': 'microsoft/deberta-v3-base',\n", " 'env.per_gpu_batch_size': 2},\n", " 'multilingual': {'model.hf_text.checkpoint_name': 'microsoft/mdeberta-v3-base',\n", " 'optimization.top_k': 1,\n", " 'env.precision': 'bf16',\n", " 'env.per_gpu_batch_size': 4}}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_text_presets(verbose=True)" ] }, { "cell_type": "code", "execution_count": 8, "id": "df8b4896", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Global seed set to 123\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a0c53a0b52ad4829b5d21096c9f9999b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| | 0.00/29.0 [00:00" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "predictor = TextPredictor(label='label', eval_metric='acc', path=save_path)\n", "#predictor.fit(train_data, time_limit=60)\n", "\n", "predictor.fit(\n", " train_data=train_data,\n", " presets=\"medium_quality_faster_train\",\n", " time_limit=60,\n", ")" ] }, { "cell_type": "markdown", "id": "90741a98", "metadata": {}, "source": [ "
\n", "\n", "## 2. Evaluation and Prediction" ] }, { "cell_type": "markdown", "id": "e7cd47e0", "metadata": {}, "source": [ "### Evaluation\n", "`predictor.evaluation()`를 사용하여 평가를 쉽게 수행할 수 있으며, F1 score 등의 추가 metric도 지정 가능합니다." ] }, { "cell_type": "code", "execution_count": 9, "id": "b81a6285", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ae00cc9f714f4384ae20fcaf29f99b19", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Predicting: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "{'acc': 0.801605504587156, 'f1': 0.808839779005525}\n" ] } ], "source": [ "if num_gpus > 0:\n", " test_score = predictor.evaluate(test_data, metrics=['acc', 'f1'])\n", " print(test_score) " ] }, { "cell_type": "markdown", "id": "4a73f665", "metadata": {}, "source": [ "### Prediction\n", "`predictor.predict()`으로 예측을 수행할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 10, "id": "5c551a7c", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "db0cb828639343b5b37471e6f2e8c963", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Predicting: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\"Sentence\": it's a charming and often affecting journey. \"Predicted Sentiment\": 1\n", "\"Sentence\": It's slow, very, very, very slow. \"Predicted Sentiment\": 0\n" ] } ], "source": [ "sentence1 = \"it's a charming and often affecting journey.\"\n", "sentence2 = \"It's slow, very, very, very slow.\"\n", "predictions = predictor.predict({'sentence': [sentence1, sentence2]})\n", "print('\"Sentence\":', sentence1, '\"Predicted Sentiment\":', predictions[0])\n", "print('\"Sentence\":', sentence2, '\"Predicted Sentiment\":', predictions[1])" ] }, { "cell_type": "code", "execution_count": 11, "id": "128c6366", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d858790fe6264688baa1fcbc8548665c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Predicting: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "\"Sentence\": it's a charming and often affecting journey. \"Predicted Class-Probabilities\": 0 0.000639\n", "1 0.869077\n", "Name: 0, dtype: float32\n", "\"Sentence\": It's slow, very, very, very slow. \"Predicted Class-Probabilities\": 0 0.999361\n", "1 0.130923\n", "Name: 1, dtype: float32\n" ] } ], "source": [ "probs = predictor.predict_proba({'sentence': [sentence1, sentence2]})\n", "print('\"Sentence\":', sentence1, '\"Predicted Class-Probabilities\":', probs[0])\n", "print('\"Sentence\":', sentence2, '\"Predicted Class-Probabilities\":', probs[1])" ] }, { "cell_type": "markdown", "id": "6c4ee289", "metadata": {}, "source": [ "전체 데이터셋에 대해 추론을 수행할 수도 있습니다." ] }, { "cell_type": "code", "execution_count": 12, "id": "3881122f", "metadata": {}, "outputs": [], "source": [ "# test_predictions = predictor.predict(test_data)\n", "# test_predictions.head()" ] }, { "cell_type": "markdown", "id": "3aa4fd86", "metadata": {}, "source": [ "### Save and Load\n", "\n", "predictor는 `fit()` 함수로 모델 훈련 시에 자동으로 모델을 저장하며, `load()` 함수를 통해 재로드할 수 있습니다. 물론 `save()` 함수로 모델을 저장하는 것도 가능합니다." ] }, { "cell_type": "code", "execution_count": 13, "id": "243b4b54", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Load pretrained checkpoint: ag-01-sentiment-classifcation-eng/model.ckpt\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9ace43ac80e74d6eb3ed3cf1701c6726", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Predicting: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01
00.0006390.999361
10.8690770.130923
\n", "
" ], "text/plain": [ " 0 1\n", "0 0.000639 0.999361\n", "1 0.869077 0.130923" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "loaded_predictor = TextPredictor.load(save_path)\n", "loaded_predictor.predict_proba({'sentence': [sentence1, sentence2]})" ] }, { "cell_type": "markdown", "id": "d82ce2bf", "metadata": {}, "source": [ "### Extract Embeddings\n", "훈련된 predictor를 사용하여 임베딩 벡터에 매핑하는 임베딩을 추출할 수도 있습니다.\n", "\n", "아래 코드 셀에서 TSNE를 사용하여 추출된 임베딩을 시각화합니다. 두 레이블에 해당하는 두 개의 클러스터가 잘 분포해 있음을 확인할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 14, "id": "1fdd1c13", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c449803eb8514d0ca28886bfa0af3aff", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Predicting: 0it [00:00, ?it/s]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[[-0.9950073 0.19104779 0.30278355 ... -0.15227251 -0.2078394\n", " -0.8929618 ]\n", " [-0.37055644 0.54944015 -0.08293767 ... -0.37117034 -1.52807\n", " -1.0482882 ]\n", " [-0.89614105 0.13071844 0.14226806 ... 0.04598733 -0.5800471\n", " -0.8197252 ]\n", " ...\n", " [-0.48994136 0.35927728 0.02496865 ... 0.6498142 -0.7644585\n", " -0.8643593 ]\n", " [-0.35284802 -0.0030367 0.31872958 ... 0.31603014 -0.7678774\n", " -0.7084229 ]\n", " [-0.64051795 0.5525908 0.25442797 ... 0.22971036 -0.82027364\n", " -0.7009061 ]]\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "if num_gpus > 0:\n", " from sklearn.manifold import TSNE\n", " embeddings = predictor.extract_embedding(test_data)\n", " print(embeddings)\n", " \n", " X_embedded = TSNE(n_components=2, random_state=123).fit_transform(embeddings)\n", " for val, color in [(0, 'red'), (1, 'blue')]:\n", " idx = (test_data['label'].to_numpy() == val).nonzero()\n", " plt.scatter(X_embedded[idx, 0], X_embedded[idx, 1], c=color, label=f'label={val}')\n", " plt.legend(loc='best') " ] }, { "cell_type": "markdown", "id": "cad5d6b5", "metadata": {}, "source": [ "
\n", "\n", "## 3. Continuous Training\n", "\n", "이전에 훈련한 모델을 로드하고 `fit()`을 호출하여, 신규 데이터나 기존 데이터로 계속 훈련할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 15, "id": "e5a7dee0", "metadata": {}, "outputs": [], "source": [ "save_cont_path = 'ag-01-sentiment-classifcation-cont-eng'\n", "!rm -rf $save_cont_path" ] } ], "metadata": { "kernelspec": { "display_name": "conda_pytorch_p38", "language": "python", "name": "conda_pytorch_p38" }, "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" } }, "nbformat": 4, "nbformat_minor": 5 }