{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 03wk-1: 감성분석 파고들기 (1)\n",
"\n",
"최규빈 \n",
"2024-09-19\n",
"\n",
"
\n",
"\n",
"# 1. 강의영상\n",
"\n",
"\n",
"\n",
"# 2. Imports"
],
"id": "cd0dbfcc-193f-417a-86c4-429c22c57fe7"
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/home/cgb3/anaconda3/envs/hf/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm"
]
}
],
"source": [
"import datasets\n",
"import transformers\n",
"import evaluate\n",
"import numpy as np\n",
"import torch # 파이토치"
],
"id": "cell-5"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3. 이전코드\n",
"\n",
"`-` Step1~4를 위한 준비"
],
"id": "8b11556e-899a-43f0-92d9-748ae6ec828d"
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# ## Step1 \n",
"# 데이터불러오기 = datasets.load_dataset\n",
"# 데이터전처리하기1 = 토크나이저 = transformers.AutoTokenizer.from_pretrained(\"distilbert/distilbert-base-uncased\") \n",
"# def 데이터전처리하기2(examples):\n",
"# return 데이터전처리하기1(examples[\"text\"], truncation=True)\n",
"# ## Step2 \n",
"# 인공지능생성하기 = transformers.AutoModelForSequenceClassification.from_pretrained\n",
"# ## Step3 \n",
"# 데이터콜렉터 = transformers.DataCollatorWithPadding(tokenizer=토크나이저)\n",
"# def 평가하기(eval_pred):\n",
"# predictions, labels = eval_pred\n",
"# predictions = np.argmax(predictions, axis=1)\n",
"# accuracy = evaluate.load(\"accuracy\")\n",
"# return accuracy.compute(predictions=predictions, references=labels)\n",
"# 트레이너세부지침생성기 = transformers.TrainingArguments\n",
"# 트레이너생성기 = transformers.Trainer\n",
"# ## Step4 \n",
"# 강인공지능생성하기 = transformers.pipeline"
],
"id": "cell-8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` Step 1~4"
],
"id": "e28f3e04-9870-492f-bdca-5da8ced2fc28"
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# ## Step1 \n",
"# 데이터 = 데이터불러오기('imdb')\n",
"# 전처리된데이터 = 데이터.map(데이터전처리하기2,batched=True)\n",
"# 전처리된훈련자료, 전처리된검증자료 = 전처리된데이터['train'], 전처리된데이터['test']\n",
"# ## Step2 \n",
"# 인공지능 = 인공지능생성하기(\"distilbert/distilbert-base-uncased\", num_labels=2)\n",
"# ## Step3 \n",
"# 트레이너세부지침 = 트레이너세부지침생성기(\n",
"# output_dir=\"my_awesome_model\",\n",
"# learning_rate=2e-5,\n",
"# per_device_train_batch_size=16,\n",
"# per_device_eval_batch_size=16,\n",
"# num_train_epochs=2, # 전체문제세트를 2번 공부하라..\n",
"# weight_decay=0.01,\n",
"# eval_strategy=\"epoch\",\n",
"# save_strategy=\"epoch\",\n",
"# load_best_model_at_end=True,\n",
"# push_to_hub=False,\n",
"# )\n",
"# 트레이너 = 트레이너생성기(\n",
"# model=인공지능,\n",
"# args=트레이너세부지침,\n",
"# train_dataset=전처리된훈련자료,\n",
"# eval_dataset=전처리된검증자료,\n",
"# tokenizer=토크나이저,\n",
"# data_collator=데이터콜렉터,\n",
"# compute_metrics=평가하기,\n",
"# )\n",
"# 트레이너.train()\n",
"# ## Step4 \n",
"# 강인공지능 = 강인공지능생성하기(\"sentiment-analysis\", model=\"my_awesome_model/checkpoint-1563\")\n",
"# print(강인공지능(\"This movie was a huge disappointment.\"))\n",
"# print(강인공지능(\"This was a masterpiece.\"))"
],
"id": "cell-10"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 4. DataSet\n",
"\n",
"`-` 가장 중요한 원초적 질문: 데이터 셋을 바꿔치기 하려면?\n",
"\n",
"`-` 내가 원하는 데이터를 아래와 같은 양식(=형태)으로 정리해야함."
],
"id": "95b5c764-b0ff-44de-832e-6918bb8f1da3"
},
{
"cell_type": "code",
"execution_count": 161,
"metadata": {},
"outputs": [],
"source": [
"데이터 = datasets.load_dataset('imdb')\n",
"데이터"
],
"id": "cell-14"
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"데이터, type(데이터)"
],
"id": "cell-15"
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"데이터['train'], type(데이터['train'])"
],
"id": "cell-16"
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"데이터['train'][0]"
],
"id": "cell-17"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` `datasets.arrow_dataset.Dataset` 의 인스턴스 만들기\n",
"\n",
"아래와 같은 함수가 있음."
],
"id": "d20d50e0-dd6a-449e-9d8e-267f9ce3a0bb"
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"#datasets.Dataset.from_dict?\n",
"#클래스메소드"
],
"id": "cell-20"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **$\\star$ `datasets.Dataset.from_dict` 사용법 (ref: ChatGPT)**\n",
">\n",
"> `datasets.Dataset.from_dict`는 Python의 딕셔너리(`dict`)를 `Dataset`\n",
"> 객체로 변환하는 함수입니다. 주로 딕셔너리 형태의 데이터를 빠르게\n",
"> 데이터셋으로 변환할 때 사용됩니다.\n",
">\n",
"> **간단한 사용법**\n",
">\n",
"> ``` python\n",
"> from datasets import Dataset\n",
">\n",
"> # 딕셔너리를 Dataset으로 변환\n",
"> data_dict = {\n",
"> 'text': [\"Hello world\", \"How are you?\", \"Fine, thanks!\"],\n",
"> 'label': [0, 1, 1]\n",
"> }\n",
">\n",
"> # Dataset 생성\n",
"> dataset = Dataset.from_dict(data_dict)\n",
">\n",
"> # 출력\n",
"> print(dataset)\n",
"> ```\n",
">\n",
"> **주요 매개변수:**\n",
">\n",
"> - `mapping`: 필수, 문자열을 키로 하고 리스트 또는 배열을 값으로 하는\n",
"> 딕셔너리.\n",
"> - `features`: 선택, 데이터셋의 각 필드 타입을 정의.\n",
"> - `info`: 선택, 데이터셋에 대한 추가 정보(설명, 인용 등).\n",
"> - `split`: 선택, 데이터셋의 나누기(‘train’, ‘test’ 등).\n",
">\n",
"> **반환값:**\n",
">\n",
"> - `Dataset`: PyArrow 기반의 데이터셋 객체."
],
"id": "c1f7642a-17a9-49eb-bce4-ef87f16009cd"
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"train_dict = {\n",
" 'text': [\n",
" \"I prefer making decisions based on logic and objective facts.\",\n",
" \"I always consider how others might feel when making a decision.\",\n",
" \"Data and analysis drive most of my decisions.\",\n",
" \"I rely on my empathy and personal values to guide my choices.\"\n",
" ],\n",
" 'label': [0, 1, 0, 1] # 0은 T(사고형), 1은 F(감정형)\n",
"}\n",
"\n",
"test_dict = {\n",
" 'text': [\n",
" \"I find it important to weigh all the pros and cons logically.\",\n",
" \"When making decisions, I prioritize harmony and people's emotions.\"\n",
" ],\n",
" 'label': [0, 1] # 0은 T(사고형), 1은 F(감정형)\n",
"}"
],
"id": "cell-22"
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"train_data = datasets.Dataset.from_dict(train_dict)\n",
"test_data = datasets.Dataset.from_dict(test_dict)"
],
"id": "cell-23"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` `datasets.dataset_dict.DatasetDict`의 인스턴스 만들기"
],
"id": "2b6a0300-714b-4f18-b16e-bcace20b3012"
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"나의데이터 = datasets.dataset_dict.DatasetDict({'train':train_data, 'test':test_data})"
],
"id": "cell-25"
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"나의데이터['train'][0]"
],
"id": "cell-26"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 일단 아래와 같은 형태로 분석할 데이터를 저장할 수 있다면, 나머지\n",
"분석은 코드를 복/붙하여 진행할 수 있음.\n",
"\n",
"``` python\n",
"train_dict = {\n",
" 'text': [\n",
" \"I prefer making decisions based on logic and objective facts.\",\n",
" \"I always consider how others might feel when making a decision.\",\n",
" \"Data and analysis drive most of my decisions.\",\n",
" \"I rely on my empathy and personal values to guide my choices.\"\n",
" ],\n",
" 'label': [0, 1, 0, 1] # 0은 T(사고형), 1은 F(감정형)\n",
"}\n",
"\n",
"test_dict = {\n",
" 'text': [\n",
" \"I find it important to weigh all the pros and cons logically.\",\n",
" \"When making decisions, I prioritize harmony and people's emotions.\"\n",
" ],\n",
" 'label': [0, 1] # 0은 T(사고형), 1은 F(감정형)\n",
"}\n",
"```\n",
"\n",
"# 5. 토크나이저\n",
"\n",
"`-` 토크나이저를 불러오는 코드"
],
"id": "ae071403-a016-43d7-ad75-f4d8196eb8ea"
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/home/cgb3/anaconda3/envs/hf/lib/python3.12/site-packages/transformers/tokenization_utils_base.py:1601: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be depracted in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n",
" warnings.warn("
]
}
],
"source": [
"토크나이저 = 데이터전처리하기1 = transformers.AutoTokenizer.from_pretrained(\"distilbert/distilbert-base-uncased\")"
],
"id": "cell-30"
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"#토크나이저?"
],
"id": "cell-31"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **$\\star$ `토크나이저` 사용법 (ref: ChatGPT)**\n",
">\n",
"> **주요 파라미터**:\n",
">\n",
"> 1. **text**:\n",
"> - `Union[str, List[str], List[List[str]]]`\n",
"> - 주어진 텍스트를 토큰화합니다. 이 텍스트는 문자열일 수도 있고,\n",
"> 문자열의 리스트 또는 리스트 안의 리스트일 수도 있습니다.\n",
"> 2. **text_pair**:\n",
"> - `Union[str, List[str], List[List[str]], NoneType]`\n",
"> - 두 개의 텍스트를 함께 모델에 입력할 때 사용됩니다. 예를 들어,\n",
"> 질문-답변 쌍 같은 경우 이 두 번째 텍스트를 넣습니다.\n",
"> 3. **text_target**:\n",
"> - `Union[str, List[str], List[List[str]]]`\n",
"> - 토큰화를 할 때 목표(target) 텍스트에 해당하는 부분입니다. 주로\n",
"> 시퀀스 생성 모델에서 활용됩니다.\n",
"> 4. **text_pair_target**:\n",
"> - `Union[str, List[str], List[List[str]], NoneType]`\n",
"> - 위의 `text_pair`와 유사하게 목표(target) 텍스트의 두 번째\n",
"> 텍스트를 나타냅니다.\n",
"> 5. **add_special_tokens**:\n",
"> - `bool`\n",
"> - 문장의 시작, 끝, 구분자 같은 특별한 토큰을 추가할지 여부를\n",
"> 결정합니다. 기본값은 `True`입니다.\n",
"> 6. **padding**:\n",
"> - `Union[bool, str, transformers.utils.generic.PaddingStrategy]`\n",
"> - 문장 길이가 다를 때 패딩을 넣어 문장의 길이를 동일하게\n",
"> 맞춥니다. 패딩 전략에는 `True`, `False`, `'longest'`,\n",
"> `'max_length'` 등이 있습니다.\n",
"> 7. **truncation**:\n",
"> - `Union[bool, str, transformers.tokenization_utils_base.TruncationStrategy]`\n",
"> - 문장이 너무 길 경우 지정된 최대 길이에 맞춰 잘라내는\n",
"> 옵션입니다. 전략에는 `True`, `False`, `'longest_first'`,\n",
"> `'only_first'`, `'only_second'` 등이 있습니다.\n",
"> 8. **max_length**:\n",
"> - `Optional[int]`\n",
"> - 문장의 최대 길이를 설정합니다. `None`일 경우 기본 설정을\n",
"> 따릅니다.\n",
"> 9. **stride**:\n",
"> - `int`\n",
"> - 텍스트를 자를 때 중첩을 만들기 위한 옵션입니다. 즉, 자른\n",
"> 부분과 다음 부분 사이의 겹치는 범위를 설정합니다.\n",
"> 10. **is_split_into_words**:\n",
"> - `bool`\n",
"> - 텍스트가 이미 단어 단위로 분리되어 있는지 여부를 나타냅니다.\n",
"> 기본적으로는 `False`로, 텍스트가 단어 단위로 분리되지 않았다고\n",
"> 가정합니다.\n",
"> 11. **return_tensors**:\n",
"> - `Union[str, transformers.utils.generic.TensorType, NoneType]`\n",
"> - 출력 형식으로 텐서를 반환할지 여부를 설정합니다.\n",
"> `'pt'`(PyTorch), `'tf'`(TensorFlow), `'np'`(NumPy) 등을 지정할\n",
"> 수 있습니다.\n",
"> 12. **return_token_type_ids**:\n",
"> - `Optional[bool]`\n",
"> - 토큰 타입 ID를 반환할지 여부를 설정합니다. 주로 두 개의 문장을\n",
"> 함께 처리할 때 문장을 구분하기 위해 사용됩니다.\n",
"> 13. **return_attention_mask**:\n",
"> - `Optional[bool]`\n",
"> - `attention_mask`를 반환할지 여부를 설정합니다. 패딩된 토큰이\n",
"> 모델의 어텐션에 영향을 주지 않도록 마스크를 설정합니다.\n",
"> 14. **return_overflowing_tokens**:\n",
"> - `bool`\n",
"> - 텍스트가 최대 길이를 초과하는 경우, 잘린 토큰을 반환할지\n",
"> 여부를 결정합니다.\n",
"> 15. **return_special_tokens_mask**:\n",
"> - `bool`\n",
"> - 특별한 토큰에 대한 마스크를 반환할지 여부를 설정합니다.\n",
"> 16. **return_offsets_mapping**:\n",
"> - `bool`\n",
"> - 텍스트의 각 토큰이 원본 텍스트에서 어느 위치에 있는지 나타내는\n",
"> 오프셋 맵핑을 반환할지 여부를 설정합니다.\n",
"> 17. **return_length**:\n",
"> - `bool`\n",
"> - 토큰화된 문장의 길이를 반환할지 여부를 설정합니다.\n",
"> 18. **verbose**:\n",
"> - `bool`\n",
"> - 디버깅 메시지를 출력할지 여부를 설정합니다. 기본값은 `True`로\n",
"> 설정되어 있습니다.\n",
">\n",
"> **사용 예시**:\n",
">\n",
"> ``` python\n",
"> from transformers import AutoTokenizer\n",
">\n",
"> # 토크나이저 불러오기\n",
"> tokenizer = AutoTokenizer.from_pretrained(\"bert-base-uncased\")\n",
">\n",
"> # 텍스트 토큰화\n",
"> encoding = tokenizer(\n",
"> text=\"Hello, how are you?\",\n",
"> padding=True,\n",
"> truncation=True,\n",
"> max_length=10,\n",
"> return_tensors='pt'\n",
"> )\n",
">\n",
"> print(encoding)\n",
"> ```\n",
">\n",
"> 이 코드에서는 “Hello, how are you?”라는 텍스트를 `bert-base-uncased`\n",
"> 토크나이저로 토큰화하고, 패딩과 트렁케이션을 적용하며, PyTorch 텐서\n",
"> 형식으로 반환하도록 설정했습니다.\n",
">\n",
"> 이러한 파라미터는 주로 자연어 처리(NLP) 모델을 훈련하거나 추론할 때\n",
"> 데이터 전처리 과정에서 많이 사용됩니다.\n",
"\n",
"`-` 기본사용1: 토크나이저의 기능 – (1) 단어별로 다른숫자를 맵핑 (2)\n",
"처음과 끝은 각각 `101`, `102`라는 숫자로 맵핑"
],
"id": "6797c75a-c334-4c1c-a36e-6ade40c3fa93"
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"토크나이저('hi hello')"
],
"id": "cell-34"
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"토크나이저('hi hi hello')"
],
"id": "cell-35"
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"토크나이저('hi hi hello hello hello hi')"
],
"id": "cell-36"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 기본사용2: 여러개의 텍스트도 `[텍스트1, 텍스트2, ... ]` 꼴로\n",
"전달하면 토크나이저가 알아서 잘 처리해준다."
],
"id": "6be702a3-469b-4993-9a06-c2d394cd07de"
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"토크나이저(['hi hello', 'hello hello hello', 'hi hi'])"
],
"id": "cell-38"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` `truncation=True` 의 역할 – 너무 문장이 길면 잘라내는 역할을 한다."
],
"id": "ca95d4e9-90b8-4653-b82c-677924429506"
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"토크나이저('hi hello '*2)"
],
"id": "cell-40"
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"len(토크나이저('hi hello '*2)['input_ids']), len(토크나이저('hi hello '*2)['attention_mask'])"
],
"id": "cell-41"
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"len(토크나이저('hi hello '*300,truncation=True)['input_ids']) # 원래는 602가 나와야하는데 짤려서 512만 나옴"
],
"id": "cell-42"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 너무 문장이 짧아서 뭔가를 채우기도 할까? – `max_length`, `padding`,\n",
"`attention_mask`"
],
"id": "48fb374e-6f06-4ccc-ac2b-880fc755f1bd"
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"토크나이저('hi hello', max_length = 10, padding=\"max_length\" )"
],
"id": "cell-44"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 6. 인공지능 ($\\star$)\n",
"\n",
"## A. 1단계\n",
"\n",
"> 인공지능에 대한 이해\n",
"\n",
"`-` 인공지능 불러오기"
],
"id": "c59bd936-7614-43f0-bb05-9a3bd36aeb39"
},
{
"cell_type": "code",
"execution_count": 141,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Some weights of DistilBertForSequenceClassification were not initialized from the model checkpoint at distilbert/distilbert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight', 'pre_classifier.bias', 'pre_classifier.weight']\n",
"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference."
]
}
],
"source": [
"torch.manual_seed(43052)\n",
"인공지능 = model = transformers.AutoModelForSequenceClassification.from_pretrained(\n",
" \"distilbert/distilbert-base-uncased\", num_labels=2\n",
")"
],
"id": "cell-49"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 인공지능의 정체? 엄청나게 많은 숫자들이 포함된 어떠한 물체 (엄청나게\n",
"많은 파라메터들이 포함된 네트워크)"
],
"id": "21395eef-babd-46fe-b45c-34dfc9bc9835"
},
{
"cell_type": "code",
"execution_count": 134,
"metadata": {},
"outputs": [],
"source": [
"인공지능"
],
"id": "cell-51"
},
{
"cell_type": "code",
"execution_count": 135,
"metadata": {},
"outputs": [],
"source": [
"인공지능.classifier.weight"
],
"id": "cell-52"
},
{
"cell_type": "code",
"execution_count": 136,
"metadata": {},
"outputs": [],
"source": [
"인공지능.pre_classifier.weight"
],
"id": "cell-53"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 인공지능? “입력정보 -\\> 정리된숫자 -\\> 계산 -\\> 계산된숫자 -\\>\n",
"출력정보” 의 과정에서 “계산”을 담당.\n",
"\n",
"- 인공지능이 가지고 있는 숫자들은 “계산”에 사용된다.\n",
"\n",
"`-` 입력정보에 영화에 대한 부정적 평가에 해당하는 텍스트를 넣는다면?"
],
"id": "5a5e71f5-6451-438f-a4fd-fa32bb662f95"
},
{
"cell_type": "code",
"execution_count": 137,
"metadata": {},
"outputs": [],
"source": [
"입력정보_원시텍스트 = \"This movie was a huge disappointment.\"\n",
"정리된숫자_토큰화된자료 = 토크나이저(입력정보_원시텍스트,return_tensors='pt')\n",
"정리된숫자_토큰화된자료"
],
"id": "cell-56"
},
{
"cell_type": "code",
"execution_count": 138,
"metadata": {},
"outputs": [],
"source": [
"인공지능(**정리된숫자_토큰화된자료)"
],
"id": "cell-57"
},
{
"cell_type": "code",
"execution_count": 139,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자_로짓 = 인공지능(**정리된숫자_토큰화된자료).logits.detach().numpy()\n",
"계산된숫자_로짓"
],
"id": "cell-58"
},
{
"cell_type": "code",
"execution_count": 140,
"metadata": {},
"outputs": [],
"source": [
"출력정보_확률 = np.exp(계산된숫자_로짓)/np.exp(계산된숫자_로짓).sum() # 0일확률(=부정평가일확률), 1일확률(=긍정평가일확률)\n",
"출력정보_확률"
],
"id": "cell-59"
},
{
"cell_type": "code",
"execution_count": 145,
"metadata": {},
"outputs": [],
"source": [
"출력정보_확률.argmax() # 부정적 영화평가에 대한 인공지능의 예측 "
],
"id": "cell-60"
},
{
"cell_type": "code",
"execution_count": 147,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자_로짓.argmax() # 부정적 영화평가에 대한 인공지능의 예측 <-- 이렇게 구해도 됩니다.. 왜??"
],
"id": "cell-61"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 입력정보에 영화에 대한 긍정적 평가에 해당하는 텍스트를 넣는다면?"
],
"id": "a2e9f4ff-110f-46fa-aa5e-3b713a9f9be6"
},
{
"cell_type": "code",
"execution_count": 148,
"metadata": {},
"outputs": [],
"source": [
"입력정보_원시텍스트 = \"This was a masterpiece.\"\n",
"정리된숫자_토큰화된자료 = 토크나이저(입력정보_원시텍스트,return_tensors='pt')\n",
"정리된숫자_토큰화된자료"
],
"id": "cell-63"
},
{
"cell_type": "code",
"execution_count": 149,
"metadata": {},
"outputs": [],
"source": [
"인공지능(**정리된숫자_토큰화된자료)"
],
"id": "cell-64"
},
{
"cell_type": "code",
"execution_count": 150,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자_로짓 = 인공지능(**정리된숫자_토큰화된자료).logits.detach().numpy()\n",
"계산된숫자_로짓"
],
"id": "cell-65"
},
{
"cell_type": "code",
"execution_count": 151,
"metadata": {},
"outputs": [],
"source": [
"출력정보_확률 = np.exp(계산된숫자_로짓)/np.exp(계산된숫자_로짓).sum() # 0일확률(=부정평가일확률), 1일확률(=긍정평가일확률)\n",
"출력정보_확률"
],
"id": "cell-66"
},
{
"cell_type": "code",
"execution_count": 152,
"metadata": {},
"outputs": [],
"source": [
"출력정보_확률.argmax() # 긍정적 영화평가에 대한 인공지능의 예측 "
],
"id": "cell-67"
},
{
"cell_type": "code",
"execution_count": 154,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자_로짓.argmax() # 긍정적 영화평가에 대한 인공지능의 예측"
],
"id": "cell-68"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 아무숫자나 뱉어내는 듯 $\\to$ 멍청한 인공지능 (옹호: 멍청한건 당연함.\n",
"아직 학습전이니까)\n",
"\n",
"`-` 인공지능에 대한 이해1: 인공지능은 “정리된숫자”를 입력으로 하고\n",
"일련의 계산을 거쳐서 “계산된숫자”를 출력해주는 함수라 생각할 수 있음.\n",
"\n",
"`-` 인공지능에 대한 이해2: 인공지능은 (1) 많은숫자들과 (2) 고유의\n",
"계산방식을 가지고 있음.\n",
"\n",
"- 인공지능이 내부에 자체적으로 저장하고 있는 숫자들 “파라메터”라고\n",
" 부름.\n",
"- 인공지능은 나름의 법칙에 따라 “데이터”와 “파라메터”의 숫자들을\n",
" 연산함. 즉 인공지능은 자체적으로 데이터와 파라메터를 어떻게 계산할지\n",
" 알고있는데, 이러한 고유의 계산방식을 “아키텍처”라고 말함.\n",
"\n",
"`-` 인공지능에 대한 이해3: 두개의 인공지능이 서로 다른 고유의 계산방식을\n",
"가지고 있다면 두 인공지능은 “다른 모델” 임.\n",
"\n",
"`-` 인공지능에 대한 이해3’: 동일한 생성방식으로 만들어진 인공지능들은\n",
"모두 같은 모델임. 예를들면 아래의 인공지능1,2는 같은 모델임\n",
"\n",
"``` python\n",
"인공지능1 = transformers.AutoModelForSequenceClassification.from_pretrained(\n",
" \"distilbert/distilbert-base-uncased\", num_labels=2\n",
")\n",
"인공지능2 = transformers.AutoModelForSequenceClassification.from_pretrained(\n",
" \"distilbert/distilbert-base-uncased\", num_labels=2\n",
")\n",
"```\n",
"\n",
"`-` 인공지능에 대한 이해4: 두 인공지능이 같은모델이라고 해도, 항상 같은\n",
"결과를 주는건 아님. 파라메터에 따라 다른 결과를 줄 수도 있음. (예를들면\n",
"위의 인공지능1,2는 같은 모델이지만 다른 파라메터를 가지므로 다른 결과를\n",
"줌)\n",
"\n",
"## B. 2단계\n",
"\n",
"> 미니배치의 이해\n",
"\n",
"`-` 예비학습"
],
"id": "9b150d02-51b2-4db9-9e7d-01d46e7004e8"
},
{
"cell_type": "code",
"execution_count": 156,
"metadata": {},
"outputs": [],
"source": [
"arr = np.array([[1,2],[2,3],[3,4]])\n",
"arr"
],
"id": "cell-78"
},
{
"cell_type": "code",
"execution_count": 159,
"metadata": {},
"outputs": [],
"source": [
"arr / arr.sum(axis=1).reshape(-1,1)"
],
"id": "cell-79"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 예비개념1: 인공지능은 사실 영화평을 하나씩 하나씩 처리하지 않는다.\n",
"덩어리로 처리한다.\n",
"\n",
"`-` 예비개념2: 그렇다고 해서 인공지능이 25000개를 모두 덩어리로\n",
"처리하는건 아니다 $\\to$ 16개씩 혹은 32개씩 묶어서 작은덩어리를 만든 후\n",
"처리한다.\n",
"\n",
"- 16, 32와 같은 숫자를 `batch_size` 라고 한다.\n",
"- 16개, 32개로 모인 작은덩어리를 미니배치라고 한다.\n",
"\n",
"`-` 16개의 입력정보를 한번에 처리"
],
"id": "2fc748b6-070c-4452-8ffb-287a47bb8552"
},
{
"cell_type": "code",
"execution_count": 175,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:16]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓) / np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"출력정보들_확률"
],
"id": "cell-83"
},
{
"cell_type": "code",
"execution_count": 177,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자들_로짓.argmax(axis=1) # 인공지능의 예측"
],
"id": "cell-84"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 기억할 것: `정리된숫자들_토큰화된자료` 는 모두 길이가 512임. (그렇게\n",
"되도록 패딩함)"
],
"id": "345c105b-8e25-4e6f-ad35-ff6b87346cce"
},
{
"cell_type": "code",
"execution_count": 182,
"metadata": {},
"outputs": [],
"source": [
"정리된숫자들_토큰화된자료['input_ids'].shape, 정리된숫자들_토큰화된자료['attention_mask'].shape"
],
"id": "cell-86"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 실제 단어수"
],
"id": "d1a17b82-d649-478f-91ee-7e5b00aa9710"
},
{
"cell_type": "code",
"execution_count": 190,
"metadata": {},
"outputs": [],
"source": [
"정리된숫자들_토큰화된자료['attention_mask'].sum(axis=1)"
],
"id": "cell-88"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 패딩된단어수"
],
"id": "94f06a61-d8e6-4343-813a-c64391b24407"
},
{
"cell_type": "code",
"execution_count": 191,
"metadata": {},
"outputs": [],
"source": [
"512-정리된숫자들_토큰화된자료['attention_mask'].sum(axis=1)"
],
"id": "cell-90"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 이러한 변환이 필요한 이유? 인공지능은 항상 `(n,m)` 차원으로 정리된\n",
"숫자들만 입력으로 받을 수 있음.\n",
"\n",
"- 왜? 사실 인공지능은 행렬계산을 하도록 설계되어있음.\n",
"- 그래서 할수없이 padding을 하거나 truncation을 하는 것임. (실제로는\n",
" 행렬이 아니지만 억지로 행렬을 만들기 위해서)\n",
"\n",
"## C. 3단계\n",
"\n",
"> 동적패딩을 이해하자.\n",
"\n",
"`-` 만약에 `batch_size=4`로 설정하여 처리한다면?"
],
"id": "fde55c3a-9154-4263-a236-7cfb55a45815"
},
{
"cell_type": "code",
"execution_count": 202,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:4]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓) / np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"출력정보들_확률"
],
"id": "cell-95"
},
{
"cell_type": "code",
"execution_count": 203,
"metadata": {},
"outputs": [],
"source": [
"계산된숫자들_로짓.argmax(axis=1) # 인공지능의 예측 "
],
"id": "cell-96"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` `정리된숫자들_토큰화된자료['input_ids']` 의 차원은 어떠할까? (4,512)"
],
"id": "fb12a1e1-b32b-4dac-8e75-3769c5a8f969"
},
{
"cell_type": "code",
"execution_count": 204,
"metadata": {},
"outputs": [],
"source": [
"정리된숫자들_토큰화된자료['input_ids'].shape, 정리된숫자들_토큰화된자료['attention_mask'].shape"
],
"id": "cell-98"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 끝의 차원이 512가 아니라 363이다.. 왜??\n",
"\n",
"`-` 덩어리의 상태에 따라서 유동적으로 패딩 $\\to$ 이렇게 해도 잘 돌아감"
],
"id": "2454a5fa-cfdc-436d-bfaa-30e14d4a5063"
},
{
"cell_type": "code",
"execution_count": 209,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:4]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-101"
},
{
"cell_type": "code",
"execution_count": 210,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][4:8]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-102"
},
{
"cell_type": "code",
"execution_count": 211,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][8:12]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-103"
},
{
"cell_type": "code",
"execution_count": 212,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][12:16]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-104"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 싹다 maxlen=512로 가정하고 패딩해서 돌린결과와 비교 $\\to$ 같음 $\\to$\n",
"동적패딩이 효율적"
],
"id": "1bf5633d-9adc-4c75-9ff9-5da03e0cb352"
},
{
"cell_type": "code",
"execution_count": 213,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:16]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-106"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## D. 4단계\n",
"\n",
"> 손실(=loss)의 개념을 이해하자\n",
"\n",
"`-` `정리된숫자들_토큰화된자료`에서 `labels`를 추가 전달하면,\n",
"`인공지능(**정리된숫자들_토큰화된자료)`의 결과로 `loss`가 추가계산됨."
],
"id": "859f7d81-7a95-4f6e-8fdd-61ee96c2f294"
},
{
"cell_type": "code",
"execution_count": 222,
"metadata": {},
"outputs": [],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:4]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"#데이터['train'][:4]['label'] # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor([0,0,0,0]) # 정답입력\n",
"인공지능(**정리된숫자들_토큰화된자료)"
],
"id": "cell-110"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 정리를 해보자."
],
"id": "53915e20-326e-4406-92ed-b8db63bde9e5"
},
{
"cell_type": "code",
"execution_count": 240,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"실제정답: [0, 0, 0, 0]\n",
"인공지능의예측: [1 1 1 1]\n",
"인공지능의확신정도: [0.5217618 0.5278467 0.5195052 0.5339033]\n",
"손실(loss): 0.746100"
]
}
],
"source": [
"입력정보들_원시텍스트 = 데이터['train'][:4]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][:4]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor([0,0,0,0]) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-112"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` loss는 작을수록 주어진 데이터에 대한 정답을 잘 맞추고 있다고 볼 수\n",
"있음. (그렇지만 학습이 잘 되었다는걸 보장하지는 못함)\n",
"\n",
"**텍스트0-텍스트3**"
],
"id": "a1c739c3-f599-45bd-8eaa-0f3aa6b2658b"
},
{
"cell_type": "code",
"execution_count": 244,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"텍스트0 -- 텍스트3\n",
"실제정답: [0, 0, 0, 0]\n",
"인공지능의예측: [1 1 1 1]\n",
"인공지능의확신정도: [0.5217618 0.5278467 0.5195052 0.5339033]\n",
"손실(loss): 0.746100"
]
}
],
"source": [
"print(\"텍스트0 -- 텍스트3\")\n",
"입력정보들_원시텍스트 = 데이터['train'][:4]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][:4]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor(데이터['train'][:4]['label']) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-115"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**텍스트12498-텍스트12501**"
],
"id": "ee306fc9-a8b3-48d6-8dab-17f890211e32"
},
{
"cell_type": "code",
"execution_count": 247,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"텍스트12498 -- 텍스트12501\n",
"실제정답: [0, 0, 1, 1]\n",
"인공지능의예측: [1 1 1 1]\n",
"인공지능의확신정도: [0.52731967 0.5243837 0.51578873 0.5351162 ]\n",
"손실(loss): 0.694952"
]
}
],
"source": [
"print(\"텍스트12498 -- 텍스트12501\")\n",
"입력정보들_원시텍스트 = 데이터['train'][12498:12502]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][12498:12502]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor(데이터['train'][12498:12502]['label']) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-117"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**텍스트12502-텍스트12506**"
],
"id": "565c3c34-dc96-45d7-8720-2a64904b5d09"
},
{
"cell_type": "code",
"execution_count": 248,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"텍스트12502 -- 텍스트12506\n",
"실제정답: [1, 1, 1, 1]\n",
"인공지능의예측: [1 1 1 1]\n",
"인공지능의확신정도: [0.52180934 0.51908445 0.521884 0.5197189 ]\n",
"손실(loss): 0.652730"
]
}
],
"source": [
"print(\"텍스트12502 -- 텍스트12506\")\n",
"입력정보들_원시텍스트 = 데이터['train'][12502:12506]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][12502:12506]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor(데이터['train'][12502:12506]['label']) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-119"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`-` 똑같이 틀려도 오답에 대한 확신이 강할수록 loss가 크다."
],
"id": "2014457c-778f-40a6-b069-d7324a9fcb99"
},
{
"cell_type": "code",
"execution_count": 250,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"텍스트0 -- 텍스트1\n",
"실제정답: [0, 0]\n",
"인공지능의예측: [1 1]\n",
"인공지능의확신정도: [0.5217617 0.5278467]\n",
"손실(loss): 0.744049"
]
}
],
"source": [
"print(\"텍스트0 -- 텍스트1\")\n",
"입력정보들_원시텍스트 = 데이터['train'][:2]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][:2]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor(데이터['train'][:2]['label']) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-121"
},
{
"cell_type": "code",
"execution_count": 251,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"텍스트1 -- 텍스트2\n",
"실제정답: [0, 0]\n",
"인공지능의예측: [1 1]\n",
"인공지능의확신정도: [0.5278467 0.5195052]\n",
"손실(loss): 0.741695"
]
}
],
"source": [
"print(\"텍스트1 -- 텍스트2\")\n",
"입력정보들_원시텍스트 = 데이터['train'][1:3]['text']\n",
"정리된숫자들_토큰화된자료 = 토크나이저(입력정보들_원시텍스트,truncation=True,return_tensors='pt',padding=True)\n",
"print(f'실제정답: {데이터['train'][1:3]['label']}') # 정답확인\n",
"정리된숫자들_토큰화된자료['labels'] = torch.tensor(데이터['train'][1:3]['label']) # 정답입력\n",
"계산된숫자들_로짓 = 인공지능(**정리된숫자들_토큰화된자료).logits.detach().numpy()\n",
"출력정보들_확률 = np.exp(계산된숫자들_로짓)/np.exp(계산된숫자들_로짓).sum(axis=1).reshape(-1,1)\n",
"print(f'인공지능의예측: {계산된숫자들_로짓.argmax(axis=1)}')\n",
"print(f'인공지능의확신정도: {출력정보들_확률.max(axis=1)}')\n",
"print(f'손실(loss): {인공지능(**정리된숫자들_토큰화된자료).loss.item():.6f}')"
],
"id": "cell-122"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **$\\star\\star\\star$ 학습이 가능한 이유 (대충 아이디어만)**\n",
">\n",
"> `1`. 랜덤으로 하나의 인공지능을 생성한다. (아래의 코드로 가능)\n",
">\n",
"> ``` python\n",
"> 인공지능 = 인공지능생성기()\n",
"> ```\n",
">\n",
"> `2`. 하나의 미니배치를 선택한다.\n",
">\n",
"> `3`. 인공지능의 파라메터중 하나의 숫자를 선택한다. 예를들면 아래와\n",
"> 같은 상황이 있다고 하자.\n",
">\n",
"> ``` python\n",
"> 인공지능.classifier.weight\n",
"> ```\n",
">\n",
"> Parameter containing:\n",
"> tensor([[-0.0234, 0.0279, 0.0242, ..., 0.0091, -0.0063, -0.0133],\n",
"> [ 0.0087, 0.0007, -0.0099, ..., 0.0183, -0.0007, 0.0295]],\n",
"> requires_grad=True)\n",
">\n",
"> 하나의 숫자 `-0.0234`를 선택한다.\n",
">\n",
"> `4`. `-0.0234`의 값을 아주 조금 변화시킨다. 예를들면 `-0.0233`,\n",
"> `-0.0235` 와 같은 숫자로 바꾼다. 2에서 고정된 미니배치에 대하여\n",
"> `-0.0234`, `-0.0233`, `-0.0235` 에 대한 loss를 계산해보고 비교한다.\n",
">\n",
"> - `-0.0234`이 최저 loss라면? 값을 안바꾸는게 좋겠음.\n",
"> - `-0.0233`이 최저 loss라면?? 값을 `-0.0233`으로 바꿈.\n",
"> - `-0.0235`이 최저 loss라면?? 값을 `-0.0235`으로 바꿈.\n",
">\n",
"> `5`. 다음은 다른 모든 파라메터에 대하여 3-4을 반복한다. (과정을\n",
"> 반복할수록 loss는 작아지겠죠, 즉 인공지능은 정답을 잘 맞추겠죠)\n",
">\n",
"> `6`. 다른 미니배치에 대하여 2-5를 반복한다.\n",
"\n",
"`-` 인공지능의 학습은 마법같은 신비한 현상이 아니고, 극한의 노가다를\n",
"통해 얻어지는 산물일 뿐이다."
],
"id": "b0e2fc5f-61c3-447e-b013-5a41591e18d2"
}
],
"nbformat": 4,
"nbformat_minor": 5,
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3 (ipykernel)",
"language": "python"
},
"language_info": {
"name": "python",
"codemirror_mode": {
"name": "ipython",
"version": "3"
},
"file_extension": ".py",
"mimetype": "text/x-python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
}
}
}