├── README.md
├── codes
├── 10_huggingface_example.ipynb
├── 3-2_generating_BERT_embedding.ipynb
├── 3-3_extracting_embeddings_from_all_encoder_layers_of_BERT.ipynb
└── 9-3_BERT라이브러리탐색.ipynb
├── images
├── chap1_1.png
├── chap1_2.png
├── chap5_1.png
├── chap8_probability-of-readmission1.png
├── chap8_probability-of-readmission2.png
├── chap9_multi-modal-transformer.png
├── chap9_table1.png
├── chap9_videobert.png
├── chapter9_BART_architecture.PNG
├── chapter9_BART_comparison.PNG
├── chapter9_BART_fine-tuning.PNG
└── chapter9_BART_noising.PNG
├── order.ipynb
└── summaries
├── chapter01
└── chapter01_eunsik.md
├── chapter02
├── chapter02_BPE.md
└── understanding_BERT_01.md
├── chapter03
├── chapter03_embedding-extraction.md
└── chapter03_finetuning.md
├── chapter04
├── Chapter04_ALBERT_suyeon.pdf
├── Chapter04_ELECTRA.pdf
├── chapter04_SpanBERT.md
└── chapter04_roberta.md
├── chapter05
├── chapter05_DistilBERT.pdf
└── chapter05_TinyBERT.md
├── chapter06
├── chapter06_텍스트_요약을_위한_BERTSUM_탐색_(1).md
└── chapter6_BERTSUM(2)_0hee0.md
├── chapter07
├── chapter07_M-BERT.md
└── chapter07_XLMR_multilingual.md
├── chapter08
├── S-BERT.md
└── chapter08_domain-BERT.md
├── chapter09
├── chapter09_BART.md
└── chapter09_VideoBERT.md
└── chapter10
└── chapter10_kobert_kogpt2_kobart.md
/README.md:
--------------------------------------------------------------------------------
1 | # 구글 BERT의 정석 스터디
2 | ## Outline
3 | - 원서 제목: Getting Started with Google BERT: Build and train state-of-the-art natural language processing models using BERT
4 | - [도서 링크](https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=281761569)
5 | - 목표
6 | - 구글 BERT의 정석 완독
7 | - 챕터 별 연습문제에 어느 정도 스스로 답할 수 있을 정도의 이해
8 | - BERT 기반의 다른 NLP 논문을 읽을 수 있을 정도의 이해
9 | - 방식:
10 | - 주 1회 1챕터를 2명씩 돌아가면서 발제
11 | - 논문을 참고할 수 있는 챕터는 논문 참고
12 | - 발제하지 않는 스터디원들은 해당 분량을 완독
13 | - Chapter 별로 issue 발행하여 궁금하거나 어려운 부분 스터디일에 공유 및 토의
14 | - 기간: 2022.01.12 ~ 2022.03.23(11주)
15 | - 스터디 일시: 매주 수요일 21:00 ~ 22:00(25+25분 발표 + 10분 토의) (스터디원들과의 협의 하에 사전 조정 가능)
16 | - [Google Meet Link](https://meet.google.com/krj-wqrd-feo)
17 |
18 | ## Presentation Order
19 | 스터디 시작일(220112)을 random seed로 하여 발표 순서를 랜덤으로 배정하였습니다. [Code](./order.ipynb)
20 |
21 | |Chapter| 발제자 |
22 | |-----|----------------|
23 | |1. 트랜스포머 입문| **이은식(fixed)** |
24 | |2. BERT 이해하기| **남수연, 박상일** |
25 | |3. BERT 활용하기| **서희, 이은식** |
26 | |4-1. BERT의 파생모델 1 ALBERT, RoBERTa| **이은식, 남수연** |
27 | |4-2. BERT의 파생모델 1 ELECTRA, SpanBERT| **박상일, 서희** |
28 | |5. BERT의 파생모델 2 지식 증류 기반| **박상일, 이은식** |
29 | |6. 텍스트 요약을 위한 BERTSUM 탐색| **서희, 남수연** |
30 | |7. 다른 언어에 BERT 적용하기| **이은식, 박상일** |
31 | |8. sentence-BERT 및 domain-BERT 살펴보기| **남수연, 서희** |
32 | |9. VideoBERT, BART| **박상일, 서희** |
33 | |10. 한국어 언어 모델 KoBERT, KoGPT2, KoBART| **이은식** |
34 |
35 | ## Repository Structure
36 | ```
37 | # repo 시작 위치를 /로 표기
38 | /summaries # 발제 자료 업로드
39 | /images # 발제 자료 이미지 업로드 (발제 자료에 이미지가 있다면 해당 디렉토리에 업로드해 상대경로로써 이미지 삽입)
40 | /codes # 발제 내용 기반 예시 코드 등 작성 시 해당 디렉토리에 업로드
41 | ```
42 | - 발제 파일 명명 방식: ```chapter01_발제자(e.g. eunsiklee.확장자)```
43 | - 발제 파일 형식: Markdown, ipynb, pdf 등 자유형식
44 | ## Contributors
45 | - 남수연([@mori8](https://github.com/mori8))
46 | - 박상일([@shyram](https://github.com/shyram))
47 | - 서희([@0hee0](https://github.com/0hee0))
48 | - 이은식([@emphasis10](https://github.com/emphasis10))
49 |
50 | ## 그 외의 것들
51 | - 패널티는 따로 정하지 않지만 추후 스터디 운영 상태에 따라 추가될 수 있습니다.
52 |
--------------------------------------------------------------------------------
/codes/10_huggingface_example.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# HuggingFace Examples"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "from transformers import AutoTokenizer, PreTrainedTokenizer\n",
17 | "from transformers import AutoModelForSequenceClassification\n",
18 | "from transformers import pipeline"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": 2,
24 | "metadata": {
25 | "scrolled": true
26 | },
27 | "outputs": [
28 | {
29 | "name": "stderr",
30 | "output_type": "stream",
31 | "text": [
32 | "Some weights of the model checkpoint at monologg/kobigbird-bert-base were not used when initializing BigBirdForMaskedLM: ['cls.seq_relationship.bias', 'cls.seq_relationship.weight']\n",
33 | "- This IS expected if you are initializing BigBirdForMaskedLM from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n",
34 | "- This IS NOT expected if you are initializing BigBirdForMaskedLM from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n"
35 | ]
36 | }
37 | ],
38 | "source": [
39 | "model_name = 'monologg/kobigbird-bert-base'\n",
40 | "fill_mask = pipeline(\n",
41 | " \"fill-mask\",\n",
42 | " model=model_name,\n",
43 | " tokenizer=model_name\n",
44 | ")"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": 3,
50 | "metadata": {
51 | "scrolled": false
52 | },
53 | "outputs": [
54 | {
55 | "name": "stderr",
56 | "output_type": "stream",
57 | "text": [
58 | "Attention type 'block_sparse' is not possible if sequence_length: 10 <= num global tokens: 2 * config.block_size + min. num sliding tokens: 3 * config.block_size + config.num_random_blocks * config.block_size + additional buffer: config.num_random_blocks * config.block_size = 704 with config.block_size = 64, config.num_random_blocks = 3. Changing attention type to 'original_full'...\n"
59 | ]
60 | },
61 | {
62 | "data": {
63 | "text/plain": [
64 | "[{'score': 0.5767750144004822,\n",
65 | " 'token': 10821,\n",
66 | " 'token_str': '워싱턴',\n",
67 | " 'sequence': '미국의 수도는 워싱턴 이다.'},\n",
68 | " {'score': 0.09579449146986008,\n",
69 | " 'token': 8386,\n",
70 | " 'token_str': '뉴욕',\n",
71 | " 'sequence': '미국의 수도는 뉴욕 이다.'},\n",
72 | " {'score': 0.06737150251865387,\n",
73 | " 'token': 13130,\n",
74 | " 'token_str': 'LA',\n",
75 | " 'sequence': '미국의 수도는 LA 이다.'},\n",
76 | " {'score': 0.05947323143482208,\n",
77 | " 'token': 7581,\n",
78 | " 'token_str': '수도',\n",
79 | " 'sequence': '미국의 수도는 수도 이다.'},\n",
80 | " {'score': 0.03958961367607117,\n",
81 | " 'token': 21661,\n",
82 | " 'token_str': '필라델피아',\n",
83 | " 'sequence': '미국의 수도는 필라델피아 이다.'}]"
84 | ]
85 | },
86 | "execution_count": 3,
87 | "metadata": {},
88 | "output_type": "execute_result"
89 | }
90 | ],
91 | "source": [
92 | "fill_mask(\"미국의 수도는 [MASK]이다.\")"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 4,
98 | "metadata": {},
99 | "outputs": [
100 | {
101 | "data": {
102 | "text/plain": [
103 | "[{'score': 0.045219432562589645,\n",
104 | " 'token': 2760,\n",
105 | " 'token_str': '나',\n",
106 | " 'sequence': '나는 나 를 먹는다.'},\n",
107 | " {'score': 0.03540102019906044,\n",
108 | " 'token': 10661,\n",
109 | " 'token_str': '우유',\n",
110 | " 'sequence': '나는 우유 를 먹는다.'},\n",
111 | " {'score': 0.03112361952662468,\n",
112 | " 'token': 8512,\n",
113 | " 'token_str': '고기',\n",
114 | " 'sequence': '나는 고기 를 먹는다.'},\n",
115 | " {'score': 0.026315296068787575,\n",
116 | " 'token': 15610,\n",
117 | " 'token_str': '고구마',\n",
118 | " 'sequence': '나는 고구마 를 먹는다.'},\n",
119 | " {'score': 0.01981933042407036,\n",
120 | " 'token': 14976,\n",
121 | " 'token_str': '쇠고기',\n",
122 | " 'sequence': '나는 쇠고기 를 먹는다.'}]"
123 | ]
124 | },
125 | "execution_count": 4,
126 | "metadata": {},
127 | "output_type": "execute_result"
128 | }
129 | ],
130 | "source": [
131 | "fill_mask(\"나는 [MASK]를 먹는다.\")"
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": 5,
137 | "metadata": {},
138 | "outputs": [
139 | {
140 | "data": {
141 | "text/plain": [
142 | "[{'score': 0.8281315565109253,\n",
143 | " 'token': 7581,\n",
144 | " 'token_str': '수도',\n",
145 | " 'sequence': '한국의 수도 는 인천이다.'},\n",
146 | " {'score': 0.015533183701336384,\n",
147 | " 'token': 6936,\n",
148 | " 'token_str': '도시',\n",
149 | " 'sequence': '한국의 도시 는 인천이다.'},\n",
150 | " {'score': 0.008934497833251953,\n",
151 | " 'token': 9879,\n",
152 | " 'token_str': '고도',\n",
153 | " 'sequence': '한국의 고도 는 인천이다.'},\n",
154 | " {'score': 0.008657638914883137,\n",
155 | " 'token': 12588,\n",
156 | " 'token_str': '중심지',\n",
157 | " 'sequence': '한국의 중심지 는 인천이다.'},\n",
158 | " {'score': 0.005730825942009687,\n",
159 | " 'token': 20365,\n",
160 | " 'token_str': '소재지',\n",
161 | " 'sequence': '한국의 소재지 는 인천이다.'}]"
162 | ]
163 | },
164 | "execution_count": 5,
165 | "metadata": {},
166 | "output_type": "execute_result"
167 | }
168 | ],
169 | "source": [
170 | "fill_mask(\"한국의 [MASK]는 인천이다.\")"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": 6,
176 | "metadata": {},
177 | "outputs": [
178 | {
179 | "data": {
180 | "text/plain": [
181 | "[{'score': 0.07572885602712631,\n",
182 | " 'token': 7841,\n",
183 | " 'token_str': '소재',\n",
184 | " 'sequence': '인천 소재 대학교'},\n",
185 | " {'score': 0.06376954168081284,\n",
186 | " 'token': 6816,\n",
187 | " 'token_str': '지역',\n",
188 | " 'sequence': '인천 지역 대학교'},\n",
189 | " {'score': 0.053160928189754486,\n",
190 | " 'token': 517,\n",
191 | " 'token_str': '-',\n",
192 | " 'sequence': '인천 - 대학교'},\n",
193 | " {'score': 0.04669084772467613,\n",
194 | " 'token': 7019,\n",
195 | " 'token_str': '국제',\n",
196 | " 'sequence': '인천 국제 대학교'},\n",
197 | " {'score': 0.03119579143822193,\n",
198 | " 'token': 12504,\n",
199 | " 'token_str': '시립',\n",
200 | " 'sequence': '인천 시립 대학교'}]"
201 | ]
202 | },
203 | "execution_count": 6,
204 | "metadata": {},
205 | "output_type": "execute_result"
206 | }
207 | ],
208 | "source": [
209 | "fill_mask(\"인천 [MASK] 대학교\")"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "# KoBERT"
217 | ]
218 | },
219 | {
220 | "cell_type": "code",
221 | "execution_count": 1,
222 | "metadata": {},
223 | "outputs": [],
224 | "source": [
225 | "from transformers import AutoTokenizer, PreTrainedTokenizer\n",
226 | "from transformers import AutoModelForSequenceClassification\n",
227 | "from transformers import pipeline"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": 7,
233 | "metadata": {},
234 | "outputs": [],
235 | "source": [
236 | "tokenizer = AutoTokenizer.from_pretrained('skt/kobert-base-v1', use_fast=False)"
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": 8,
242 | "metadata": {},
243 | "outputs": [
244 | {
245 | "data": {
246 | "text/plain": [
247 | "PreTrainedTokenizer(name_or_path='skt/kobert-base-v1', vocab_size=8002, model_max_len=1000000000000000019884624838656, is_fast=False, padding_side='left', truncation_side='right', special_tokens={'bos_token': '[CLS]', 'eos_token': '[SEP]', 'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': AddedToken(\"[MASK]\", rstrip=False, lstrip=True, single_word=False, normalized=True)})"
248 | ]
249 | },
250 | "execution_count": 8,
251 | "metadata": {},
252 | "output_type": "execute_result"
253 | }
254 | ],
255 | "source": [
256 | "tokenizer"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": 9,
262 | "metadata": {},
263 | "outputs": [
264 | {
265 | "data": {
266 | "text/plain": [
267 | "['▁한국', '어', '▁모델', '을', '▁공유', '합니다', '.']"
268 | ]
269 | },
270 | "execution_count": 9,
271 | "metadata": {},
272 | "output_type": "execute_result"
273 | }
274 | ],
275 | "source": [
276 | "tokenizer.tokenize('한국어 모델을 공유합니다.')"
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": 10,
282 | "metadata": {},
283 | "outputs": [
284 | {
285 | "data": {
286 | "text/plain": [
287 | "[4958, 6855, 2046, 7088, 1050, 7843, 54, 3, 2]"
288 | ]
289 | },
290 | "execution_count": 10,
291 | "metadata": {},
292 | "output_type": "execute_result"
293 | }
294 | ],
295 | "source": [
296 | "tokenizer.encode(\"한국어 모델을 공유합니다.\")"
297 | ]
298 | },
299 | {
300 | "cell_type": "markdown",
301 | "metadata": {},
302 | "source": [
303 | "## Sentiment Analysis using pretrained model(w. klue/bert-base)"
304 | ]
305 | },
306 | {
307 | "cell_type": "markdown",
308 | "metadata": {},
309 | "source": [
310 | "https://huggingface.co/docs/transformers/custom_datasets"
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": 2,
316 | "metadata": {
317 | "scrolled": true
318 | },
319 | "outputs": [
320 | {
321 | "name": "stderr",
322 | "output_type": "stream",
323 | "text": [
324 | "Some weights of the model checkpoint at klue/bert-base were not used when initializing BertForSequenceClassification: ['cls.predictions.decoder.weight', 'cls.predictions.decoder.bias', 'cls.predictions.transform.LayerNorm.weight', 'cls.seq_relationship.bias', 'cls.predictions.transform.dense.bias', 'cls.seq_relationship.weight', 'cls.predictions.transform.LayerNorm.bias', 'cls.predictions.bias', 'cls.predictions.transform.dense.weight']\n",
325 | "- This IS expected if you are initializing BertForSequenceClassification from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n",
326 | "- This IS NOT expected if you are initializing BertForSequenceClassification from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n",
327 | "Some weights of BertForSequenceClassification were not initialized from the model checkpoint at klue/bert-base and are newly initialized: ['classifier.bias', 'classifier.weight']\n",
328 | "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
329 | ]
330 | }
331 | ],
332 | "source": [
333 | "model = AutoModelForSequenceClassification.from_pretrained('klue/bert-base', num_labels=2)\n",
334 | "tokenizer = AutoTokenizer.from_pretrained('klue/bert-base')"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": 3,
340 | "metadata": {},
341 | "outputs": [
342 | {
343 | "name": "stdout",
344 | "output_type": "stream",
345 | "text": [
346 | "fatal: destination path 'nsmc' already exists and is not an empty directory.\r\n"
347 | ]
348 | }
349 | ],
350 | "source": [
351 | "!git clone https://github.com/e9t/nsmc.git"
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "execution_count": 4,
357 | "metadata": {},
358 | "outputs": [],
359 | "source": [
360 | "import json\n",
361 | "import os\n",
362 | "import torch\n",
363 | "\n",
364 | "from collections import Counter\n",
365 | "from datasets import Dataset\n",
366 | "from transformers import Trainer, TrainingArguments"
367 | ]
368 | },
369 | {
370 | "cell_type": "code",
371 | "execution_count": 5,
372 | "metadata": {
373 | "scrolled": false
374 | },
375 | "outputs": [],
376 | "source": [
377 | "raw_paths = [os.path.join('nsmc', 'raw', path) for path in os.listdir('nsmc/raw')]"
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": 38,
383 | "metadata": {},
384 | "outputs": [],
385 | "source": [
386 | "dat = {'text': [], 'label': []}"
387 | ]
388 | },
389 | {
390 | "cell_type": "code",
391 | "execution_count": 39,
392 | "metadata": {},
393 | "outputs": [],
394 | "source": [
395 | "labels = []\n",
396 | "for path in raw_paths:\n",
397 | " with open(path) as f:\n",
398 | " data = json.load(f)\n",
399 | " for i in data:\n",
400 | " if int(i['rating']) >= 9:\n",
401 | " dat['text'].append(i['review'])\n",
402 | " dat['label'].append(1)\n",
403 | " elif int(i['rating']) <= 4:\n",
404 | " dat['text'].append(i['review'])\n",
405 | " dat['label'].append(0)"
406 | ]
407 | },
408 | {
409 | "cell_type": "code",
410 | "execution_count": 40,
411 | "metadata": {},
412 | "outputs": [],
413 | "source": [
414 | "def preprocess_function(examples):\n",
415 | " return tokenizer(examples['text'], truncation=True, padding='max_length', max_length=512)"
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": 41,
421 | "metadata": {},
422 | "outputs": [],
423 | "source": [
424 | "train_dat = {'text': dat['text'][:1000], 'label': dat['label'][:1000]}\n",
425 | "train_dat = Dataset.from_dict(train_dat, split='train')\n",
426 | "train_dataset = train_dat.map(preprocess_function, batched=True, num_proc=7)\n",
427 | "train_dataset = train_dataset.remove_columns('text')"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 42,
433 | "metadata": {},
434 | "outputs": [],
435 | "source": [
436 | "valid_dat = {'text': dat['text'][1000:2000], 'label': dat['label'][1000:2000]}\n",
437 | "valid_dat = Dataset.from_dict(valid_dat, split='train')\n",
438 | "valid_dataset = valid_dat.map(preprocess_function, batched=True, num_proc=7)\n",
439 | "valid_dataset = valid_dataset.remove_columns('text')"
440 | ]
441 | },
442 | {
443 | "cell_type": "code",
444 | "execution_count": 43,
445 | "metadata": {},
446 | "outputs": [],
447 | "source": [
448 | "from datasets import load_metric\n",
449 | "import numpy as np\n",
450 | "metric = load_metric('accuracy')\n",
451 | "\n",
452 | "def compute_metrics(eval_pred):\n",
453 | " logits, labels = eval_pred\n",
454 | " predictions = np.argmax(logits, axis=-1)\n",
455 | " return metric.compute(predictions=predictions, references=labels)"
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": 44,
461 | "metadata": {},
462 | "outputs": [
463 | {
464 | "data": {
465 | "text/plain": [
466 | "Dataset({\n",
467 | " features: ['label', 'input_ids', 'token_type_ids', 'attention_mask'],\n",
468 | " num_rows: 1000\n",
469 | "})"
470 | ]
471 | },
472 | "execution_count": 44,
473 | "metadata": {},
474 | "output_type": "execute_result"
475 | }
476 | ],
477 | "source": [
478 | "train_dataset"
479 | ]
480 | },
481 | {
482 | "cell_type": "code",
483 | "execution_count": 45,
484 | "metadata": {},
485 | "outputs": [
486 | {
487 | "data": {
488 | "text/plain": [
489 | "Dataset({\n",
490 | " features: ['text', 'label'],\n",
491 | " num_rows: 1000\n",
492 | "})"
493 | ]
494 | },
495 | "execution_count": 45,
496 | "metadata": {},
497 | "output_type": "execute_result"
498 | }
499 | ],
500 | "source": [
501 | "valid_dataset"
502 | ]
503 | },
504 | {
505 | "cell_type": "code",
506 | "execution_count": 50,
507 | "metadata": {},
508 | "outputs": [
509 | {
510 | "name": "stderr",
511 | "output_type": "stream",
512 | "text": [
513 | "PyTorch: setting up devices\n",
514 | "The default value for the training argument `--report_to` will change in v5 (from all installed integrations to none). In v5, you will need to use `--report_to all` to get the same behavior as now. You should start updating your code and make this info disappear :-).\n"
515 | ]
516 | }
517 | ],
518 | "source": [
519 | "args = TrainingArguments(output_dir='./sentiment',\n",
520 | " per_device_train_batch_size=4,\n",
521 | " logging_steps=100,\n",
522 | " evaluation_strategy='epoch',\n",
523 | " do_eval=True)"
524 | ]
525 | },
526 | {
527 | "cell_type": "code",
528 | "execution_count": 51,
529 | "metadata": {},
530 | "outputs": [],
531 | "source": [
532 | "trainer = Trainer(model=model,\n",
533 | " args=args,\n",
534 | " train_dataset=train_dataset,\n",
535 | " eval_dataset=valid_dataset,\n",
536 | " tokenizer=tokenizer,\n",
537 | " compute_metrics=compute_metrics)"
538 | ]
539 | },
540 | {
541 | "cell_type": "code",
542 | "execution_count": 52,
543 | "metadata": {
544 | "scrolled": false
545 | },
546 | "outputs": [
547 | {
548 | "name": "stderr",
549 | "output_type": "stream",
550 | "text": [
551 | "/usr/local/lib/python3.6/dist-packages/transformers/optimization.py:309: FutureWarning: This implementation of AdamW is deprecated and will be removed in a future version. Use the PyTorch implementation torch.optim.AdamW instead, or set `no_deprecation_warning=True` to disable this warning\n",
552 | " FutureWarning,\n",
553 | "***** Running training *****\n",
554 | " Num examples = 1000\n",
555 | " Num Epochs = 3\n",
556 | " Instantaneous batch size per device = 4\n",
557 | " Total train batch size (w. parallel, distributed & accumulation) = 4\n",
558 | " Gradient Accumulation steps = 1\n",
559 | " Total optimization steps = 750\n"
560 | ]
561 | },
562 | {
563 | "data": {
564 | "text/html": [
565 | "\n",
566 | "
\n",
567 | " \n",
568 | "
\n",
569 | " [750/750 03:53, Epoch 3/3]\n",
570 | "
\n",
571 | " \n",
572 | " \n",
573 | " \n",
574 | " Epoch | \n",
575 | " Training Loss | \n",
576 | " Validation Loss | \n",
577 | " Accuracy | \n",
578 | "
\n",
579 | " \n",
580 | " \n",
581 | " \n",
582 | " 1 | \n",
583 | " 0.130500 | \n",
584 | " 1.096880 | \n",
585 | " 0.831000 | \n",
586 | "
\n",
587 | " \n",
588 | " 2 | \n",
589 | " 0.068400 | \n",
590 | " 0.926864 | \n",
591 | " 0.873000 | \n",
592 | "
\n",
593 | " \n",
594 | " 3 | \n",
595 | " 0.063500 | \n",
596 | " 0.924929 | \n",
597 | " 0.876000 | \n",
598 | "
\n",
599 | " \n",
600 | "
"
601 | ],
602 | "text/plain": [
603 | ""
604 | ]
605 | },
606 | "metadata": {},
607 | "output_type": "display_data"
608 | },
609 | {
610 | "name": "stderr",
611 | "output_type": "stream",
612 | "text": [
613 | "***** Running Evaluation *****\n",
614 | " Num examples = 1000\n",
615 | " Batch size = 8\n",
616 | "Saving model checkpoint to ./sentiment/checkpoint-500\n",
617 | "Configuration saved in ./sentiment/checkpoint-500/config.json\n",
618 | "Model weights saved in ./sentiment/checkpoint-500/pytorch_model.bin\n",
619 | "tokenizer config file saved in ./sentiment/checkpoint-500/tokenizer_config.json\n",
620 | "Special tokens file saved in ./sentiment/checkpoint-500/special_tokens_map.json\n",
621 | "***** Running Evaluation *****\n",
622 | " Num examples = 1000\n",
623 | " Batch size = 8\n",
624 | "***** Running Evaluation *****\n",
625 | " Num examples = 1000\n",
626 | " Batch size = 8\n",
627 | "\n",
628 | "\n",
629 | "Training completed. Do not forget to share your model on huggingface.co/models =)\n",
630 | "\n",
631 | "\n"
632 | ]
633 | },
634 | {
635 | "data": {
636 | "text/plain": [
637 | "TrainOutput(global_step=750, training_loss=0.0730759978418549, metrics={'train_runtime': 233.4359, 'train_samples_per_second': 12.851, 'train_steps_per_second': 3.213, 'total_flos': 789333166080000.0, 'train_loss': 0.0730759978418549, 'epoch': 3.0})"
638 | ]
639 | },
640 | "execution_count": 52,
641 | "metadata": {},
642 | "output_type": "execute_result"
643 | }
644 | ],
645 | "source": [
646 | "trainer.train()"
647 | ]
648 | },
649 | {
650 | "cell_type": "markdown",
651 | "metadata": {},
652 | "source": [
653 | "# KoGPT2"
654 | ]
655 | },
656 | {
657 | "cell_type": "code",
658 | "execution_count": 53,
659 | "metadata": {},
660 | "outputs": [],
661 | "source": [
662 | "from transformers import GPT2LMHeadModel\n",
663 | "from transformers import PreTrainedTokenizerFast"
664 | ]
665 | },
666 | {
667 | "cell_type": "code",
668 | "execution_count": 54,
669 | "metadata": {
670 | "scrolled": true
671 | },
672 | "outputs": [
673 | {
674 | "name": "stderr",
675 | "output_type": "stream",
676 | "text": [
677 | "loading file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/tokenizer.json from cache at /root/.cache/huggingface/transformers/fd8418e6675550cbca8ad6c102d717aa89372eb7a632ad3168300c7fed43491c.db074bfdd88bec54455de5ee2400efdbc64d4acf449a44d5f314e79c1eadc611\n",
678 | "loading file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/added_tokens.json from cache at None\n",
679 | "loading file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/special_tokens_map.json from cache at None\n",
680 | "loading file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/tokenizer_config.json from cache at None\n",
681 | "loading configuration file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/13bb826cf24517d7849a701e02452715a67c5e560142be3d4735442b2a545809.6b384eec6effdd44287f67715cd55bd0dff2cf846d843b932b43ba7b632b8b1e\n",
682 | "Model config GPT2Config {\n",
683 | " \"_name_or_path\": \"skt/kogpt2-base-v2\",\n",
684 | " \"_num_labels\": 1,\n",
685 | " \"activation_function\": \"gelu_new\",\n",
686 | " \"architectures\": [\n",
687 | " \"GPT2LMHeadModel\"\n",
688 | " ],\n",
689 | " \"attn_pdrop\": 0.1,\n",
690 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
691 | " \"bos_token_id\": 0,\n",
692 | " \"created_date\": \"2021-04-28\",\n",
693 | " \"embd_pdrop\": 0.1,\n",
694 | " \"eos_token_id\": 1,\n",
695 | " \"gradient_checkpointing\": false,\n",
696 | " \"id2label\": {\n",
697 | " \"0\": \"LABEL_0\"\n",
698 | " },\n",
699 | " \"initializer_range\": 0.02,\n",
700 | " \"label2id\": {\n",
701 | " \"LABEL_0\": 0\n",
702 | " },\n",
703 | " \"layer_norm_epsilon\": 1e-05,\n",
704 | " \"license\": \"CC-BY-NC-SA 4.0\",\n",
705 | " \"model_type\": \"gpt2\",\n",
706 | " \"n_ctx\": 1024,\n",
707 | " \"n_embd\": 768,\n",
708 | " \"n_head\": 12,\n",
709 | " \"n_inner\": null,\n",
710 | " \"n_layer\": 12,\n",
711 | " \"n_positions\": 1024,\n",
712 | " \"pad_token_id\": 3,\n",
713 | " \"reorder_and_upcast_attn\": false,\n",
714 | " \"resid_pdrop\": 0.1,\n",
715 | " \"scale_attn_by_inverse_layer_idx\": false,\n",
716 | " \"scale_attn_weights\": true,\n",
717 | " \"summary_activation\": null,\n",
718 | " \"summary_first_dropout\": 0.1,\n",
719 | " \"summary_proj_to_labels\": true,\n",
720 | " \"summary_type\": \"cls_index\",\n",
721 | " \"summary_use_proj\": true,\n",
722 | " \"task_specific_params\": {\n",
723 | " \"text-generation\": {\n",
724 | " \"do_sample\": true,\n",
725 | " \"max_length\": 50\n",
726 | " }\n",
727 | " },\n",
728 | " \"transformers_version\": \"4.17.0\",\n",
729 | " \"use_cache\": true,\n",
730 | " \"vocab_size\": 51200\n",
731 | "}\n",
732 | "\n",
733 | "The tokenizer class you load from this checkpoint is not the same type as the class this function is called from. It may result in unexpected tokenization. \n",
734 | "The tokenizer class you load from this checkpoint is 'GPT2Tokenizer'. \n",
735 | "The class this function is called from is 'PreTrainedTokenizerFast'.\n"
736 | ]
737 | }
738 | ],
739 | "source": [
740 | "tokenizer = PreTrainedTokenizerFast.from_pretrained('skt/kogpt2-base-v2',\n",
741 | " bos_token='',\n",
742 | " eos_token='',\n",
743 | " pad_token='',\n",
744 | " mask_token='')"
745 | ]
746 | },
747 | {
748 | "cell_type": "code",
749 | "execution_count": 55,
750 | "metadata": {},
751 | "outputs": [
752 | {
753 | "data": {
754 | "text/plain": [
755 | "[25906, 8702, 7801, 25856, 34407, 10528, 422, 426, 18258, 14652, 21154]"
756 | ]
757 | },
758 | "execution_count": 55,
759 | "metadata": {},
760 | "output_type": "execute_result"
761 | }
762 | ],
763 | "source": [
764 | "tokenizer.encode(\"안녕하세요. 한국어 GPT-2 모델입니다.\")"
765 | ]
766 | },
767 | {
768 | "cell_type": "code",
769 | "execution_count": 56,
770 | "metadata": {},
771 | "outputs": [],
772 | "source": [
773 | "import torch"
774 | ]
775 | },
776 | {
777 | "cell_type": "code",
778 | "execution_count": 57,
779 | "metadata": {
780 | "scrolled": true
781 | },
782 | "outputs": [
783 | {
784 | "name": "stderr",
785 | "output_type": "stream",
786 | "text": [
787 | "loading configuration file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/13bb826cf24517d7849a701e02452715a67c5e560142be3d4735442b2a545809.6b384eec6effdd44287f67715cd55bd0dff2cf846d843b932b43ba7b632b8b1e\n",
788 | "Model config GPT2Config {\n",
789 | " \"_num_labels\": 1,\n",
790 | " \"activation_function\": \"gelu_new\",\n",
791 | " \"architectures\": [\n",
792 | " \"GPT2LMHeadModel\"\n",
793 | " ],\n",
794 | " \"attn_pdrop\": 0.1,\n",
795 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
796 | " \"bos_token_id\": 0,\n",
797 | " \"created_date\": \"2021-04-28\",\n",
798 | " \"embd_pdrop\": 0.1,\n",
799 | " \"eos_token_id\": 1,\n",
800 | " \"gradient_checkpointing\": false,\n",
801 | " \"id2label\": {\n",
802 | " \"0\": \"LABEL_0\"\n",
803 | " },\n",
804 | " \"initializer_range\": 0.02,\n",
805 | " \"label2id\": {\n",
806 | " \"LABEL_0\": 0\n",
807 | " },\n",
808 | " \"layer_norm_epsilon\": 1e-05,\n",
809 | " \"license\": \"CC-BY-NC-SA 4.0\",\n",
810 | " \"model_type\": \"gpt2\",\n",
811 | " \"n_ctx\": 1024,\n",
812 | " \"n_embd\": 768,\n",
813 | " \"n_head\": 12,\n",
814 | " \"n_inner\": null,\n",
815 | " \"n_layer\": 12,\n",
816 | " \"n_positions\": 1024,\n",
817 | " \"pad_token_id\": 3,\n",
818 | " \"reorder_and_upcast_attn\": false,\n",
819 | " \"resid_pdrop\": 0.1,\n",
820 | " \"scale_attn_by_inverse_layer_idx\": false,\n",
821 | " \"scale_attn_weights\": true,\n",
822 | " \"summary_activation\": null,\n",
823 | " \"summary_first_dropout\": 0.1,\n",
824 | " \"summary_proj_to_labels\": true,\n",
825 | " \"summary_type\": \"cls_index\",\n",
826 | " \"summary_use_proj\": true,\n",
827 | " \"task_specific_params\": {\n",
828 | " \"text-generation\": {\n",
829 | " \"do_sample\": true,\n",
830 | " \"max_length\": 50\n",
831 | " }\n",
832 | " },\n",
833 | " \"transformers_version\": \"4.17.0\",\n",
834 | " \"use_cache\": true,\n",
835 | " \"vocab_size\": 51200\n",
836 | "}\n",
837 | "\n",
838 | "loading weights file https://huggingface.co/skt/kogpt2-base-v2/resolve/main/pytorch_model.bin from cache at /root/.cache/huggingface/transformers/495b405e3742953dbcc56685d1560fa02a2d86fc50b891868990a4471b06c934.4ebf112d34c2c8fc657866680005d92d21859c52c0ef5e941fa640129b2f8f88\n",
839 | "All model checkpoint weights were used when initializing GPT2LMHeadModel.\n",
840 | "\n",
841 | "All the weights of GPT2LMHeadModel were initialized from the model checkpoint at skt/kogpt2-base-v2.\n",
842 | "If your task is similar to the task the model of the checkpoint was trained on, you can already use GPT2LMHeadModel for predictions without further training.\n"
843 | ]
844 | }
845 | ],
846 | "source": [
847 | "text = \"근육이 커지기 위해서는\"\n",
848 | "input_ids = tokenizer.encode(text)\n",
849 | "model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')\n",
850 | "gen_ids = model.generate(torch.tensor([input_ids]),\n",
851 | " max_length=128,\n",
852 | " repetition_penalty=2.0,\n",
853 | " pad_token_id=tokenizer.pad_token_id,\n",
854 | " eos_token_id=tokenizer.eos_token_id,\n",
855 | " bos_token_id=tokenizer.bos_token_id,\n",
856 | " use_cache=True)\n",
857 | "generated = tokenizer.decode(gen_ids[0,:].tolist())"
858 | ]
859 | },
860 | {
861 | "cell_type": "code",
862 | "execution_count": 58,
863 | "metadata": {},
864 | "outputs": [
865 | {
866 | "data": {
867 | "text/plain": [
868 | "'근육이 커지기 위해서는 무엇보다 규칙적인 생활습관이 중요하다.\\n특히, 아침식사는 단백질과 비타민이 풍부한 과일과 채소를 많이 섭취하는 것이 좋다.\\n또한 하루 30분 이상 충분한 수면을 취하는 것도 도움이 된다.\\n아침 식사를 거르지 않고 규칙적으로 운동을 하면 혈액순환에 도움을 줄 뿐만 아니라 신진대사를 촉진해 체내 노폐물을 배출하고 혈압을 낮춰준다.\\n운동은 하루에 10분 정도만 하는 게 좋으며 운동 후에는 반드시 스트레칭을 통해 근육량을 늘리고 유연성을 높여야 한다.\\n운동 후 바로 잠자리에 드는 것은 피해야 하며 특히 아침에 일어나면 몸이 피곤해지기 때문에 무리하게 움직이면 오히려 역효과가 날 수도 있다.\\n운동을'"
869 | ]
870 | },
871 | "execution_count": 58,
872 | "metadata": {},
873 | "output_type": "execute_result"
874 | }
875 | ],
876 | "source": [
877 | "generated"
878 | ]
879 | },
880 | {
881 | "cell_type": "markdown",
882 | "metadata": {},
883 | "source": [
884 | "# KoBART"
885 | ]
886 | },
887 | {
888 | "cell_type": "code",
889 | "execution_count": 59,
890 | "metadata": {},
891 | "outputs": [],
892 | "source": [
893 | "model_name = 'gogamza/kobart-base-v2'"
894 | ]
895 | },
896 | {
897 | "cell_type": "code",
898 | "execution_count": 60,
899 | "metadata": {},
900 | "outputs": [
901 | {
902 | "name": "stderr",
903 | "output_type": "stream",
904 | "text": [
905 | "Could not locate the tokenizer configuration file, will try to use the model config instead.\n",
906 | "loading configuration file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/54a37e9385f90886428b084042f151c1a699203416d41765d94aac4cddb5fd5c.d098ef3866c1da94bdfaa5c1f24ecb7c5c16b37423b79263fbd3668d2ae61f91\n",
907 | "Model config BartConfig {\n",
908 | " \"_name_or_path\": \"gogamza/kobart-base-v2\",\n",
909 | " \"activation_dropout\": 0.0,\n",
910 | " \"activation_function\": \"gelu\",\n",
911 | " \"add_bias_logits\": false,\n",
912 | " \"add_final_layer_norm\": false,\n",
913 | " \"architectures\": [\n",
914 | " \"BartModel\"\n",
915 | " ],\n",
916 | " \"attention_dropout\": 0.0,\n",
917 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
918 | " \"bos_token_id\": 1,\n",
919 | " \"classif_dropout\": 0.1,\n",
920 | " \"classifier_dropout\": 0.1,\n",
921 | " \"d_model\": 768,\n",
922 | " \"decoder_attention_heads\": 16,\n",
923 | " \"decoder_ffn_dim\": 3072,\n",
924 | " \"decoder_layerdrop\": 0.0,\n",
925 | " \"decoder_layers\": 6,\n",
926 | " \"decoder_start_token_id\": 1,\n",
927 | " \"do_blenderbot_90_layernorm\": false,\n",
928 | " \"dropout\": 0.1,\n",
929 | " \"encoder_attention_heads\": 16,\n",
930 | " \"encoder_ffn_dim\": 3072,\n",
931 | " \"encoder_layerdrop\": 0.0,\n",
932 | " \"encoder_layers\": 6,\n",
933 | " \"eos_token_id\": 1,\n",
934 | " \"extra_pos_embeddings\": 2,\n",
935 | " \"force_bos_token_to_be_generated\": false,\n",
936 | " \"forced_eos_token_id\": 1,\n",
937 | " \"gradient_checkpointing\": false,\n",
938 | " \"id2label\": {\n",
939 | " \"0\": \"NEGATIVE\",\n",
940 | " \"1\": \"POSITIVE\"\n",
941 | " },\n",
942 | " \"init_std\": 0.02,\n",
943 | " \"is_encoder_decoder\": true,\n",
944 | " \"kobart_version\": 2.0,\n",
945 | " \"label2id\": {\n",
946 | " \"NEGATIVE\": 0,\n",
947 | " \"POSITIVE\": 1\n",
948 | " },\n",
949 | " \"max_position_embeddings\": 1026,\n",
950 | " \"model_type\": \"bart\",\n",
951 | " \"normalize_before\": false,\n",
952 | " \"normalize_embedding\": true,\n",
953 | " \"num_hidden_layers\": 6,\n",
954 | " \"pad_token_id\": 3,\n",
955 | " \"scale_embedding\": false,\n",
956 | " \"static_position_embeddings\": false,\n",
957 | " \"tokenizer_class\": \"PreTrainedTokenizerFast\",\n",
958 | " \"transformers_version\": \"4.17.0\",\n",
959 | " \"use_cache\": true,\n",
960 | " \"vocab_size\": 30000\n",
961 | "}\n",
962 | "\n",
963 | "loading file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/tokenizer.json from cache at /root/.cache/huggingface/transformers/f94202e1dad4fcfcb282aff4c6865b6119e03c87c6fa9e5886abe93835c41ecd.dc2013f8bbecd755468e2c44397f53dc624be5451d0190744397caf61a20383f\n",
964 | "loading file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/added_tokens.json from cache at /root/.cache/huggingface/transformers/7c75331e2f4b5767db997fbb489f1408eb36a3217beb3057ae8d04bd2b3f97ba.04312f398a3bbda664297588800a86e0fda9d4ef4f0749cd9d96f88043daad39\n",
965 | "loading file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/special_tokens_map.json from cache at /root/.cache/huggingface/transformers/a87d2ed77831bb40ce806a97c04126addf5ecc82b3e23ecf916b2a4acdb9c29a.c23d5e62137984cf842a885705037b25b156747d145406702932d5f5d5e7c88e\n",
966 | "loading file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/tokenizer_config.json from cache at None\n",
967 | "loading configuration file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/54a37e9385f90886428b084042f151c1a699203416d41765d94aac4cddb5fd5c.d098ef3866c1da94bdfaa5c1f24ecb7c5c16b37423b79263fbd3668d2ae61f91\n",
968 | "Model config BartConfig {\n",
969 | " \"_name_or_path\": \"gogamza/kobart-base-v2\",\n",
970 | " \"activation_dropout\": 0.0,\n",
971 | " \"activation_function\": \"gelu\",\n",
972 | " \"add_bias_logits\": false,\n",
973 | " \"add_final_layer_norm\": false,\n",
974 | " \"architectures\": [\n",
975 | " \"BartModel\"\n",
976 | " ],\n",
977 | " \"attention_dropout\": 0.0,\n",
978 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
979 | " \"bos_token_id\": 1,\n",
980 | " \"classif_dropout\": 0.1,\n",
981 | " \"classifier_dropout\": 0.1,\n",
982 | " \"d_model\": 768,\n",
983 | " \"decoder_attention_heads\": 16,\n",
984 | " \"decoder_ffn_dim\": 3072,\n",
985 | " \"decoder_layerdrop\": 0.0,\n",
986 | " \"decoder_layers\": 6,\n",
987 | " \"decoder_start_token_id\": 1,\n",
988 | " \"do_blenderbot_90_layernorm\": false,\n",
989 | " \"dropout\": 0.1,\n",
990 | " \"encoder_attention_heads\": 16,\n",
991 | " \"encoder_ffn_dim\": 3072,\n",
992 | " \"encoder_layerdrop\": 0.0,\n",
993 | " \"encoder_layers\": 6,\n",
994 | " \"eos_token_id\": 1,\n",
995 | " \"extra_pos_embeddings\": 2,\n",
996 | " \"force_bos_token_to_be_generated\": false,\n",
997 | " \"forced_eos_token_id\": 1,\n",
998 | " \"gradient_checkpointing\": false,\n",
999 | " \"id2label\": {\n",
1000 | " \"0\": \"NEGATIVE\",\n",
1001 | " \"1\": \"POSITIVE\"\n",
1002 | " },\n",
1003 | " \"init_std\": 0.02,\n",
1004 | " \"is_encoder_decoder\": true,\n",
1005 | " \"kobart_version\": 2.0,\n",
1006 | " \"label2id\": {\n",
1007 | " \"NEGATIVE\": 0,\n",
1008 | " \"POSITIVE\": 1\n",
1009 | " },\n",
1010 | " \"max_position_embeddings\": 1026,\n",
1011 | " \"model_type\": \"bart\",\n",
1012 | " \"normalize_before\": false,\n",
1013 | " \"normalize_embedding\": true,\n",
1014 | " \"num_hidden_layers\": 6,\n",
1015 | " \"pad_token_id\": 3,\n",
1016 | " \"scale_embedding\": false,\n",
1017 | " \"static_position_embeddings\": false,\n",
1018 | " \"tokenizer_class\": \"PreTrainedTokenizerFast\",\n",
1019 | " \"transformers_version\": \"4.17.0\",\n",
1020 | " \"use_cache\": true,\n",
1021 | " \"vocab_size\": 30000\n",
1022 | "}\n",
1023 | "\n"
1024 | ]
1025 | }
1026 | ],
1027 | "source": [
1028 | "tokenizer = AutoTokenizer.from_pretrained(model_name)"
1029 | ]
1030 | },
1031 | {
1032 | "cell_type": "code",
1033 | "execution_count": 61,
1034 | "metadata": {},
1035 | "outputs": [
1036 | {
1037 | "data": {
1038 | "text/plain": [
1039 | "['▁안녕하',\n",
1040 | " '세요.',\n",
1041 | " '▁한국어',\n",
1042 | " '▁B',\n",
1043 | " 'A',\n",
1044 | " 'R',\n",
1045 | " 'T',\n",
1046 | " '입니다.',\n",
1047 | " 'ᄆ',\n",
1048 | " ':)',\n",
1049 | " '▁',\n",
1050 | " 'ᅵ',\n",
1051 | " '^',\n",
1052 | " 'o']"
1053 | ]
1054 | },
1055 | "execution_count": 61,
1056 | "metadata": {},
1057 | "output_type": "execute_result"
1058 | }
1059 | ],
1060 | "source": [
1061 | "tokenizer.tokenize(\"안녕하세요. 한국어 BART입니다.ㅁ:)ㅣ^o\")"
1062 | ]
1063 | },
1064 | {
1065 | "cell_type": "code",
1066 | "execution_count": 62,
1067 | "metadata": {},
1068 | "outputs": [],
1069 | "source": [
1070 | "from transformers import AutoModel"
1071 | ]
1072 | },
1073 | {
1074 | "cell_type": "code",
1075 | "execution_count": 63,
1076 | "metadata": {},
1077 | "outputs": [
1078 | {
1079 | "name": "stderr",
1080 | "output_type": "stream",
1081 | "text": [
1082 | "loading configuration file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/54a37e9385f90886428b084042f151c1a699203416d41765d94aac4cddb5fd5c.d098ef3866c1da94bdfaa5c1f24ecb7c5c16b37423b79263fbd3668d2ae61f91\n",
1083 | "Model config BartConfig {\n",
1084 | " \"_name_or_path\": \"gogamza/kobart-base-v2\",\n",
1085 | " \"activation_dropout\": 0.0,\n",
1086 | " \"activation_function\": \"gelu\",\n",
1087 | " \"add_bias_logits\": false,\n",
1088 | " \"add_final_layer_norm\": false,\n",
1089 | " \"architectures\": [\n",
1090 | " \"BartModel\"\n",
1091 | " ],\n",
1092 | " \"attention_dropout\": 0.0,\n",
1093 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
1094 | " \"bos_token_id\": 1,\n",
1095 | " \"classif_dropout\": 0.1,\n",
1096 | " \"classifier_dropout\": 0.1,\n",
1097 | " \"d_model\": 768,\n",
1098 | " \"decoder_attention_heads\": 16,\n",
1099 | " \"decoder_ffn_dim\": 3072,\n",
1100 | " \"decoder_layerdrop\": 0.0,\n",
1101 | " \"decoder_layers\": 6,\n",
1102 | " \"decoder_start_token_id\": 1,\n",
1103 | " \"do_blenderbot_90_layernorm\": false,\n",
1104 | " \"dropout\": 0.1,\n",
1105 | " \"encoder_attention_heads\": 16,\n",
1106 | " \"encoder_ffn_dim\": 3072,\n",
1107 | " \"encoder_layerdrop\": 0.0,\n",
1108 | " \"encoder_layers\": 6,\n",
1109 | " \"eos_token_id\": 1,\n",
1110 | " \"extra_pos_embeddings\": 2,\n",
1111 | " \"force_bos_token_to_be_generated\": false,\n",
1112 | " \"forced_eos_token_id\": 1,\n",
1113 | " \"gradient_checkpointing\": false,\n",
1114 | " \"id2label\": {\n",
1115 | " \"0\": \"NEGATIVE\",\n",
1116 | " \"1\": \"POSITIVE\"\n",
1117 | " },\n",
1118 | " \"init_std\": 0.02,\n",
1119 | " \"is_encoder_decoder\": true,\n",
1120 | " \"kobart_version\": 2.0,\n",
1121 | " \"label2id\": {\n",
1122 | " \"NEGATIVE\": 0,\n",
1123 | " \"POSITIVE\": 1\n",
1124 | " },\n",
1125 | " \"max_position_embeddings\": 1026,\n",
1126 | " \"model_type\": \"bart\",\n",
1127 | " \"normalize_before\": false,\n",
1128 | " \"normalize_embedding\": true,\n",
1129 | " \"num_hidden_layers\": 6,\n",
1130 | " \"pad_token_id\": 3,\n",
1131 | " \"scale_embedding\": false,\n",
1132 | " \"static_position_embeddings\": false,\n",
1133 | " \"tokenizer_class\": \"PreTrainedTokenizerFast\",\n",
1134 | " \"transformers_version\": \"4.17.0\",\n",
1135 | " \"use_cache\": true,\n",
1136 | " \"vocab_size\": 30000\n",
1137 | "}\n",
1138 | "\n",
1139 | "loading weights file https://huggingface.co/gogamza/kobart-base-v2/resolve/main/pytorch_model.bin from cache at /root/.cache/huggingface/transformers/6a128677efa8d82c5bc9853bbefcff450bf4174bed52765687fc77f1aa7a39c1.ef5977990801f5b7dbc37adda9fe5948ed9829c75ac20e99bf026098743b1978\n",
1140 | "All model checkpoint weights were used when initializing BartModel.\n",
1141 | "\n",
1142 | "All the weights of BartModel were initialized from the model checkpoint at gogamza/kobart-base-v2.\n",
1143 | "If your task is similar to the task the model of the checkpoint was trained on, you can already use BartModel for predictions without further training.\n"
1144 | ]
1145 | }
1146 | ],
1147 | "source": [
1148 | "model = AutoModel.from_pretrained(model_name)"
1149 | ]
1150 | },
1151 | {
1152 | "cell_type": "code",
1153 | "execution_count": 64,
1154 | "metadata": {},
1155 | "outputs": [],
1156 | "source": [
1157 | "inputs = tokenizer(['안녕하세요'], return_tensors='pt')"
1158 | ]
1159 | },
1160 | {
1161 | "cell_type": "code",
1162 | "execution_count": 65,
1163 | "metadata": {},
1164 | "outputs": [
1165 | {
1166 | "data": {
1167 | "text/plain": [
1168 | "{'input_ids': tensor([[22465, 23935]]), 'token_type_ids': tensor([[0, 0]]), 'attention_mask': tensor([[1, 1]])}"
1169 | ]
1170 | },
1171 | "execution_count": 65,
1172 | "metadata": {},
1173 | "output_type": "execute_result"
1174 | }
1175 | ],
1176 | "source": [
1177 | "inputs"
1178 | ]
1179 | },
1180 | {
1181 | "cell_type": "code",
1182 | "execution_count": 66,
1183 | "metadata": {},
1184 | "outputs": [],
1185 | "source": [
1186 | "results = model(inputs['input_ids'])"
1187 | ]
1188 | },
1189 | {
1190 | "cell_type": "code",
1191 | "execution_count": 67,
1192 | "metadata": {},
1193 | "outputs": [
1194 | {
1195 | "data": {
1196 | "text/plain": [
1197 | "odict_keys(['last_hidden_state', 'past_key_values', 'encoder_last_hidden_state'])"
1198 | ]
1199 | },
1200 | "execution_count": 67,
1201 | "metadata": {},
1202 | "output_type": "execute_result"
1203 | }
1204 | ],
1205 | "source": [
1206 | "results.keys()"
1207 | ]
1208 | },
1209 | {
1210 | "cell_type": "code",
1211 | "execution_count": 68,
1212 | "metadata": {},
1213 | "outputs": [
1214 | {
1215 | "data": {
1216 | "text/plain": [
1217 | "torch.Size([1, 2, 768])"
1218 | ]
1219 | },
1220 | "execution_count": 68,
1221 | "metadata": {},
1222 | "output_type": "execute_result"
1223 | }
1224 | ],
1225 | "source": [
1226 | "results['encoder_last_hidden_state'].shape # (batch_size, sequence_length, hidden state dimension)"
1227 | ]
1228 | },
1229 | {
1230 | "cell_type": "code",
1231 | "execution_count": 69,
1232 | "metadata": {},
1233 | "outputs": [
1234 | {
1235 | "data": {
1236 | "text/plain": [
1237 | "torch.Size([1, 2, 768])"
1238 | ]
1239 | },
1240 | "execution_count": 69,
1241 | "metadata": {},
1242 | "output_type": "execute_result"
1243 | }
1244 | ],
1245 | "source": [
1246 | "results['last_hidden_state'].shape"
1247 | ]
1248 | },
1249 | {
1250 | "cell_type": "markdown",
1251 | "metadata": {},
1252 | "source": [
1253 | "## BART for summarization"
1254 | ]
1255 | },
1256 | {
1257 | "cell_type": "code",
1258 | "execution_count": 70,
1259 | "metadata": {},
1260 | "outputs": [],
1261 | "source": [
1262 | "from transformers import PreTrainedTokenizerFast\n",
1263 | "from transformers import BartForConditionalGeneration"
1264 | ]
1265 | },
1266 | {
1267 | "cell_type": "code",
1268 | "execution_count": 71,
1269 | "metadata": {},
1270 | "outputs": [],
1271 | "source": [
1272 | "model_name = 'gogamza/kobart-summarization'"
1273 | ]
1274 | },
1275 | {
1276 | "cell_type": "code",
1277 | "execution_count": 72,
1278 | "metadata": {},
1279 | "outputs": [
1280 | {
1281 | "name": "stderr",
1282 | "output_type": "stream",
1283 | "text": [
1284 | "loading file https://huggingface.co/gogamza/kobart-summarization/resolve/main/tokenizer.json from cache at /root/.cache/huggingface/transformers/4369897f91813214377063544fb9a44ad537ca3a2559c7bdc98eaf9d934d4a89.dc2013f8bbecd755468e2c44397f53dc624be5451d0190744397caf61a20383f\n",
1285 | "loading file https://huggingface.co/gogamza/kobart-summarization/resolve/main/added_tokens.json from cache at /root/.cache/huggingface/transformers/c8171f2310611c5f6994c35b7016633d42194eb424192baa1910c896fdd197f6.04312f398a3bbda664297588800a86e0fda9d4ef4f0749cd9d96f88043daad39\n",
1286 | "loading file https://huggingface.co/gogamza/kobart-summarization/resolve/main/special_tokens_map.json from cache at /root/.cache/huggingface/transformers/aed722871fe9f8d064a1df70dcfe967be2f02797eaaaf6ee28ffd2c59d7514e9.15447ae63ad4a2eba8bc7a5146360711dc32b315b4f1488b4806debf35315e9a\n",
1287 | "loading file https://huggingface.co/gogamza/kobart-summarization/resolve/main/tokenizer_config.json from cache at None\n",
1288 | "loading configuration file https://huggingface.co/gogamza/kobart-summarization/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/1c32baaf6a1067a5e27a0dfbac0a3d23a86d958ab10b092d5ea4150bd451de17.4e52ef6c87e6938c92ba0d19888607d76e30e950e81060a8fa6cb1189c93614d\n",
1289 | "Model config BartConfig {\n",
1290 | " \"_name_or_path\": \"gogamza/kobart-summarization\",\n",
1291 | " \"activation_dropout\": 0.0,\n",
1292 | " \"activation_function\": \"gelu\",\n",
1293 | " \"add_bias_logits\": false,\n",
1294 | " \"add_final_layer_norm\": false,\n",
1295 | " \"architectures\": [\n",
1296 | " \"BartForConditionalGeneration\"\n",
1297 | " ],\n",
1298 | " \"attention_dropout\": 0.0,\n",
1299 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
1300 | " \"bos_token_id\": 0,\n",
1301 | " \"classif_dropout\": 0.1,\n",
1302 | " \"classifier_dropout\": 0.1,\n",
1303 | " \"d_model\": 768,\n",
1304 | " \"decoder_attention_heads\": 16,\n",
1305 | " \"decoder_ffn_dim\": 3072,\n",
1306 | " \"decoder_layerdrop\": 0.0,\n",
1307 | " \"decoder_layers\": 6,\n",
1308 | " \"decoder_start_token_id\": 2,\n",
1309 | " \"do_blenderbot_90_layernorm\": false,\n",
1310 | " \"dropout\": 0.1,\n",
1311 | " \"encoder_attention_heads\": 16,\n",
1312 | " \"encoder_ffn_dim\": 3072,\n",
1313 | " \"encoder_layerdrop\": 0.0,\n",
1314 | " \"encoder_layers\": 6,\n",
1315 | " \"eos_token_id\": 1,\n",
1316 | " \"extra_pos_embeddings\": 2,\n",
1317 | " \"force_bos_token_to_be_generated\": false,\n",
1318 | " \"forced_eos_token_id\": 2,\n",
1319 | " \"id2label\": {\n",
1320 | " \"0\": \"NEGATIVE\",\n",
1321 | " \"1\": \"POSITIVE\"\n",
1322 | " },\n",
1323 | " \"init_std\": 0.02,\n",
1324 | " \"is_encoder_decoder\": true,\n",
1325 | " \"label2id\": {\n",
1326 | " \"NEGATIVE\": 0,\n",
1327 | " \"POSITIVE\": 1\n",
1328 | " },\n",
1329 | " \"max_position_embeddings\": 1026,\n",
1330 | " \"model_type\": \"bart\",\n",
1331 | " \"normalize_before\": false,\n",
1332 | " \"normalize_embedding\": true,\n",
1333 | " \"num_hidden_layers\": 6,\n",
1334 | " \"pad_token_id\": 3,\n",
1335 | " \"scale_embedding\": false,\n",
1336 | " \"static_position_embeddings\": false,\n",
1337 | " \"transformers_version\": \"4.17.0\",\n",
1338 | " \"use_cache\": true,\n",
1339 | " \"vocab_size\": 30000\n",
1340 | "}\n",
1341 | "\n",
1342 | "The tokenizer class you load from this checkpoint is not the same type as the class this function is called from. It may result in unexpected tokenization. \n",
1343 | "The tokenizer class you load from this checkpoint is 'BartTokenizer'. \n",
1344 | "The class this function is called from is 'PreTrainedTokenizerFast'.\n",
1345 | "loading configuration file https://huggingface.co/gogamza/kobart-summarization/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/1c32baaf6a1067a5e27a0dfbac0a3d23a86d958ab10b092d5ea4150bd451de17.4e52ef6c87e6938c92ba0d19888607d76e30e950e81060a8fa6cb1189c93614d\n",
1346 | "Model config BartConfig {\n",
1347 | " \"activation_dropout\": 0.0,\n",
1348 | " \"activation_function\": \"gelu\",\n",
1349 | " \"add_bias_logits\": false,\n",
1350 | " \"add_final_layer_norm\": false,\n",
1351 | " \"architectures\": [\n",
1352 | " \"BartForConditionalGeneration\"\n",
1353 | " ],\n",
1354 | " \"attention_dropout\": 0.0,\n",
1355 | " \"author\": \"Heewon Jeon(madjakarta@gmail.com)\",\n",
1356 | " \"bos_token_id\": 0,\n",
1357 | " \"classif_dropout\": 0.1,\n",
1358 | " \"classifier_dropout\": 0.1,\n",
1359 | " \"d_model\": 768,\n",
1360 | " \"decoder_attention_heads\": 16,\n",
1361 | " \"decoder_ffn_dim\": 3072,\n",
1362 | " \"decoder_layerdrop\": 0.0,\n",
1363 | " \"decoder_layers\": 6,\n",
1364 | " \"decoder_start_token_id\": 2,\n",
1365 | " \"do_blenderbot_90_layernorm\": false,\n",
1366 | " \"dropout\": 0.1,\n",
1367 | " \"encoder_attention_heads\": 16,\n",
1368 | " \"encoder_ffn_dim\": 3072,\n",
1369 | " \"encoder_layerdrop\": 0.0,\n",
1370 | " \"encoder_layers\": 6,\n",
1371 | " \"eos_token_id\": 1,\n",
1372 | " \"extra_pos_embeddings\": 2,\n",
1373 | " \"force_bos_token_to_be_generated\": false,\n",
1374 | " \"forced_eos_token_id\": 2,\n",
1375 | " \"id2label\": {\n",
1376 | " \"0\": \"NEGATIVE\",\n",
1377 | " \"1\": \"POSITIVE\"\n",
1378 | " },\n",
1379 | " \"init_std\": 0.02,\n",
1380 | " \"is_encoder_decoder\": true,\n",
1381 | " \"label2id\": {\n",
1382 | " \"NEGATIVE\": 0,\n",
1383 | " \"POSITIVE\": 1\n",
1384 | " },\n",
1385 | " \"max_position_embeddings\": 1026,\n",
1386 | " \"model_type\": \"bart\",\n",
1387 | " \"normalize_before\": false,\n",
1388 | " \"normalize_embedding\": true,\n",
1389 | " \"num_hidden_layers\": 6,\n",
1390 | " \"pad_token_id\": 3,\n",
1391 | " \"scale_embedding\": false,\n",
1392 | " \"static_position_embeddings\": false,\n",
1393 | " \"transformers_version\": \"4.17.0\",\n",
1394 | " \"use_cache\": true,\n",
1395 | " \"vocab_size\": 30000\n",
1396 | "}\n",
1397 | "\n",
1398 | "loading weights file https://huggingface.co/gogamza/kobart-summarization/resolve/main/pytorch_model.bin from cache at /root/.cache/huggingface/transformers/f30ba9ba60f377194e6a39913246c76f6dcac8158e399598ed56fec262103dba.b063b56b256aaf29f8c7c67e318ed78b83b9381147ac794d0df9ef0399066ea7\n",
1399 | "All model checkpoint weights were used when initializing BartForConditionalGeneration.\n",
1400 | "\n",
1401 | "All the weights of BartForConditionalGeneration were initialized from the model checkpoint at gogamza/kobart-summarization.\n",
1402 | "If your task is similar to the task the model of the checkpoint was trained on, you can already use BartForConditionalGeneration for predictions without further training.\n"
1403 | ]
1404 | }
1405 | ],
1406 | "source": [
1407 | "tokenizer = PreTrainedTokenizerFast.from_pretrained(model_name)\n",
1408 | "model = BartForConditionalGeneration.from_pretrained(model_name)"
1409 | ]
1410 | },
1411 | {
1412 | "cell_type": "code",
1413 | "execution_count": 73,
1414 | "metadata": {},
1415 | "outputs": [
1416 | {
1417 | "name": "stdout",
1418 | "output_type": "stream",
1419 | "text": [
1420 | "과거를 떠올려보자. 방송을 보던 우리의 모습을. 독보적인 매체는 TV였다. 온 가족이 둘러앉아 TV를 봤다. 간혹 가족들끼리 뉴스와 드라마, 예능 프로그램을 둘러싸고 리모컨 쟁탈전이 벌어지기도 했다. 각자 선호하는 프로그램을 '본방'으로 보기 위한 싸움이었다. TV가 한 대인지 두 대인지 여부도 그래서 중요했다. 지금은 어떤가. '안방극장'이라는 말은 옛말이 됐다. TV가 없는 집도 많다. 미디어의 혜택을 누릴 수 있는 방법은 늘어났다. 각자의 방에서 각자의 휴대폰으로, 노트북으로, 태블릿으로 콘텐츠를 즐긴다.\n"
1421 | ]
1422 | }
1423 | ],
1424 | "source": [
1425 | "text = \"과거를 떠올려보자. 방송을 보던 우리의 모습을. 독보적인 매체는 TV였다. 온 가족이 둘러앉아 TV를 봤다. 간혹 가족들끼리 뉴스와 드라마, 예능 프로그램을 둘러싸고 리모컨 쟁탈전이 벌어지기도 했다. 각자 선호하는 프로그램을 '본방'으로 보기 위한 싸움이었다. TV가 한 대인지 두 대인지 여부도 그래서 중요했다. 지금은 어떤가. '안방극장'이라는 말은 옛말이 됐다. TV가 없는 집도 많다. 미디어의 혜택을 누릴 수 있는 방법은 늘어났다. 각자의 방에서 각자의 휴대폰으로, 노트북으로, 태블릿으로 콘텐츠를 즐긴다.\"\n",
1426 | "print(text)"
1427 | ]
1428 | },
1429 | {
1430 | "cell_type": "code",
1431 | "execution_count": 74,
1432 | "metadata": {},
1433 | "outputs": [],
1434 | "source": [
1435 | "raw_input_ids = tokenizer.encode(text)\n",
1436 | "input_ids = [tokenizer.bos_token_id] + raw_input_ids + [tokenizer.eos_token_id]"
1437 | ]
1438 | },
1439 | {
1440 | "cell_type": "code",
1441 | "execution_count": 75,
1442 | "metadata": {},
1443 | "outputs": [],
1444 | "source": [
1445 | "summary_ids = model.generate(torch.tensor([input_ids]))"
1446 | ]
1447 | },
1448 | {
1449 | "cell_type": "code",
1450 | "execution_count": 76,
1451 | "metadata": {},
1452 | "outputs": [
1453 | {
1454 | "data": {
1455 | "text/plain": [
1456 | "'TV가 없는 집도 많고, TV가 없는 집도 많아진 만큼 미디어의 혜택을'"
1457 | ]
1458 | },
1459 | "execution_count": 76,
1460 | "metadata": {},
1461 | "output_type": "execute_result"
1462 | }
1463 | ],
1464 | "source": [
1465 | "tokenizer.decode(summary_ids.squeeze().tolist(), skip_special_tokens=True)"
1466 | ]
1467 | },
1468 | {
1469 | "cell_type": "code",
1470 | "execution_count": 77,
1471 | "metadata": {},
1472 | "outputs": [
1473 | {
1474 | "data": {
1475 | "text/plain": [
1476 | "tensor([[ 2, 16132, 8981, 14426, 14230, 9866, 14178, 14161, 16132, 8981,\n",
1477 | " 14426, 14230, 9866, 16664, 12335, 14933, 17166, 12024, 18477, 2]])"
1478 | ]
1479 | },
1480 | "execution_count": 77,
1481 | "metadata": {},
1482 | "output_type": "execute_result"
1483 | }
1484 | ],
1485 | "source": [
1486 | "summary_ids"
1487 | ]
1488 | },
1489 | {
1490 | "cell_type": "code",
1491 | "execution_count": 78,
1492 | "metadata": {},
1493 | "outputs": [
1494 | {
1495 | "data": {
1496 | "text/plain": [
1497 | "[0,\n",
1498 | " 15320,\n",
1499 | " 10443,\n",
1500 | " 17697,\n",
1501 | " 10313,\n",
1502 | " 10884,\n",
1503 | " 12060,\n",
1504 | " 245,\n",
1505 | " 21801,\n",
1506 | " 14046,\n",
1507 | " 9810,\n",
1508 | " 16433,\n",
1509 | " 15266,\n",
1510 | " 245,\n",
1511 | " 14373,\n",
1512 | " 10884,\n",
1513 | " 14134,\n",
1514 | " 14174,\n",
1515 | " 18610,\n",
1516 | " 16132,\n",
1517 | " 20029,\n",
1518 | " 14488,\n",
1519 | " 22795,\n",
1520 | " 16215,\n",
1521 | " 11700,\n",
1522 | " 11696,\n",
1523 | " 16132,\n",
1524 | " 10443,\n",
1525 | " 16786,\n",
1526 | " 14130,\n",
1527 | " 14313,\n",
1528 | " 13700,\n",
1529 | " 14978,\n",
1530 | " 9993,\n",
1531 | " 19769,\n",
1532 | " 15126,\n",
1533 | " 11863,\n",
1534 | " 15891,\n",
1535 | " 243,\n",
1536 | " 19517,\n",
1537 | " 17624,\n",
1538 | " 25749,\n",
1539 | " 14420,\n",
1540 | " 10607,\n",
1541 | " 12924,\n",
1542 | " 18787,\n",
1543 | " 13128,\n",
1544 | " 16984,\n",
1545 | " 16557,\n",
1546 | " 26499,\n",
1547 | " 19754,\n",
1548 | " 24252,\n",
1549 | " 26046,\n",
1550 | " 17624,\n",
1551 | " 14063,\n",
1552 | " 10888,\n",
1553 | " 10788,\n",
1554 | " 17075,\n",
1555 | " 17238,\n",
1556 | " 14353,\n",
1557 | " 20155,\n",
1558 | " 19249,\n",
1559 | " 16132,\n",
1560 | " 8981,\n",
1561 | " 14036,\n",
1562 | " 14029,\n",
1563 | " 15539,\n",
1564 | " 14196,\n",
1565 | " 14029,\n",
1566 | " 15539,\n",
1567 | " 20771,\n",
1568 | " 9866,\n",
1569 | " 14955,\n",
1570 | " 14610,\n",
1571 | " 15615,\n",
1572 | " 17444,\n",
1573 | " 14593,\n",
1574 | " 8981,\n",
1575 | " 245,\n",
1576 | " 26907,\n",
1577 | " 10788,\n",
1578 | " 29540,\n",
1579 | " 17164,\n",
1580 | " 18220,\n",
1581 | " 16565,\n",
1582 | " 25649,\n",
1583 | " 15097,\n",
1584 | " 14130,\n",
1585 | " 16132,\n",
1586 | " 8981,\n",
1587 | " 14426,\n",
1588 | " 14230,\n",
1589 | " 9866,\n",
1590 | " 14178,\n",
1591 | " 14130,\n",
1592 | " 17166,\n",
1593 | " 12024,\n",
1594 | " 18477,\n",
1595 | " 25689,\n",
1596 | " 14032,\n",
1597 | " 14082,\n",
1598 | " 20913,\n",
1599 | " 29553,\n",
1600 | " 14130,\n",
1601 | " 26667,\n",
1602 | " 14110,\n",
1603 | " 14030,\n",
1604 | " 26667,\n",
1605 | " 19594,\n",
1606 | " 16077,\n",
1607 | " 27476,\n",
1608 | " 16077,\n",
1609 | " 21980,\n",
1610 | " 14027,\n",
1611 | " 23786,\n",
1612 | " 14999,\n",
1613 | " 9267,\n",
1614 | " 14130,\n",
1615 | " 1]"
1616 | ]
1617 | },
1618 | "execution_count": 78,
1619 | "metadata": {},
1620 | "output_type": "execute_result"
1621 | }
1622 | ],
1623 | "source": [
1624 | "input_ids"
1625 | ]
1626 | },
1627 | {
1628 | "cell_type": "code",
1629 | "execution_count": null,
1630 | "metadata": {},
1631 | "outputs": [],
1632 | "source": []
1633 | }
1634 | ],
1635 | "metadata": {
1636 | "kernelspec": {
1637 | "display_name": "Python 3",
1638 | "language": "python",
1639 | "name": "python3"
1640 | },
1641 | "language_info": {
1642 | "codemirror_mode": {
1643 | "name": "ipython",
1644 | "version": 3
1645 | },
1646 | "file_extension": ".py",
1647 | "mimetype": "text/x-python",
1648 | "name": "python",
1649 | "nbconvert_exporter": "python",
1650 | "pygments_lexer": "ipython3",
1651 | "version": "3.6.9"
1652 | }
1653 | },
1654 | "nbformat": 4,
1655 | "nbformat_minor": 2
1656 | }
1657 |
--------------------------------------------------------------------------------
/codes/9-3_BERT라이브러리탐색.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 2,
6 | "id": "1a5da9b8",
7 | "metadata": {},
8 | "outputs": [
9 | {
10 | "name": "stdout",
11 | "output_type": "stream",
12 | "text": [
13 | "Collecting ktrain\n",
14 | " Downloading ktrain-0.29.3.tar.gz (25.3 MB)\n",
15 | " --------------------------------------- 25.3/25.3 MB 59.9 MB/s eta 0:00:00\n",
16 | " Preparing metadata (setup.py): started\n",
17 | " Preparing metadata (setup.py): finished with status 'done'\n",
18 | "Collecting scikit-learn==0.24.2\n",
19 | " Downloading scikit_learn-0.24.2-cp38-cp38-win_amd64.whl (6.9 MB)\n",
20 | " ---------------------------------------- 6.9/6.9 MB 73.3 MB/s eta 0:00:00\n",
21 | "Requirement already satisfied: matplotlib>=3.0.0 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (3.3.4)\n",
22 | "Requirement already satisfied: pandas>=1.0.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (1.2.4)\n",
23 | "Collecting fastprogress>=0.1.21\n",
24 | " Downloading fastprogress-1.0.2-py3-none-any.whl (12 kB)\n",
25 | "Requirement already satisfied: requests in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (2.25.1)\n",
26 | "Requirement already satisfied: joblib in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (1.0.1)\n",
27 | "Requirement already satisfied: packaging in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (20.9)\n",
28 | "Collecting langdetect\n",
29 | " Downloading langdetect-1.0.9.tar.gz (981 kB)\n",
30 | " ---------------------------------------- 981.5/981.5 KB ? eta 0:00:00\n",
31 | " Preparing metadata (setup.py): started\n",
32 | " Preparing metadata (setup.py): finished with status 'done'\n",
33 | "Collecting jieba\n",
34 | " Downloading jieba-0.42.1.tar.gz (19.2 MB)\n",
35 | " --------------------------------------- 19.2/19.2 MB 73.1 MB/s eta 0:00:00\n",
36 | " Preparing metadata (setup.py): started\n",
37 | " Preparing metadata (setup.py): finished with status 'done'\n",
38 | "Collecting cchardet\n",
39 | " Downloading cchardet-2.1.7-cp38-cp38-win_amd64.whl (115 kB)\n",
40 | " -------------------------------------- 115.2/115.2 KB 6.6 MB/s eta 0:00:00\n",
41 | "Requirement already satisfied: chardet in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from ktrain) (4.0.0)\n",
42 | "Collecting syntok==1.3.3\n",
43 | " Downloading syntok-1.3.3-py3-none-any.whl (22 kB)\n",
44 | "Collecting seqeval==0.0.19\n",
45 | " Downloading seqeval-0.0.19.tar.gz (30 kB)\n",
46 | " Preparing metadata (setup.py): started\n",
47 | " Preparing metadata (setup.py): finished with status 'done'\n",
48 | "Collecting transformers==4.10.3\n",
49 | " Downloading transformers-4.10.3-py3-none-any.whl (2.8 MB)\n",
50 | " ---------------------------------------- 2.8/2.8 MB 88.8 MB/s eta 0:00:00\n",
51 | "Collecting sentencepiece\n",
52 | " Downloading sentencepiece-0.1.96-cp38-cp38-win_amd64.whl (1.1 MB)\n",
53 | " ---------------------------------------- 1.1/1.1 MB 67.6 MB/s eta 0:00:00\n",
54 | "Collecting keras_bert>=0.86.0\n",
55 | " Downloading keras-bert-0.89.0.tar.gz (25 kB)\n",
56 | " Preparing metadata (setup.py): started\n",
57 | " Preparing metadata (setup.py): finished with status 'done'\n",
58 | "Collecting whoosh\n",
59 | " Downloading Whoosh-2.7.4-py2.py3-none-any.whl (468 kB)\n",
60 | " ------------------------------------- 468.8/468.8 KB 30.6 MB/s eta 0:00:00\n",
61 | "Requirement already satisfied: threadpoolctl>=2.0.0 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from scikit-learn==0.24.2->ktrain) (2.1.0)\n",
62 | "Requirement already satisfied: numpy>=1.13.3 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from scikit-learn==0.24.2->ktrain) (1.20.1)\n",
63 | "Requirement already satisfied: scipy>=0.19.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from scikit-learn==0.24.2->ktrain) (1.6.2)\n",
64 | "Requirement already satisfied: Keras>=2.2.4 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from seqeval==0.0.19->ktrain) (2.7.0)\n",
65 | "Requirement already satisfied: regex in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from syntok==1.3.3->ktrain) (2021.4.4)\n",
66 | "Requirement already satisfied: pyyaml>=5.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from transformers==4.10.3->ktrain) (5.4.1)\n",
67 | "Requirement already satisfied: filelock in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from transformers==4.10.3->ktrain) (3.0.12)\n",
68 | "Collecting tokenizers<0.11,>=0.10.1\n",
69 | " Downloading tokenizers-0.10.3-cp38-cp38-win_amd64.whl (2.0 MB)\n",
70 | " ---------------------------------------- 2.0/2.0 MB 64.1 MB/s eta 0:00:00\n",
71 | "Requirement already satisfied: huggingface-hub>=0.0.12 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from transformers==4.10.3->ktrain) (0.4.0)\n",
72 | "Requirement already satisfied: sacremoses in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from transformers==4.10.3->ktrain) (0.0.47)\n",
73 | "Requirement already satisfied: tqdm>=4.27 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from transformers==4.10.3->ktrain) (4.59.0)\n",
74 | "Collecting keras-transformer==0.40.0\n",
75 | " Downloading keras-transformer-0.40.0.tar.gz (9.7 kB)\n",
76 | " Preparing metadata (setup.py): started\n",
77 | " Preparing metadata (setup.py): finished with status 'done'\n",
78 | "Collecting keras-pos-embd==0.13.0\n",
79 | " Downloading keras-pos-embd-0.13.0.tar.gz (5.6 kB)\n",
80 | " Preparing metadata (setup.py): started\n",
81 | " Preparing metadata (setup.py): finished with status 'done'\n",
82 | "Collecting keras-multi-head==0.29.0\n",
83 | " Downloading keras-multi-head-0.29.0.tar.gz (13 kB)\n",
84 | " Preparing metadata (setup.py): started\n",
85 | " Preparing metadata (setup.py): finished with status 'done'\n",
86 | "Collecting keras-layer-normalization==0.16.0\n",
87 | " Downloading keras-layer-normalization-0.16.0.tar.gz (3.9 kB)\n",
88 | " Preparing metadata (setup.py): started\n",
89 | " Preparing metadata (setup.py): finished with status 'done'\n",
90 | "Collecting keras-position-wise-feed-forward==0.8.0\n",
91 | " Downloading keras-position-wise-feed-forward-0.8.0.tar.gz (4.1 kB)\n",
92 | " Preparing metadata (setup.py): started\n",
93 | " Preparing metadata (setup.py): finished with status 'done'\n",
94 | "Collecting keras-embed-sim==0.10.0\n",
95 | " Downloading keras-embed-sim-0.10.0.tar.gz (3.6 kB)\n",
96 | " Preparing metadata (setup.py): started\n",
97 | " Preparing metadata (setup.py): finished with status 'done'\n",
98 | "Collecting keras-self-attention==0.51.0\n",
99 | " Downloading keras-self-attention-0.51.0.tar.gz (11 kB)\n",
100 | " Preparing metadata (setup.py): started\n",
101 | " Preparing metadata (setup.py): finished with status 'done'\n",
102 | "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from matplotlib>=3.0.0->ktrain) (2.4.7)\n",
103 | "Requirement already satisfied: kiwisolver>=1.0.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from matplotlib>=3.0.0->ktrain) (1.3.1)\n",
104 | "Requirement already satisfied: pillow>=6.2.0 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from matplotlib>=3.0.0->ktrain) (8.2.0)\n",
105 | "Requirement already satisfied: python-dateutil>=2.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from matplotlib>=3.0.0->ktrain) (2.8.1)\n",
106 | "Requirement already satisfied: cycler>=0.10 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from matplotlib>=3.0.0->ktrain) (0.10.0)\n",
107 | "Requirement already satisfied: pytz>=2017.3 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from pandas>=1.0.1->ktrain) (2021.1)\n",
108 | "Requirement already satisfied: six in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from langdetect->ktrain) (1.15.0)\n",
109 | "Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from requests->ktrain) (1.26.4)\n",
110 | "Requirement already satisfied: idna<3,>=2.5 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from requests->ktrain) (2.10)\n",
111 | "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from requests->ktrain) (2020.12.5)\n",
112 | "Requirement already satisfied: typing-extensions>=3.7.4.3 in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from huggingface-hub>=0.0.12->transformers==4.10.3->ktrain) (3.7.4.3)\n",
113 | "Requirement already satisfied: click in c:\\users\\shyram\\anaconda3\\lib\\site-packages (from sacremoses->transformers==4.10.3->ktrain) (7.1.2)\n",
114 | "Building wheels for collected packages: ktrain, seqeval, keras_bert, keras-transformer, keras-embed-sim, keras-layer-normalization, keras-multi-head, keras-pos-embd, keras-position-wise-feed-forward, keras-self-attention, jieba, langdetect\n",
115 | " Building wheel for ktrain (setup.py): started\n",
116 | " Building wheel for ktrain (setup.py): finished with status 'done'\n",
117 | " Created wheel for ktrain: filename=ktrain-0.29.3-py3-none-any.whl size=25295401 sha256=1455f83b354cef5a321ad1f6b092c4a60df38cfc9958278fed03654b5d3ad991\n",
118 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\e4\\04\\35\\785e4d64090aa723d2731def6d883294c9e501d605330a34a2\n",
119 | " Building wheel for seqeval (setup.py): started\n",
120 | " Building wheel for seqeval (setup.py): finished with status 'done'\n",
121 | " Created wheel for seqeval: filename=seqeval-0.0.19-py3-none-any.whl size=9918 sha256=46a5f115cfbfbb78870a1cf01600f490346181296e507243b51fc3c7c94daa82\n",
122 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\58\\e5\\9e\\2f94312239a6753267da6ceafe12d614603b78d308676df5e2\n",
123 | " Building wheel for keras_bert (setup.py): started\n",
124 | " Building wheel for keras_bert (setup.py): finished with status 'done'\n",
125 | " Created wheel for keras_bert: filename=keras_bert-0.89.0-py3-none-any.whl size=33515 sha256=d6da838bbc2aff38bcd8f19bb7213e651f932924c14c9e3e5320cdb62e20f2b8\n",
126 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\a1\\34\\ed\\6bbd71716d7bcea30d75e8bc5aeb94f4cb52636295c8343534\n",
127 | " Building wheel for keras-transformer (setup.py): started\n",
128 | " Building wheel for keras-transformer (setup.py): finished with status 'done'\n",
129 | " Created wheel for keras-transformer: filename=keras_transformer-0.40.0-py3-none-any.whl size=12303 sha256=1ba99df7f26ee290aedbfe1b3ab73a846e6e570d0c4d220be1f0066f0a7dc1a5\n",
130 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\07\\cd\\a7\\a8fa93f7e177eee0101fed63179f7a2fa3b53671ffaad82bfd\n",
131 | " Building wheel for keras-embed-sim (setup.py): started\n",
132 | " Building wheel for keras-embed-sim (setup.py): finished with status 'done'\n",
133 | " Created wheel for keras-embed-sim: filename=keras_embed_sim-0.10.0-py3-none-any.whl size=3959 sha256=b288a68a6096c921b925bdb1ac95654e6ee5eaf06b08853f4f13c5985681a1af\n",
134 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\59\\bd\\9a\\ec6e575aaa50687d7af968bde7ce710b542eeaa9ee7978d4ba\n",
135 | " Building wheel for keras-layer-normalization (setup.py): started\n",
136 | " Building wheel for keras-layer-normalization (setup.py): finished with status 'done'\n",
137 | " Created wheel for keras-layer-normalization: filename=keras_layer_normalization-0.16.0-py3-none-any.whl size=4667 sha256=8c39da930aba3b73fd42154bf464369b33c5a43ac89e121967843b6d5c0489cc\n",
138 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\d7\\2b\\f4\\28f4bab995fa99c26b761bc7f9aeb5bf6c81e9be6ccd0b853b\n",
139 | " Building wheel for keras-multi-head (setup.py): started\n",
140 | " Building wheel for keras-multi-head (setup.py): finished with status 'done'\n",
141 | " Created wheel for keras-multi-head: filename=keras_multi_head-0.29.0-py3-none-any.whl size=14993 sha256=733a14b20ea503abca3d42af053e53322a610d53f337aef7561ec215de2e7a96\n",
142 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\91\\eb\\bc\\ce4bb467f5a7db6727f148f70bb0e52a62ef7edd41a19c8bdd\n",
143 | " Building wheel for keras-pos-embd (setup.py): started\n",
144 | " Building wheel for keras-pos-embd (setup.py): finished with status 'done'\n",
145 | " Created wheel for keras-pos-embd: filename=keras_pos_embd-0.13.0-py3-none-any.whl size=6960 sha256=7d3c1ad9cba1c0bf911fb49998e81e14144f957331c4eeee1d811a9eadca5d51\n",
146 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\91\\c4\\ff\\7e13e4f102c3b7d73ff075a50fe3266f3ec2de898d5493a8a2\n",
147 | " Building wheel for keras-position-wise-feed-forward (setup.py): started\n",
148 | " Building wheel for keras-position-wise-feed-forward (setup.py): finished with status 'done'\n",
149 | " Created wheel for keras-position-wise-feed-forward: filename=keras_position_wise_feed_forward-0.8.0-py3-none-any.whl size=4983 sha256=ff8f5f76b40c7133fabe33d5fe2e87b01de7b4b6d996b73213ad5242bffc3728\n",
150 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\f2\\15\\39\\59861ed531ef6c7c75810500eb22c68a425f82dde31d68630a\n",
151 | " Building wheel for keras-self-attention (setup.py): started\n",
152 | " Building wheel for keras-self-attention (setup.py): finished with status 'done'\n",
153 | " Created wheel for keras-self-attention: filename=keras_self_attention-0.51.0-py3-none-any.whl size=18911 sha256=5f59132d1aaa25f8bdcef54b3e0cd61f7033272bed4e0b56803049862ed43bd2\n",
154 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\ac\\13\\2d\\3de7c76f618a8d162884ac5b726a8c2242ad88afa370f1e62f\n",
155 | " Building wheel for jieba (setup.py): started\n",
156 | " Building wheel for jieba (setup.py): finished with status 'done'\n",
157 | " Created wheel for jieba: filename=jieba-0.42.1-py3-none-any.whl size=19314477 sha256=570f36b42086fdc59069025941a9e507a31bbd3917768d4dd9e19a16174d6999\n",
158 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\ca\\38\\d8\\dfdfe73bec1d12026b30cb7ce8da650f3f0ea2cf155ea018ae\n",
159 | " Building wheel for langdetect (setup.py): started\n",
160 | " Building wheel for langdetect (setup.py): finished with status 'done'\n",
161 | " Created wheel for langdetect: filename=langdetect-1.0.9-py3-none-any.whl size=993221 sha256=db8f735b45488281b98f2cf3550940234dc195d8acc581c99cb67594467b91cf\n",
162 | " Stored in directory: c:\\users\\shyram\\appdata\\local\\pip\\cache\\wheels\\13\\c7\\b0\\79f66658626032e78fc1a83103690ef6797d551cb22e56e734\n",
163 | "Successfully built ktrain seqeval keras_bert keras-transformer keras-embed-sim keras-layer-normalization keras-multi-head keras-pos-embd keras-position-wise-feed-forward keras-self-attention jieba langdetect\n",
164 | "Installing collected packages: whoosh, tokenizers, sentencepiece, jieba, cchardet, syntok, seqeval, langdetect, keras-self-attention, keras-position-wise-feed-forward, keras-pos-embd, keras-layer-normalization, keras-embed-sim, fastprogress, scikit-learn, keras-multi-head, transformers, keras-transformer, keras_bert, ktrain\n",
165 | " Attempting uninstall: tokenizers\n",
166 | " Found existing installation: tokenizers 0.11.4\n",
167 | " Uninstalling tokenizers-0.11.4:\n",
168 | " Successfully uninstalled tokenizers-0.11.4\n",
169 | " Attempting uninstall: scikit-learn\n",
170 | " Found existing installation: scikit-learn 0.24.1\n",
171 | " Uninstalling scikit-learn-0.24.1:\n",
172 | " Successfully uninstalled scikit-learn-0.24.1\n",
173 | " Attempting uninstall: transformers\n",
174 | " Found existing installation: transformers 4.16.2\n",
175 | " Uninstalling transformers-4.16.2:\n",
176 | " Successfully uninstalled transformers-4.16.2\n",
177 | "Successfully installed cchardet-2.1.7 fastprogress-1.0.2 jieba-0.42.1 keras-embed-sim-0.10.0 keras-layer-normalization-0.16.0 keras-multi-head-0.29.0 keras-pos-embd-0.13.0 keras-position-wise-feed-forward-0.8.0 keras-self-attention-0.51.0 keras-transformer-0.40.0 keras_bert-0.89.0 ktrain-0.29.3 langdetect-1.0.9 scikit-learn-0.24.2 sentencepiece-0.1.96 seqeval-0.0.19 syntok-1.3.3 tokenizers-0.10.3 transformers-4.10.3 whoosh-2.7.4\n"
178 | ]
179 | },
180 | {
181 | "name": "stderr",
182 | "output_type": "stream",
183 | "text": [
184 | "WARNING: You are using pip version 22.0.3; however, version 22.0.4 is available.\n",
185 | "You should consider upgrading via the 'c:\\users\\shyram\\anaconda3\\python.exe -m pip install --upgrade pip' command.\n"
186 | ]
187 | }
188 | ],
189 | "source": [
190 | "!pip install ktrain"
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": 3,
196 | "id": "05ec235f",
197 | "metadata": {},
198 | "outputs": [],
199 | "source": [
200 | "import ktrain\n",
201 | "from ktrain import text\n",
202 | "import pandas as pd"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "id": "bb769e60",
208 | "metadata": {},
209 | "source": [
210 | "**json 파일 다운로드** \n",
211 | "https://drive.google.com/uc?id=1-8urBLVtFuuvAVHi0s000e7r0KPUgt9f"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": 6,
217 | "id": "687bb64b",
218 | "metadata": {},
219 | "outputs": [
220 | {
221 | "data": {
222 | "text/html": [
223 | "\n",
224 | "\n",
237 | "
\n",
238 | " \n",
239 | " \n",
240 | " | \n",
241 | " reviewerID | \n",
242 | " asin | \n",
243 | " reviewerName | \n",
244 | " helpful | \n",
245 | " reviewText | \n",
246 | " overall | \n",
247 | " summary | \n",
248 | " unixReviewTime | \n",
249 | " reviewTime | \n",
250 | "
\n",
251 | " \n",
252 | " \n",
253 | " \n",
254 | " 0 | \n",
255 | " A3EBHHCZO6V2A4 | \n",
256 | " 5555991584 | \n",
257 | " Amaranth \"music fan\" | \n",
258 | " [3, 3] | \n",
259 | " It's hard to believe \"Memory of Trees\" came ou... | \n",
260 | " 5 | \n",
261 | " Enya's last great album | \n",
262 | " 1158019200 | \n",
263 | " 09 12, 2006 | \n",
264 | "
\n",
265 | " \n",
266 | " 1 | \n",
267 | " AZPWAXJG9OJXV | \n",
268 | " 5555991584 | \n",
269 | " bethtexas | \n",
270 | " [0, 0] | \n",
271 | " A clasically-styled and introverted album, Mem... | \n",
272 | " 5 | \n",
273 | " Enya at her most elegant | \n",
274 | " 991526400 | \n",
275 | " 06 3, 2001 | \n",
276 | "
\n",
277 | " \n",
278 | " 2 | \n",
279 | " A38IRL0X2T4DPF | \n",
280 | " 5555991584 | \n",
281 | " bob turnley | \n",
282 | " [2, 2] | \n",
283 | " I never thought Enya would reach the sublime h... | \n",
284 | " 5 | \n",
285 | " The best so far | \n",
286 | " 1058140800 | \n",
287 | " 07 14, 2003 | \n",
288 | "
\n",
289 | " \n",
290 | " 3 | \n",
291 | " A22IK3I6U76GX0 | \n",
292 | " 5555991584 | \n",
293 | " Calle | \n",
294 | " [1, 1] | \n",
295 | " This is the third review of an irish album I w... | \n",
296 | " 5 | \n",
297 | " Ireland produces good music. | \n",
298 | " 957312000 | \n",
299 | " 05 3, 2000 | \n",
300 | "
\n",
301 | " \n",
302 | " 4 | \n",
303 | " A1AISPOIIHTHXX | \n",
304 | " 5555991584 | \n",
305 | " Cloud \"...\" | \n",
306 | " [1, 1] | \n",
307 | " Enya, despite being a successful recording art... | \n",
308 | " 4 | \n",
309 | " 4.5; music to dream to | \n",
310 | " 1200528000 | \n",
311 | " 01 17, 2008 | \n",
312 | "
\n",
313 | " \n",
314 | "
\n",
315 | "
"
316 | ],
317 | "text/plain": [
318 | " reviewerID asin reviewerName helpful \\\n",
319 | "0 A3EBHHCZO6V2A4 5555991584 Amaranth \"music fan\" [3, 3] \n",
320 | "1 AZPWAXJG9OJXV 5555991584 bethtexas [0, 0] \n",
321 | "2 A38IRL0X2T4DPF 5555991584 bob turnley [2, 2] \n",
322 | "3 A22IK3I6U76GX0 5555991584 Calle [1, 1] \n",
323 | "4 A1AISPOIIHTHXX 5555991584 Cloud \"...\" [1, 1] \n",
324 | "\n",
325 | " reviewText overall \\\n",
326 | "0 It's hard to believe \"Memory of Trees\" came ou... 5 \n",
327 | "1 A clasically-styled and introverted album, Mem... 5 \n",
328 | "2 I never thought Enya would reach the sublime h... 5 \n",
329 | "3 This is the third review of an irish album I w... 5 \n",
330 | "4 Enya, despite being a successful recording art... 4 \n",
331 | "\n",
332 | " summary unixReviewTime reviewTime \n",
333 | "0 Enya's last great album 1158019200 09 12, 2006 \n",
334 | "1 Enya at her most elegant 991526400 06 3, 2001 \n",
335 | "2 The best so far 1058140800 07 14, 2003 \n",
336 | "3 Ireland produces good music. 957312000 05 3, 2000 \n",
337 | "4 4.5; music to dream to 1200528000 01 17, 2008 "
338 | ]
339 | },
340 | "execution_count": 6,
341 | "metadata": {},
342 | "output_type": "execute_result"
343 | }
344 | ],
345 | "source": [
346 | "df = pd.read_json(r'reviews_Digital_Music_5.json',lines=True)\n",
347 | "df.head()"
348 | ]
349 | },
350 | {
351 | "cell_type": "code",
352 | "execution_count": 7,
353 | "id": "891bd472",
354 | "metadata": {},
355 | "outputs": [
356 | {
357 | "data": {
358 | "text/html": [
359 | "\n",
360 | "\n",
373 | "
\n",
374 | " \n",
375 | " \n",
376 | " | \n",
377 | " reviewText | \n",
378 | " overall | \n",
379 | "
\n",
380 | " \n",
381 | " \n",
382 | " \n",
383 | " 0 | \n",
384 | " It's hard to believe \"Memory of Trees\" came ou... | \n",
385 | " 5 | \n",
386 | "
\n",
387 | " \n",
388 | " 1 | \n",
389 | " A clasically-styled and introverted album, Mem... | \n",
390 | " 5 | \n",
391 | "
\n",
392 | " \n",
393 | " 2 | \n",
394 | " I never thought Enya would reach the sublime h... | \n",
395 | " 5 | \n",
396 | "
\n",
397 | " \n",
398 | " 3 | \n",
399 | " This is the third review of an irish album I w... | \n",
400 | " 5 | \n",
401 | "
\n",
402 | " \n",
403 | " 4 | \n",
404 | " Enya, despite being a successful recording art... | \n",
405 | " 4 | \n",
406 | "
\n",
407 | " \n",
408 | "
\n",
409 | "
"
410 | ],
411 | "text/plain": [
412 | " reviewText overall\n",
413 | "0 It's hard to believe \"Memory of Trees\" came ou... 5\n",
414 | "1 A clasically-styled and introverted album, Mem... 5\n",
415 | "2 I never thought Enya would reach the sublime h... 5\n",
416 | "3 This is the third review of an irish album I w... 5\n",
417 | "4 Enya, despite being a successful recording art... 4"
418 | ]
419 | },
420 | "execution_count": 7,
421 | "metadata": {},
422 | "output_type": "execute_result"
423 | }
424 | ],
425 | "source": [
426 | "df = df[['reviewText','overall']]\n",
427 | "df.head()"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 8,
433 | "id": "788cc587",
434 | "metadata": {},
435 | "outputs": [],
436 | "source": [
437 | "sentiment = {1:'negative',2:'negative',3:'negative', 4:'positive',5:'positive'}"
438 | ]
439 | },
440 | {
441 | "cell_type": "code",
442 | "execution_count": 10,
443 | "id": "c7a8f268",
444 | "metadata": {},
445 | "outputs": [
446 | {
447 | "data": {
448 | "text/html": [
449 | "\n",
450 | "\n",
463 | "
\n",
464 | " \n",
465 | " \n",
466 | " | \n",
467 | " reviewText | \n",
468 | " sentiment | \n",
469 | "
\n",
470 | " \n",
471 | " \n",
472 | " \n",
473 | " 0 | \n",
474 | " It's hard to believe \"Memory of Trees\" came ou... | \n",
475 | " positive | \n",
476 | "
\n",
477 | " \n",
478 | " 1 | \n",
479 | " A clasically-styled and introverted album, Mem... | \n",
480 | " positive | \n",
481 | "
\n",
482 | " \n",
483 | " 2 | \n",
484 | " I never thought Enya would reach the sublime h... | \n",
485 | " positive | \n",
486 | "
\n",
487 | " \n",
488 | " 3 | \n",
489 | " This is the third review of an irish album I w... | \n",
490 | " positive | \n",
491 | "
\n",
492 | " \n",
493 | " 4 | \n",
494 | " Enya, despite being a successful recording art... | \n",
495 | " positive | \n",
496 | "
\n",
497 | " \n",
498 | "
\n",
499 | "
"
500 | ],
501 | "text/plain": [
502 | " reviewText sentiment\n",
503 | "0 It's hard to believe \"Memory of Trees\" came ou... positive\n",
504 | "1 A clasically-styled and introverted album, Mem... positive\n",
505 | "2 I never thought Enya would reach the sublime h... positive\n",
506 | "3 This is the third review of an irish album I w... positive\n",
507 | "4 Enya, despite being a successful recording art... positive"
508 | ]
509 | },
510 | "execution_count": 10,
511 | "metadata": {},
512 | "output_type": "execute_result"
513 | }
514 | ],
515 | "source": [
516 | "df['sentiment'] = df['overall'].map(sentiment)\n",
517 | "df = df[['reviewText','sentiment']]\n",
518 | "df.head()"
519 | ]
520 | },
521 | {
522 | "cell_type": "code",
523 | "execution_count": 11,
524 | "id": "af390d43",
525 | "metadata": {},
526 | "outputs": [
527 | {
528 | "name": "stdout",
529 | "output_type": "stream",
530 | "text": [
531 | "['negative', 'positive']\n",
532 | " negative positive\n",
533 | "38430 0.0 1.0\n",
534 | "12842 0.0 1.0\n",
535 | "6965 0.0 1.0\n",
536 | "8671 0.0 1.0\n",
537 | "15755 0.0 1.0\n",
538 | "['negative', 'positive']\n",
539 | " negative positive\n",
540 | "50214 0.0 1.0\n",
541 | "53169 1.0 0.0\n",
542 | "4119 0.0 1.0\n",
543 | "37339 1.0 0.0\n",
544 | "23168 1.0 0.0\n",
545 | "downloading pretrained BERT model (uncased_L-12_H-768_A-12.zip)...\n",
546 | "[██████████████████████████████████████████████████]\n",
547 | "extracting pretrained BERT model...\n",
548 | "done.\n",
549 | "\n",
550 | "cleanup downloaded zip...\n",
551 | "done.\n",
552 | "\n",
553 | "preprocessing train...\n",
554 | "language: en\n"
555 | ]
556 | },
557 | {
558 | "data": {
559 | "text/html": [
560 | "\n",
561 | "\n"
573 | ],
574 | "text/plain": [
575 | ""
576 | ]
577 | },
578 | "metadata": {},
579 | "output_type": "display_data"
580 | },
581 | {
582 | "data": {
583 | "text/html": [
584 | "done."
585 | ],
586 | "text/plain": [
587 | ""
588 | ]
589 | },
590 | "metadata": {},
591 | "output_type": "display_data"
592 | },
593 | {
594 | "name": "stdout",
595 | "output_type": "stream",
596 | "text": [
597 | "Is Multi-Label? False\n",
598 | "preprocessing test...\n",
599 | "language: en\n"
600 | ]
601 | },
602 | {
603 | "data": {
604 | "text/html": [
605 | "\n",
606 | "\n"
618 | ],
619 | "text/plain": [
620 | ""
621 | ]
622 | },
623 | "metadata": {},
624 | "output_type": "display_data"
625 | },
626 | {
627 | "data": {
628 | "text/html": [
629 | "done."
630 | ],
631 | "text/plain": [
632 | ""
633 | ]
634 | },
635 | "metadata": {},
636 | "output_type": "display_data"
637 | }
638 | ],
639 | "source": [
640 | "(x_train, y_train), (x_test, y_test), preproc = text.texts_from_df(train_df = df, \n",
641 | " text_column = 'reviewText',\n",
642 | " label_columns=['sentiment'],\n",
643 | " maxlen=100, \n",
644 | " max_features=100000,\n",
645 | " preprocess_mode='bert',\n",
646 | " val_pct=0.1)"
647 | ]
648 | },
649 | {
650 | "cell_type": "code",
651 | "execution_count": 12,
652 | "id": "326a5ff1",
653 | "metadata": {},
654 | "outputs": [
655 | {
656 | "name": "stdout",
657 | "output_type": "stream",
658 | "text": [
659 | "Is Multi-Label? False\n",
660 | "maxlen is 100\n",
661 | "done.\n"
662 | ]
663 | }
664 | ],
665 | "source": [
666 | "model = text.text_classifier(name='bert', train_data = (x_train, y_train) , preproc=preproc, metrics=['accuracy'])"
667 | ]
668 | },
669 | {
670 | "cell_type": "code",
671 | "execution_count": 13,
672 | "id": "1353ad53",
673 | "metadata": {},
674 | "outputs": [],
675 | "source": [
676 | "learner = ktrain.get_learner(model = model, \n",
677 | " train_data=(x_train, y_train), \n",
678 | " val_data=(x_test, y_test), \n",
679 | " batch_size=32, \n",
680 | " use_multiprocessing = True)"
681 | ]
682 | },
683 | {
684 | "cell_type": "code",
685 | "execution_count": 14,
686 | "id": "12f9673b",
687 | "metadata": {},
688 | "outputs": [
689 | {
690 | "name": "stdout",
691 | "output_type": "stream",
692 | "text": [
693 | "\n",
694 | "\n",
695 | "begin training using onecycle policy with max lr of 2e-05...\n",
696 | "1820/1820 [==============================] - 368s 196ms/step - loss: 0.3300 - accuracy: 0.8638 - val_loss: 0.2699 - val_accuracy: 0.8873\n"
697 | ]
698 | },
699 | {
700 | "data": {
701 | "text/plain": [
702 | ""
703 | ]
704 | },
705 | "execution_count": 14,
706 | "metadata": {},
707 | "output_type": "execute_result"
708 | }
709 | ],
710 | "source": [
711 | "learner.fit_onecycle(lr=2e-5, epochs=1,checkpoint_folder='output')"
712 | ]
713 | },
714 | {
715 | "cell_type": "code",
716 | "execution_count": 15,
717 | "id": "b9ba019d",
718 | "metadata": {},
719 | "outputs": [],
720 | "source": [
721 | "predictor = ktrain.get_predictor(learner.model, preproc)"
722 | ]
723 | },
724 | {
725 | "cell_type": "code",
726 | "execution_count": 16,
727 | "id": "c562869f",
728 | "metadata": {},
729 | "outputs": [
730 | {
731 | "data": {
732 | "text/plain": [
733 | "'positive'"
734 | ]
735 | },
736 | "execution_count": 16,
737 | "metadata": {},
738 | "output_type": "execute_result"
739 | }
740 | ],
741 | "source": [
742 | "predictor.predict('I loved the song')"
743 | ]
744 | },
745 | {
746 | "cell_type": "code",
747 | "execution_count": 17,
748 | "id": "624fdd88",
749 | "metadata": {},
750 | "outputs": [
751 | {
752 | "data": {
753 | "text/plain": [
754 | "'negative'"
755 | ]
756 | },
757 | "execution_count": 17,
758 | "metadata": {},
759 | "output_type": "execute_result"
760 | }
761 | ],
762 | "source": [
763 | "predictor.predict('I hated the song')"
764 | ]
765 | }
766 | ],
767 | "metadata": {
768 | "kernelspec": {
769 | "display_name": "Python 3",
770 | "language": "python",
771 | "name": "python3"
772 | },
773 | "language_info": {
774 | "codemirror_mode": {
775 | "name": "ipython",
776 | "version": 3
777 | },
778 | "file_extension": ".py",
779 | "mimetype": "text/x-python",
780 | "name": "python",
781 | "nbconvert_exporter": "python",
782 | "pygments_lexer": "ipython3",
783 | "version": "3.8.8"
784 | }
785 | },
786 | "nbformat": 4,
787 | "nbformat_minor": 5
788 | }
789 |
--------------------------------------------------------------------------------
/images/chap1_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap1_1.png
--------------------------------------------------------------------------------
/images/chap1_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap1_2.png
--------------------------------------------------------------------------------
/images/chap5_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap5_1.png
--------------------------------------------------------------------------------
/images/chap8_probability-of-readmission1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap8_probability-of-readmission1.png
--------------------------------------------------------------------------------
/images/chap8_probability-of-readmission2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap8_probability-of-readmission2.png
--------------------------------------------------------------------------------
/images/chap9_multi-modal-transformer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap9_multi-modal-transformer.png
--------------------------------------------------------------------------------
/images/chap9_table1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap9_table1.png
--------------------------------------------------------------------------------
/images/chap9_videobert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chap9_videobert.png
--------------------------------------------------------------------------------
/images/chapter9_BART_architecture.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chapter9_BART_architecture.PNG
--------------------------------------------------------------------------------
/images/chapter9_BART_comparison.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chapter9_BART_comparison.PNG
--------------------------------------------------------------------------------
/images/chapter9_BART_fine-tuning.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chapter9_BART_fine-tuning.PNG
--------------------------------------------------------------------------------
/images/chapter9_BART_noising.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/images/chapter9_BART_noising.PNG
--------------------------------------------------------------------------------
/order.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "Untitled39.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": []
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "code",
21 | "execution_count": 1,
22 | "metadata": {
23 | "colab": {
24 | "base_uri": "https://localhost:8080/"
25 | },
26 | "id": "usDEk0aB07RL",
27 | "outputId": "6066923a-ebf7-49d6-fc8c-27263fd3ea86"
28 | },
29 | "outputs": [
30 | {
31 | "output_type": "stream",
32 | "name": "stdout",
33 | "text": [
34 | "['은식', '수연', '상일', '희', '은식', '은식', '수연', '상일', '희', '상일', '은식', '희', '수연', '은식', '상일', '수연', '희', '상일', '희', '은식', '수연']\n"
35 | ]
36 | },
37 | {
38 | "output_type": "execute_result",
39 | "data": {
40 | "text/plain": [
41 | "Counter({'상일': 5, '수연': 5, '은식': 6, '희': 5})"
42 | ]
43 | },
44 | "metadata": {},
45 | "execution_count": 1
46 | }
47 | ],
48 | "source": [
49 | "import random\n",
50 | "from collections import Counter\n",
51 | "\n",
52 | "random.seed(220112)\n",
53 | "\n",
54 | "names = ['수연', '상일', '희', '은식']\n",
55 | "orders = ['은식']\n",
56 | "\n",
57 | "random.shuffle(names[:2])\n",
58 | "orders += names\n",
59 | "\n",
60 | "while len(orders) < 21:\n",
61 | " random.shuffle(names)\n",
62 | " orders += names\n",
63 | "\n",
64 | "orders = orders[:21]\n",
65 | "print(orders)\n",
66 | "\n",
67 | "Counter(orders)"
68 | ]
69 | }
70 | ]
71 | }
--------------------------------------------------------------------------------
/summaries/chapter01/chapter01_eunsik.md:
--------------------------------------------------------------------------------
1 | # Chapter 1. 트랜스포머 입문
2 |
3 | ## Transformer?
4 |
5 | - RNN, LSTM의 long-term dependency 문제를 보완한 아키텍쳐.
6 | - Attention 사용 초기에는 RNN, LSTM 기반의 Seq2Seq + Attention 형태로 많이 사용했는데 Transformer는 Self-Attention만을 사용함.
7 | - **Encoder-Decoder** 구조.
8 | - Encoder: 입력 문장의 표현 방법을 학습
9 | - Decoder: 표현 방법을 입력받아 원하는 문장을 생성
10 |
11 |
12 |
13 | ## Encoder?
14 |
15 | - Transformer에서 Encoder는 여러 개를 쌓아서 사용
16 | - Multi-Head Attention과 Feed Forward
17 |
18 | ### Attention 복습
19 |
20 | [https://wikidocs.net/22893](https://wikidocs.net/22893)
21 |
22 | Attention(Q, K, V) = Attention value
23 |
24 | 1. Query에 대해서 모든 Key와의 유사도 계산
25 | 2. 유사도를 Key에 매핑된 Value에 반영
26 | 3. 적용된 Value를 모두 더하면 -> Attention value
27 |
28 | ### Self-Attention
29 |
30 | - 단어 그대로 Attention을 자기 자신에게 수행한다는 의미
31 | - Q=K=V=입력 문장의 모든 단어 벡터들
32 | - 입력 문장 내의 단어들끼리 유사도를 구함. 각 단어의 표현들은 문장 안에 있는 다른 모든 단어의 표현과 연결해 단어가 문장 내에서 갖는 의미를 이해
33 | - 특정 단어와 문장 내에 있는 모든 단어가 어떤 연관이 있는지를 이해하면 좀 더 좋은 표현을 학습하는데 도움이 됨.
34 | - 무작위 초기화 된 가중치 행렬 W^Q, W^K, W^V을 만들고 입력 행렬 X에 곱해서 Q, K, V를 생성. 가중치 행렬들은 학습 과정에서 업데이트 됨.
35 | - Q와 K의 내적을 구하고 sqrt(d_k)로 나누기 때문에 Scale-dot product attention이라고도 함.
36 | 1. 쿼리(Q) 행렬과 키(K^T) 행렬의 내적 연산을 수행
37 | - Q와 K^T간의 내적을 계산하면 **유사도**를 구할 수 있음
38 | - 문장의 각 단어가 다른 모든 단어와 얼마나 유사한지 파악하는데 도움을 줌
39 | 2. QK^T 행렬을 키 벡터 차원(sqrt(d_k))의 제곱근값으로 나누기
40 | - 안정적인 경사값을 얻을 수 있음
41 | 3. Softmax 함수로 Normalizing
42 | - 2번까지의 값은 unnormalized form
43 | - 행 별로 softmax
44 | - softmax 함수로 normalizing하면 전체 합이 1, 각각의 값은 0~1 사이. 확률값으로 이해가능
45 | - score matrix: 각각의 단어가 문장 전체의 단어와 얼마나 연관이 있는지 확률로 알 수 있음
46 | 4. Attention(Z) 행렬 구하기
47 | - Normalized Similarity * V
48 | - Similarity를 Value를 Weight sum!
49 |
50 | ### Multi-head Attention(MHA)
51 |
52 | Attention이 단어 의미 사이의 연관을 잘 찾는다면 좋은 결과가 나오지만, 그렇지 않는다면 문장의 의미가 잘못 해석될 수도 있음. MHA는 여러 개의 Attention을 사용하여 정확한 문장의 의미를 이해하는데 도움을 준다. 구체적인 방법으로는 MHA의 결과로 나온 각각의 Attention vector를 concat하고 새로운 가중치 행렬 W^0를 곱하는 방법을 사용한다. (Attention head의 최종 결과는 Attention head의 원래 크기이므로 크기를 줄이기 위해 W_0을 곱하는 것)
53 |
54 | → 옮긴이의 코멘트에는 “헤드를 여러 개 사용해 어텐션을 사용할 경우 단일 헤드를 사용하는 경우보다 오분류가 일어날 위험을 줄이는 것으로 해석할 수 있다.”라고 되어있는데, Attention 결과의 앙상블 개념으로 생각하면 좋을 것 같습니다.
55 |
56 | ### Positional Encoding
57 |
58 | RNN은 순차적으로 들어가지만 Transformer는 병렬로 들어가기 때문에 구조에서 오는 순서 정보가 없음. 이를 해결하기 위해서 부가적으로 Positional Encoding을 추가해 줌. 논문의 저자들은 다음의 식을 사용함.
59 |
60 |
61 |
62 | 위치 인코딩 P를 계산 + 임베딩 행렬 X
63 |
64 | ### Feed Forward Network(FFN)
65 |
66 | 2개의 Dense + ReLU activation function. Attention 행렬을 입력받아 Encoder 표현을 출력함.
67 |
68 | ### Add와 Norm
69 |
70 | - sublayer에서 MHA의 input과 output을 서로 연결
71 | - sublayer에서 FFN의 input과 output을 서로 연결
72 | - Layer Normalization + Residual Connection
73 | - Layer Normalization: 각 layer의 값이 크게 변화하는 것을 방지해 모델을 더 빠르게 학습할 수 있게 함
74 | - Residual Connection: Vision의 ResNet에서 보던 구조. Skip Connection이라고도 하는데 기존 학습 정보를 보존하고 추가적인 정보만 학습하기 때문에 학습이 쉬워지고, 수렴이 빨라진다. [참고](https://daeun-computer-uneasy.tistory.com/28)
75 |
76 | ## Decoder?
77 |
78 | - Encoder의 결과값을 가져와서 Decoder의 입력값으로 사용하여 타깃을 생성
79 | - Decoder는 **이전 Decoder의 출력**과 **Encoder의 출력**을 입력으로 사용함
80 | - \ + 문장 embedding → 첫 단어 생성
81 | - \ 첫 단어 + 문장 embedding → 첫 단어 두번째 단어 생성
82 | - \가 나올 때까지 반복
83 | - Decoder의 입력도 Positional Embedding을 더해서 사용
84 |
85 | ### Masked Multi-head Attention(Masked MHA)
86 |
87 | - Decoder에서는 앞에 \를 붙여서 input으로 넣으면, output으로 맨 뒤에 \를 붙여서 결과가 나옴
88 | - 한 단계 shifted된 문장을 출력
89 | - Self-attention은 각 단어의 의미를 이해하기 위해 각 단어와 전체 단어를 연결함.
90 | - Decoder에서는 이전 단계에서 생성한 단어까지만 들어감
91 | - 따라서 각 단어에서 아직 예측되지 않은 오른쪽은 볼 수 없다고 생각 → mask!
92 | - 똑같이 계산하되, softmax 함수에 넣기 전에 -∞으로 mask
93 |
94 | ### Multi-head Attention
95 |
96 | - Decoder의 MHA는 이전 sublayer의 출력(M)과, Encoder의 출력(R)을 입력으로 받음.
97 | - Encoder-Decoder attention layer: Encoder의 결과와 Decoder의 결과 사이의 상호작용이 일어나는 곳
98 | - 행렬 M으로 Q를 만들고, R로 K, V를 생성
99 | - 일반적으로 Q는 target 문장의 표현을 포함하기 때문에 M에서 가져옴
100 | - K, V는 입력 문장의 표현을 가져서 R을 참조
101 | - Q, K, V가 어디서 왔는지를 제외하면 다른 과정들은 Encoder의 MHA와 동일함.
102 |
103 | ### FFN, add, norm
104 |
105 | Encoder와 동일
106 |
107 | ### Linear, Softmax Layer
108 |
109 | - **REMIND: Decoder는 입력 단어들(\ + 지금까지 예측한 단어들)을 입력받아서 다음 단어를 예측**
110 | - Linear layer는 마지막 decoder의 최상위 output을 input으로 받아서 vocab 크기와 같은 logit을 출력
111 | - 이 logit을 softmax에 넣어주면 확률값으로 변환 가능
112 | - vocab에서 가장 큰 확률을 가지는 단어를 argmax로 찾아내면 → 그 단어가 예측된 다음 단어
113 |
114 | ## Transformer 학습
115 |
116 | - Decoder가 vocab에 대한 확률 분포를 예측하고 확률이 가장 큰 단어를 선택함
117 | - 실제 확률 분포와 모델이 예측하는 확률 분포의 차이를 줄여나가는 방법으로 학습
118 | - loss function으로 cross-entropy를 사용
119 | - optimizer는 Adam을 사용
120 | - overfitting을 막기 위해 각 sublayer의 output, embedding, positional encoding의 합을 구할 때 Dropout을 적용
121 |
122 | ## Summary
123 |
124 | - Self-attention은 단어를 좀 더 잘 이해하기 위해 주어진 문장의 모든 단어와 해당 단어를 연결
125 | - Query, Key, Value Matrix의 사용
126 | - Positional Encoding
127 | - Encoder - FFN, add, norm
128 | - Decoder - Masked MHA, Encoder-decoder attention, FFN
129 | - Encoder-Decoder가 결합한 상태에서 어떻게 작동하는지
130 |
131 | ## 연습문제
132 |
133 | 1. 셀프 어텐션의 전체 단계를 설명하라.
134 | 2. 스케일 닷 프로덕트 어텐션을 정의하라.
135 | 3. 쿼리, 키, 밸류 행렬은 어떻게 생성하는가?
136 | 4. 위치 인코딩이 필요한 이유는 무엇인가?
137 | 5. 디코더의 서브레이어에는 무엇이 있는가?
138 | 6. 디코더의 인코더-디코더 어텐션 레이어의 입력은 무엇인가?
139 |
140 | ## Reference
141 |
142 | - [Attention Is All You Need paper](https://arxiv.org/pdf/1706.03762.pdf)
143 | - [남수연님 발표자료](https://github.com/dsc-sookmyung/2021-DeepSleep-Paper-Review/blob/main/Week7/Attention%20Is%20All%20You%20Need.pdf)
144 | - [딥 러닝을 이용한 자연어처리 입문](https://wikidocs.net/31379)
145 |
--------------------------------------------------------------------------------
/summaries/chapter02/chapter02_BPE.md:
--------------------------------------------------------------------------------
1 | # Chapter 2.5 하위 단어 토큰화 알고리즘
2 |
3 |
4 |
5 | ## Tokenization
6 |
7 | 문장을 token sequence로 나누는 과정. 토큰화를 수행하는 프로그램을 토크나이저라고 한다.
8 |
9 |
10 |
11 | #### 단어 단위 토큰화
12 |
13 | - 단어(어절) 단위로 토큰화를 수행. 가장 단순한 방법으로는 공백으로 구분하는 방법이 있다
14 | - 어휘 집합(vocabulary)의 크기가 매우 커질 수 있음
15 | - "먹었다, 먹었는데, 먹었고..." 등 표현이 살짝만 바뀐 어휘를 집합에 포함시켜야 되기 때문
16 | - 학습된 토크나이저를 사용하여 집합의 크기가 커지는 것을 완화할 수 있음
17 | - "먹었다, 먹었는데, 먹었고..." -> {"먹었", "다", "는데", "고"}
18 |
19 |
20 |
21 | #### 문자 단위 토큰화
22 |
23 | - 문자 단위로 토큰화를 수행
24 | - 한글로 표현할 수 있는 글자는 모두 1만 1,172개이므로 알파벳, 숫자, 기호 등을 고려해도 15,000개 이내로 토큰화 수행 가능
25 | - 모든 문자를 vocab에 추가하므로 미등록 토큰 문제에서 자유롭다
26 |
27 | - 각 문자 토큰이 의미있는 단위가 되기 어렵다.
28 | - "어제" -> {"어", "제"} 로 토큰화가 수행되는데, "어"가 "어제"의 "어"인지, 어미 "어" 인지 알 수 없음
29 |
30 | - 문자 단위로 나누기 때문에 토큰 시퀀스의 길이가 길어진다
31 |
32 |
33 |
34 | #### 서브워드 단위 토큰화
35 |
36 | - 단어와 문자 단위 토큰화의 중간에 있는 형태
37 | - 어휘 집합 크기가 지나치게 커지지 않으면서
38 | - 미등록 토큰 문제를 피하고
39 | - 분석된 토큰 시퀀스가 너무 길어지지 않게 한다
40 |
41 | - 대표적으로 BPE 알고리즘이 이에 해당
42 |
43 |
44 |
45 |
46 |
47 | ## BPE: Byte Pair Encoding
48 |
49 | 1994년 제안된 정보 압축 알고리즘으로, 가장 많이 등장한 문자열을 병합해서 데이터를 압축하는 기법이다. 최근 자연어 처리 모델에 널리 쓰인다. 알고리즘의 순서는 간단하게 아래와 같이 요약할 수 있다.
50 |
51 | (1) 문자열을 글자 단위로 분리한다.
52 |
53 | (2) 모든 글자들을 vocab에 등록한다.
54 |
55 | (3) 모든 글자의 쌍(pair)이 등장하는 빈도를 측정한다.
56 |
57 | (4) 가장 빈도가 높은 쌍을 vocab에 등록하며, 모든 문자열들에서 해당 쌍을 하나의 문자열로 병합한다.
58 |
59 | (5) 처음에 정해놓은 횟수가 될 때까지 (3)과 (4)를 반복한다.
60 |
61 | 이렇게 토큰화된 vocab에 없는 단어가 있다면 unknown 토큰인 \로 대체한다.
62 |
63 |
64 |
65 | 아래와 같은 데이터가 있다고 가정하자.
66 |
67 | > aaabdaaabac
68 |
69 | BPE는 데이터에 등장한 글자 (a, b, c, d)를 초기 사전으로 구성하며, 사전에 등록된 글자들의 모든 쌍의 빈도를 확인하고, 가장 많이 나타난 쌍을 병합하여 사전에 추가한다. 가장 많이 나타난 쌍은 (aa) 이므로 이를 병합한다. 이를 Z로 표현한다.
70 |
71 | > **Z**abd**Z**abac
72 |
73 | 이 문자열을 한번 더 압축한다면, ab가 많이 나타났으니 (ab)를 병합할 수 있다. 이를 Y라고 표현한다.
74 |
75 | - 물론 (Za)를 병합할 수 있지만, (ab)와 같은 빈도수 2를 가지고 있으므로, 알파벳 순으로 앞선 (ab)를 병합하기로 선택했다. 이는 사용자가 조절할 수 있다.
76 |
77 | > Z**Y**dZ**Y**ac
78 |
79 | (ZY)가 가장 많은 빈도수를 가지고 있으므로 문자열을 한번 더 병합할 수 있다. 이를 X로 표현한다.
80 |
81 | > **X**d**X**ac
82 |
83 |
84 |
85 | **BPE 수행 전**
86 |
87 | - 사전을 통해 4개의 문자를 표현할 수 있다. (a, b, c, d)
88 |
89 | - 문자열의 데이터 길이는 11이다. (aaabdaaabac)
90 |
91 | **BPE 수행 후**
92 |
93 | - 사전을 통해 7개의 문자를 표현할 수 있다. (a, b, c, d, Z=(aa), Y=(ab), X=(ZY))
94 |
95 | - 문자열의 데이터 길이는 5이다. (XdXac)
96 |
97 |
98 |
99 | BPE는 사전의 크기를 지나치게 늘리지 않으면서 데이터 길이를 효율적으로 압축할 수 있도록 한다. 또한 BPE 기반 토큰화 기법은 분석 대상 언어에 대한 지식이 필요 없다. 말뭉치에서 자주 나타나는 문자열을 토큰으로 분석하기 때문이다.
100 |
101 |
102 |
103 |
104 |
105 | #### WordPiece
106 |
107 | - BPE와 유사지만, 토큰 쌍의 빈도가 아닌 가능도(likelihood)를 사용한다.
108 |
109 | $$
110 | {{\#ab} \over n} \over {{\#a \over n} \times {\#b \over n}}
111 | $$
112 |
113 | - 위 수식의 값이 커지려면 a, b 가 서로 독립임을 가정했을 때, 둘이 자주 동시에 등장해야 한다. (둘이 자주 등장하지만 동시에 등장하지 않으면 likelihood값이 감소한다)
114 |
115 |
116 |
117 |
118 |
119 | ## Reference
120 |
121 | - 구글 BERT의 정석 [book]
122 | - BERT와 GPT로 배우는 자연어 처리 [book]
123 |
--------------------------------------------------------------------------------
/summaries/chapter02/understanding_BERT_01.md:
--------------------------------------------------------------------------------
1 | ## BERT란 무엇인가
2 |
3 | BERT(Bidirectional Encoder Representation from Transformer) : Google에서 만든 문맥을 고려한 Transformer 기반 고성능 텍스트 임베딩 모델.
4 |
5 | ### 임베딩 모델이 문맥을 고려할 때의 장점
6 |
7 | **👉🏻 다의어∙동음이의어를 구분할 수 있다.**
8 |
9 | > A: He got bit by Python(파이썬이 그를 물었다).
10 | >
11 | > B: Python is my favorite programming language(내가 제일 좋아하는 프로그래밍 언어는 파이썬이다).
12 |
13 | - **Word2Vec**: `정적 임베딩`, A에서의 'Python' 임베딩 == B에서의 'Python' 임베딩
14 | - **BERT**: `동적 임베딩`, 트랜스포머 모델 기반이므로 문장의 각 단어를 문장 내 모든 단어들과 연결시켜 문맥을 이해할 수 있다. A에서는 'Python-bit'과의 관계에 주목, B에서는 'Python-programming' 관계에 주목하여 서로 다른 임베딩 값을 갖는다.
15 |
16 | ## BERT의 동작 방식
17 |
18 | 트랜스포머 모델을 기반으로 하지만, 트랜스포머의 인코더-디코더 구조에서 **인코더**만 사용한다. 인코더는 문장을 입력받아 문맥을 고려해 문장의 의미를 학습하여 각 단어의 **문맥 표현**을 출력했다.
19 |
20 | 
21 |
22 | 문장이 인코더의 입력으로 들어오면 인코더는 멀티 헤드 어텐션 메커니즘으로 단어끼리 모두 연결하여 관계와 문맥을 파악해 문장 각 단어의 문맥 포현을 출력한다. 인코더는 여러 개 쌓을 수 있으며, 각 단어 토큰의 표현 크기는 인코더 레이어 출력의 차원이다.
23 |
24 | ## BERT의 구조
25 |
26 | BERT는 크기에 따라 아래의 두 모델로 나뉜다.
27 |
28 | - BERT-base: OpenAI GPT와 동일한 하이퍼파라미터를 가짐. GPT와의 성능 비교를 위해 설계됨
29 | - BERT-large: BERT의 최대 성능을 보여주기 위해 만들어짐
30 |
31 | 
32 |
33 |
34 | ### GLUE Results
35 |
36 | 
37 |
38 | - 모든 task에 대해 SOTA 달성
39 | - BERT-large가 일반적으로 BERT-base보다 성능이 좋음
40 | - **사전학습** 덕분에 데이터셋의 크기가 작아도 모델의 크기가 클수록 정확도가 상승
41 |
42 | ## BERT 사전 학습
43 |
44 | BERT에 데이터를 입력하기 전에 세 가지 임베딩 레이어를 통해 입력 데이터를 임베딩으로 변환해야 한다.
45 |
46 | ### 입력 임베딩
47 |
48 | 
49 |
50 | - 토큰 임베딩(token embedding)
51 | - 세그먼트 임베딩(segement embedding)
52 | - 위치 임베딩(position embedding)
53 |
54 | #### 토큰 임베딩
55 |
56 | - 문장 쌍(Sentence pair)은 합쳐져서 단일 시퀀스로 입력되며, 입력 내의 쌍은 한 개 혹은 두 개의 문장으로 이루어져 있을 수 있다.
57 | - 예시: QA Task - \[Question, Paragraph]
58 | - Q: What is your favorite programming language?
59 | - A: My favorite programming language is Python.
60 | - Sentence의 시작 부분에 `[CLS]`라는 토큰을 추가한다.
61 | - 분류 문제를 풀 때만 사용되지만 다른 문제를 풀더라도 무조건 추가해야 한다.
62 | - Sentence 내 모든 문장의 끝에 `[SEP]`라는 새 토큰을 추가한다.
63 | - 토큰 임베딩을 거친 후의 형태: `tokens = [[CLS], My, favorite, ... , [SEP], It's, ..., use, [SEP]]`
64 |
65 | #### 워드피스 토크나이저
66 |
67 | BERT에서 사용하는 토크나이저는 단어를 더 작은 단위로 쪼개 토큰화하는 서브워드 토크나이저 기반의 **워드피스 토크나이저**다. 단어를 더 작은 단위로 쪼개 토큰화했을 때의 장점은 다음과 같다:
68 |
69 | - **OOV(out-of-vocabulary)의 처리가 쉬워진다**. 단어가 어휘 사전에 없으면 계속해서 하위 단어로 쪼개가며 개별 문자에 도달할 때까지 확인하기 때문이다.
70 | - **계산 비용을 비교적 작게 유지할 수 있다**. 텍스트 데이터를 학습한 모델의 크기는 Vocabulary의 크기에 영향을 받고 이 크기에 비례하여 계산비용이 증가하는데, 하위 단어로 쪼개 토큰화하면 Vocabulary의 크기를 작게 유지할 수 있다.
71 | - 고유의 알고리즘 덕분에 **언어에 상관없이 범용적으로 적용할 수 있다.**
72 |
73 | #### 워드피스 토크나이저는 어떻게 동작하는가?
74 |
75 | 워드피스 토크나이저가 처음으로 등장한 [논문](https://static.googleusercontent.com/media/research.google.com/ja//pubs/archive/37842.pdf)의 설명에 따르면 다음과 같은 알고리즘을 따라 동작한다.
76 |
77 | 1. 기본 글자들(알파벳 등)으로 단어 유닛 인벤토리를 초기화한다.
78 | 2. 1에서 생성된 단어 인벤토리를 사용해 훈련 데이터로 언어 모델을 만든다.
79 | 3. 현재의 단어 인벤토리에서 두 개의 유닛을 결합해 새로운 단어 유닛을 생성한다. 이 때 선택되는 두 단어는 결합했을 때의 **가능도(likelihood)** 상승폭이 가장 큰 단어들이다. 👉🏻 모수 추정을 위해 **ML(maximize likelihood)** 사용
80 | 4. 미리 정해둔 단어 인벤토리 크기 한도에 도달하거나 가능도의 증가폭이 특정 임계점 아래로 내려갈 때까지 `Goto 2` -> 반복
81 |
82 | > 가능도(likelihood): 어떤 값이 관측되었을 때, 이것이 어떤 확률 분포에서 왔을지에 대한 확률
83 |
84 | #### 세그먼트 임베딩
85 |
86 | - 같은 문장 내의 서로 다른 두 작은 문장을 구별하는 데 사용된다.
87 | - 두 문장을 구분하기 위해 `[SEP]` 토큰 사용에 추가로 세그먼트 임베딩을 사용해서 앞의 문장에는 `sentence A embedding`, 뒤의 문장에는 `sentence B embedding`을 더해준다.
88 | - 문장이 하나라면 `sentence A embedding` 만을 사용한다.
89 |
90 | #### 위치 임베딩
91 |
92 | - BERT의 베이스가 되는 트랜스포머는 모든 단어를 병렬로 처리하므로 단어의 순서에 대한 정보를 따로 제공해 줘야 한다. 위치 임베딩을 통해 문장의 각 토큰에 대한 위치 임베딩 출력을 얻을 수 있다.
93 | - BERT는 트랜스포머와 다르게 학습을 통해 위치 정보를 얻는 포지션 임베딩을 사용한다. 문장의 길이만큼의 포지션 임베딩 벡터를 학습시켜 사용한다.
94 |
95 | ### 사전학습에 대한 기존 방법론
96 |
97 | 
98 |
99 | - 전통적인 언어 모델링(Language Modeling): **n-gram**, 앞의 N-1개의 단어로 뒤에 올 단어를 예측하는 모델
100 | - 필연적으로 단방향일수 밖에 없고, BiLM을 사용하는 ELMo더라도 순방향, 순방향의 언어 모델을 둘 다 학습해 활용하지만, 단방향 언어 모델의 출력을 concat하여 사용하는 정도이므로 제한적인 양방향성을 가짐
101 |
102 | ### BERT 사전학습에 사용된 새로운 방법론
103 |
104 | - Masked Language Model(MLM)
105 | - Next Sentence Prediction(NSP)
106 |
107 | #### 마스크 언어 모델링 Masked Language Model
108 |
109 | BERT는 양방향성을 MLM을 통해 구현했다. MLM은 자동 인코딩 언어 모델로, 예측을 위해 문장을 **양방향**으로 읽는다. 전체 단어의 15%를 무작위로 마스킹하고, 마스크된 단어를 예측하도록 모델을 학습하며 문맥을 파악하는 능력을 향상시킨다. 마스크된 단어를 예측하기 위해 모델은 양방향으로 문장을 읽고 마스킹된 단어를 예측하려 시도한다. `[MASK]` 토큰은 사전학습에서만 사용되며, 파인 튜닝 시에는 사용되지 않는다.
110 |
111 | 15%의 토큰을 무작위로 마스킹할 때 `80-10-10%` 규칙을 적용한다.
112 |
113 | - 80%: 토큰을 `[MASK]`로 바꾼다.
114 | - 예) `So we could call it even` -> `So we could [MASK] it even`
115 | - 10%: 토큰을 임의의 토큰(단어)로 바꾼다.
116 | - 예) `So we could call it even` -> `So we could pizza it even`
117 | - 10%: 어떠한 변경도 하지 않는다. BERT는 이 단어가 변경된 단어인지 원래 단어인지 모르므로 BERT가 원래 단어가 무엇인지 예측하도록 한다.
118 |
119 | **전체 단어 마스킹 Whole Word Masking**
120 |
121 | 전체 단어 마스킹은 단어를 무작위로 마스킹하는 과정에서 하위 단어가 선택되었을 때, 해당 하위 단어와 관련된 모든 단어를 마스킹하는 방법이다. 아래는 WWM의 동작 예시다.
122 |
123 | ```
124 | #1
125 | tokens = [[CLS], let, us, start, pre, ##train, ##ing, the, model, [SEP]]
126 | #2 - ##train이 마스킹됨
127 | tokens = [[CLS], let, us, start, pre, [MASK], ##ing, the, model, [SEP]]
128 | #3 - ##train과 관련된 pre와 ##ing도 마스킹됨
129 | tokens = [[CLS], let, us, start, [MASK], [MASK], [MASK], the, model, [SEP]]
130 | ```
131 |
132 | 마스킹된 하위 단어(예시에서는 `##train`)와 관련된 모든 단어를 마스킹하는 동안 마스크 비율(15%)을 초과하면 다른 단어의 마스킹을 무시한다.
133 |
134 | **마스크된 토큰 예측**
135 |
136 | 
137 |
138 | 토큰화와 WWM을 거친 후에 입력 토큰을 토큰, 세그먼트, 위치 임베딩 레이어에 입력해 입력 임베딩을 얻을 수 있다. 이 입력 임베딩을 BERT에 제공하면 BERT는 각 토큰의 표현 $R$을 출력한다. 각 단어들의 표현들($R$) 중 마스크된 토큰의 표현 벡터 $R_{MASK}$을 소프트맥스 활성화를 통해 피드포워드 네트워크에 입력하면, 그 출력으로 각 단어가 \[MASK\] 자리에 있어야 할 단어일 확률을 반환한다.
139 |
140 | #### 다음 문장 예측 Next Sentence Prediction
141 |
142 | QA, Natural Language Inference(NLI)처럼 NLP 태스크 중에선 두 문장 사이의 관계를 이해하는 것이 중요한 것들이 있는데, 이것은 전통적인 언어 모델링(n-gram)에서 학습될 수 없는 부분이다. 따라서 BERT는 NSP라고 불리는 두 문장을 입력하고 두번째 문장이 첫번째 문장의 다음 문장인지 예측하는 이진 분류 테스트를 수행한다.
143 |
144 | - 학습을 위해 50%는 실제로 이어지는 두 문장을 넣는다.
145 | - 나머지 50%은 랜덤으로 추출된 두 문장을 넣는다.
146 |
147 | 이진 분류를 위해 레이블링 작업이 필요하다. 서로 이어지는 문장 쌍에는 `IsNext` 레이블을 붙이고, 서로 이어지지 않는 문장 쌍에는 `NotNext` 레이블을 붙여 두 문장이 이어지지 않음을 표시한다.
148 |
149 | - `[CLS] He got [MASK] by Python [SEP] So now he's bleeding LABEL = IsNext`
150 | - `[CLS] He got [MASK] by Python [SEP] Let's go out and get some pizza LABEL = NotNext`
151 |
152 | 예측을 위해서는 `[CLS]` 토큰의 표현값을 사용한다. `[CLS]`는 문장 내 다른 단어들과의 self-attention을 통해 모든 토큰의 집계 표현을 담고 있기 때문이다. ([참고](https://stackoverflow.com/questions/62705268/why-bert-transformer-uses-cls-token-for-classification-instead-of-average-over)) `[CLS]` 토큰에 classification layer를 붙이고 softmax를 통해 각 레이블에 속할 확률을 계산한다.
153 | 
154 |
155 | ### 사전 학습 절차
156 |
157 | 1. 말뭉치에서 두 문장 A, B를 샘플링한다.
158 | - A와 B의 총 토큰 수의 합은 512보다 작거나 같아야 한다.
159 | - 전체의 50%은 B 문장이 A 문장과 이어지는 문장(`IsNext`)이 되도록 샘플링하고, 나머지 50%은 B 문장이 A 문장의 후속 문장이 아닌 것(`NotNext`)으로 샘플링한다.
160 | 2. 워드피스 토크나이저로 문장을 토큰화하고, 토큰 임베딩-세그먼트 임베딩-위치 임베딩 레이어를 거친다.
161 | - 시작 부분에 `[CLS]` 토큰을, 문장 끝에 `[SEP]` 토큰을 추가한다.
162 | - `80-10-10%` 규칙에 따라 토큰의 15%를 무작위 마스킹한다.
163 | 3. BERT에 토큰을 입력하고, MLM과 NSP 태스크를 동시에 수행한다.
164 | - 웜업 스텝(= 1만): 초기 1만 스텝은 학습률이 0에서 1e - 4로 선형 증가, 1만 스텝 이후 선형 감소
165 | - 드롭아웃(0.1) 사용
166 | - **GeLU** 활성화 함수 사용: 음수에 대해서도 미분이 가능해 약간의 그래디언트를 전달할 수 있음
167 |
168 | 
169 |
170 | ### 사전 학습의 효과
171 |
172 | 
173 |
174 | > **No NSP**: MLM 사용 / NSP 미사용
175 | >
176 | > **LTR & No NSP**: MLM 대신 Left-to-Right 사용 / NLP 미사용
177 |
178 | - NSP 태스크를 진행하지 않으면 자연어 추론 태스크(QNLI, MNLI)와 QA 태스크(SQuAD)에서 큰 성능 하락이 있음
179 | - MLM 대신 LTR이나 BiLSTM을 사용했을 때 MRPC와 SQuAD에서의 성능이 크게 하락함. MLM이 LTR과 BiLSTM보다 훨씬 깊은 양방향성을 띈다.
180 |
181 | ## 참고자료
182 |
183 | - [BERT 논문](https://arxiv.org/abs/1810.04805)
184 | - [BERT 논문정리 ∙ Minho Park](https://mino-park7.github.io/nlp/2018/12/12/bert-%EB%85%BC%EB%AC%B8%EC%A0%95%EB%A6%AC/?fbclid=IwAR3S-8iLWEVG6FGUVxoYdwQyA-zG0GpOUzVEsFBd0ARFg4eFXqCyGLznu7w#bert%EC%9D%98-pre-training-%EB%B0%A9%EB%B2%95%EB%A1%A0)
185 | - [Wikidocs: 딥 러닝을 이용한 자연어 처리 입문](https://wikidocs.net/115055)
186 | - [WordPiece: Subword-based tokenization algorithm](https://towardsdatascience.com/wordpiece-subword-based-tokenization-algorithm-1fbd14394ed7)
187 |
--------------------------------------------------------------------------------
/summaries/chapter03/chapter03_embedding-extraction.md:
--------------------------------------------------------------------------------
1 | # Chapter 3. BERT 활용하기
2 |
3 | ## 사전 학습된 BERT 모델
4 |
5 | *BERT를 처음부터 사전 학습시키는 것은 계산 비용이 많이 든다. 따라서 사전 학습된 공개 BERT 모델을 다운로드해 사용하는 것이 효과적이다.*
6 | *Cf. [구글 리서치의 깃허브 저장소](https://github.com/google-research/bert) 또는 [사용 가능한 모든 사전 학습된 BERT 모델을 확인할 수 있는 huggingface.co](https://huggingface.co/models?sort=downloads&search=bert)*
7 |
8 | ### 종류
9 |
10 | - 구조
11 | - 인코더 레이어 수 *L*, 어텐션 헤드 *A*, 은닉 유닛 *H*의 다양한 조합
12 | - BERT-base / BERT-large
13 | - BERT-tiny / BERT-mini / BERT-small / BERT-medium
14 |
15 | - 형식
16 |
17 | - BERT-uncased : 모든 토큰이 소문자인 상태로 학습을 진행한 모델
18 | - 일반적으로 사용되는 모델
19 |
20 | - BERT-cased : 토큰에 대해 소문자화를 하지 않은 상태로 학습을 진행한 모델
21 | - 대소문자를 보존해야 하는 **개체명 인식(NER)**과 같은 특정 작업을 수행하는 경우
22 |
23 |
24 | ### 두 가지 사용 방법
25 |
26 | - 임베딩을 추출해 특징 추출기로 사용한다.
27 | - 사전 학습된 BERT 모델을 텍스트 분류, 질문-응답 등과 같은 다운스트림 태스크에 맞게 파인 튜닝한다.
28 |
29 | ## 사전 학습된 BERT 모델을 특징 추출기로 사용하는 방법
30 |
31 | ### 데이터셋의 문장을 벡터화하는 방법
32 |
33 | **데이터셋(텍스트)** → 모델에 입력하기 위해 **텍스트를 벡터화**
34 |
35 | - 문맥 독립 임베딩 모델
36 | - TF-IDF, Word2Vec, FastText, GloVe
37 | - 문맥 임베딩 모델
38 | - ELMo, BERT, GPT-3
39 |
40 | ### 사전 학습된 BERT에서 임베딩 추출하는 방법
41 |
42 | - 단어 임베딩(벡터 표현) 추출
43 | - 문장 임베딩(벡터 표현) 추출
44 |
45 | #### 단어 임베딩 추출
46 |
47 | 사전 학습된 BERT 모델을 사용해 데이터셋의 문장을 벡터화하는 방법
48 |
49 | 1. 워드피스 토크나이저를 이용해 문장을 토큰화하여 토큰(단어)을 얻는다.
50 | 2. 토큰 리스트 시작 부분에 `[CLS]` 토큰을 추가하고 끝에 `[SEP]` 토큰을 추가한다.
51 | 3. 모든 토큰의 길이는 동일하게 유지해야 하므로, `[PAD]` 토큰을 이용하여 토큰의 길이를 동일하게 맞춰준다.
52 | 4. 어텐션 마스크를 사용하여 `[PAD]` 토큰이 실제 토큰의 일부가 아니라는 것을 모델이 이해하도록 한다.
53 | - 모든 위치에서 어텐션 마스크값을 1로 설정하고 `[PAD] ` 토큰이 있는 위치에만 0을 설정한다.
54 | 5. 모든 토큰을 고유한 토큰 ID에 매핑한다.
55 | 6. 사전 학습된 BERT 모델에 대한 입력으로 어텐션 마스크와 함께 토큰 ID를 공급하고 각 토큰의 벡터 표현(임베딩)을 얻는다.
56 |
57 | 위와 같은 방법으로 학습셋의 모든 문장을 벡터화하여 문장에서 각 단어에 대한 표현을 얻는다.
58 |
59 |
60 |
61 | *출처 [Understanding the Bert Model](https://medium.com/analytics-vidhya/understanding-the-bert-model-a04e1c7933a9)*
62 |
63 | #### 문장 임베딩 추출
64 |
65 | `[CLS]` 토큰의 표현은 전제 문장의 집계 표현을 보유하게 되므로, **문장의 표현**은 `[CLS]` 토큰에 해당하는 `R_[CLS]` 표현 벡터가 된다.
66 |
67 | - `[CLS]` 토큰의 표현을 문장 표현으로 사용하는 것이 항상 좋은 생각은 아니다. 문장의 표현을 얻는 효율적인 방법은 모든 토큰의 표현을 평균화하거나 풀링하는 것이다. _Cf. 4장_
68 |
69 | - 매우 유사한 방식으로 학습셋에 있는 모든 문장의 벡터 표현을 계산하여 모든 문장의 문장 표현을 얻은 후에는 해당 표현을 입력으로 제공하고 분류기로 학습해 감정 분석 작업을 수행할 수 있다.
70 |
71 | ### Hugging Face Transformer
72 |
73 | Hugging Face의 오픈 소스 라이브러리 `transformers`와 사전 학습된 BERT 모델을 사용해, 문장에 있는 모든 단어의 문맥화된 단어 임베딩 생성하기
74 |
75 | - Hugging Face : 자연어 기술의 민주화를 추구하는 조직
76 | - `transformers` : 파이토치 및 텐서플로와 모두 호환, NLP 및 NLU 태스크에 강력, 100개 이상의 언어로 사전 학습된 수천 개의 모델 포함
77 |
78 | #### BERT의 최상위 인코더 계층인 12번째 인코더에서만 임베딩을 얻는 방법
79 |
80 | - 💻 [최종 인코더 계층에서만 임베딩을 추출하는 실습 코드](../../codes/3-2_generating_BERT_embedding.ipynb) *Cf. Google Colab / Python 3.x*
81 |
82 | - 코드 흐름
83 |
84 | 1. 설치 및 다운로드
85 | - `transformers` 설치
86 | - 사전 학습된 BERT *model* 다운로드
87 | - 위 모델을 사전 학습시키는 데 사용된 *tokenizer* 다운로드
88 |
89 | 2. 입력 전처리
90 |
91 | - *tokenizer*를 이용해 문장 토큰화
92 | - *attention_mask* 생성
93 | - *token_ids*로 변환
94 |
95 | 3. 임베딩 추출
96 |
97 | - *token_ids* 및 *attention_mask*를 *model*에 입력하고 임베딩 획득
98 |
99 | - *model*은 두 값으로 구성된 튜플 반환
100 |
101 | ```
102 | last_hidden_state, pooler_output = model(token_ids, attention_mask = attention_mask)
103 | ```
104 |
105 | `last_hidden_state` : 최종 인코더 계층(12번째 인코더)에서만 얻은 모든 토큰의 표현 벡터
106 |
107 | `pooler_output` : 최종 인코더 계층의 `[CLS]` 토큰 표현을 나타내며 선형 및 tanh 활성화 함수에 의해 계산
108 |
109 | 📌 `last_hidden_state[0][0]` vs. `pooler_output`
110 |
111 | - https://github.com/huggingface/transformers/issues/7540
112 |
113 | *Cf. 책에서는 last_hidden_state를 hidden_rep로, pooler_output을 cls_head라고 기술했다.*
114 |
115 | #### BERT의 모든 인코더 레이어에서 임베딩을 추출하는 방법
116 |
117 | - 최종 인코더 레이어(마지막 계층의 은닉 상태)에서만 얻은 임베딩(표현 벡터) 사용 **vs.** 다른 인코더 레이어에서 얻은 임베딩 고려
118 |
119 | ➡︎ 모든 인코더 레이어(모든 은닉 상태)에서 얻은 임베딩도 고려하자!
120 |
121 | | 속성 | 표기 | F1 스코어 |
122 | | :----------------------------: | :-------------: | :-------: |
123 | | 임베딩 | h_0 | 91.0 |
124 | | 마지막에서 두 번째 레이어 | h_11 | 95.6 |
125 | | 마지막 레이어 | h_12 | 94.9 |
126 | | 마지막 4개 레이어의 가중합 | h_9 to h_12 | 95.9 |
127 | | **마지막 4개 레이어의 연결값** | **h_9 to h_12** | **96.1** |
128 | | 12개 레이어의 가중합 | h_1 to h_12 | 95.5 |
129 |
130 | 구글 BERT의 정석 그림 3-5 서로 다른 레이어의 임베딩 속성으로 도출한 F1 스코어
131 |
132 | - 💻 [모든 인코더 레이어에서 임베딩 추출하는 실습 코드](../../codes/3-3_extracting_embeddings_from_all_encoder_layers_of_BERT.ipynb) *Cf. Google Colab / Python 3.x*
133 |
134 | - BERT의 최상위 인코더 계층인 12번째 인코더에서만 임베딩을 얻는 코드와 유사하고, 다른 점은 다음과 같다 :
135 |
136 | - 사전 학습된 BERT 모델을 다운로드 받을 때
137 |
138 | 모든 인코더 레이어에서 임베딩을 얻기 위해, `output_hidden_states = True` 로 설정한다.
139 |
140 | - 임베딩을 가져올 때
141 |
142 | 모델은 hidden_state를 추가하여, 2개가 아닌 3개의 값이 있는 튜플을 반환한다.
143 |
144 | ```
145 | last_hidden_state, pooler_output, hidden_states = model(token_ids, attention_mask = attention_mask)
146 | ```
147 |
148 | `last_hidden_state` 와 `pooler_output` 의 값은 최상위 인코더 계층에서만 임베딩을 얻는 경우와 동일하고, `hidden_states`가 추가된다.
149 |
150 | `hidden_states` : 모든 인코더 계층에서 얻은 모든 토큰의 표현 포함
151 |
152 | - 입력 임베딩 레이어 *h_0*에서 *h_12*까지 모든 인코더 레이어의 표현을 포함하는 13개의 값을 포함하는 튜플
153 |
154 | *hidden_states[i]는 i번째 레이어 h_i에서 얻은 모든 토큰의 표현 벡터를 가진다. => hidden_states[12]==last_hidden_state*
155 |
156 | ## 정리
157 |
158 | - 사전 학습된 BERT 모델을 다음 두 가지 방법으로 사용할 수 있다.
159 |
160 | - 임베딩을 추출해 특징 추출기로 사용한다.
161 |
162 | - 사전 학습된 BERT 모델을 다운스트림 태스크에 맞게 파인 튜닝한다.
163 |
164 | _Cf. 이 문서에서는 임베딩을 추출하는 방법만 다뤘다._
165 |
166 | - 사전 학습된 BERT에서 단어 및 문장 임베딩(표현)을 추출할 수 있다.
167 |
168 | - 단어의 벡터 표현
169 | - 최종 인코더는 문장에 있는 모든 토큰(단어)의 최종 표현 벡터(임베딩)을 반환한다.
170 | - 문장의 벡터 표현
171 | - `[CLS]` 토큰의 표현은 전체 문장의 집계 표현을 보유하게 된다.
172 |
173 | - 사전 학습된 BERT 모델에서 임베딩을 추출할 때 어떤 레이어에서 얻은 임베딩을 사용해야 할까?
174 |
175 | - 최종 인코더 레이어(마지막 계층의 은닉 상태)에서만 얻은 임베딩
176 | - 모든 인코더 레이어(모든 은닉 상태)에서 얻은 임베딩
177 |
178 | - 실습 코드
179 |
180 | - 저자의 깃허브 저장소
181 | - [3.03. Generating BERT embedding .ipynb](https://github.com/PacktPublishing/Getting-Started-with-Google-BERT/blob/main/Chapter03/3.03.%20Generating%20BERT%20embedding%20.ipynb)
182 | - [3.04. Extracting embeddings from all encoder layers of BERT.ipynb](https://github.com/PacktPublishing/Getting-Started-with-Google-BERT/blob/main/Chapter03/3.04.%20Extracting%20embeddings%20from%20all%20encoder%20layers%20of%20BERT.ipynb)
183 |
184 | - 버전 업데이트를 반영하고, 한글 설명을 추가한 코드 *Cf. Google Colab / Python 3.x*
185 |
186 | - [최종 인코더 계층에서만 임베딩 추출](../../codes/3-2_generating_BERT_embedding.ipynb)
187 |
188 | - [모든 인코더 레이어에서 임베딩 추출](../../codes/3-3_extracting_embeddings_from_all_encoder_layers_of_BERT.ipynb)
189 |
190 | ## 참고 자료
191 |
192 | - 구글 BERT의 정석 [book](http://www.yes24.com/Product/Goods/104491152)
193 |
--------------------------------------------------------------------------------
/summaries/chapter03/chapter03_finetuning.md:
--------------------------------------------------------------------------------
1 | # 다운스트림 태스크를 위한 BERT 파인 튜닝 방법
2 |
3 | 처음부터 학습하는 것이 아니라 Pretrained Model을 사용하여 학습
4 |
5 | - 텍스트 분류
6 | - 자연어 추론(NLI)
7 | - 개체명 인식(NER)
8 | - 질문-응답
9 |
10 | ## 텍스트 분류
11 |
12 | - Tokenization(Special Tokens 추가)
13 | - R_[CLS]를 문장의 표현으로 사용
14 | - Classifier(softmax)에 넣고 감정 분석
15 |
16 | Fine-tuning 하면서 Model Weight를 조절하는 방법은 두 가지
17 |
18 | 1. 분류 계층과 함께 사전 학습된 BERT 모델의 가중치를 업데이트
19 | 2. Pretrained BERT가 아니라 Classifier weight만 업데이트. Feature Extractor로 사용(Model Freeze)
20 |
21 | Feature Extractor로 사용하는 것과 무엇이 다를까? Model Free
22 |
23 | ### 감정 분석을 위한 BERT 파인 튜닝
24 |
25 | IMDB Dataset은 영화 리뷰 텍스트와 리뷰의 감정 레이블로 구성
26 |
27 | ```python
28 | from transfomers import BertForSequenceClassification, BertTokenizerFast, Trainer,
29 | TrainingArguments
30 | from nlp import load_dataset
31 | import torch
32 | import numpy as np
33 |
34 | # Data loading
35 | # download from GDrive
36 | dataset = load_dataset('csv', data_files='./imdbs.csv', split='train')
37 | type(dataset) # nlp.arrow_dataset.Dataset
38 | dataset = dataset.train_test_split(test_size=0.3)
39 |
40 | train_set = dataset['train']
41 | test_set = dataset['test']
42 |
43 | model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
44 | tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')
45 |
46 | # ---------------
47 | tokens = [ '[CLS]', 'I', 'love', 'Paris', '[SEP]' ]
48 | inputs_ids = [101, 1045, 2293, 3000, 102]
49 | token_type_ids = [0, 0, 0, 0, 0] #Segment Embedding
50 | attention_mask = [1, 1, 1, 1, 1]
51 |
52 | tokenizer('I love Paris') # Same as above
53 |
54 | tokenizer(['I love Paris', 'birds fly', 'snow fall'], padding=True, max_length=5)
55 | # ---------------
56 | def preprocess(data):
57 | return tokenizer(data['text'], padding=True, truncation=True)
58 |
59 | train_set = train_set.map(preprocess, batched=True, batch_size=len(train_set))
60 | test_set = test_set.map(preprocess, batched=True, batch_size=len(test_set))
61 |
62 | train_set.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])
63 | test_set.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])
64 |
65 | batch_size = 8
66 | epochs = 2
67 |
68 | warmup_steps = 500
69 | weight_decay = 0.01
70 |
71 | training_args = TrainingArguments(
72 | output_dir='./results',
73 | num_train_epochs=epochs,
74 | per_device_train_batch_size=batch_size,
75 | per_device_eval_batch_size=batch_size,
76 | warmup_steps=warmup_steps,
77 | weight_decay=weight_decay,
78 | evaluate_during_training=True,
79 | logging_dir='./logs',
80 | )
81 |
82 | trainer = Trainer(
83 | model=model,
84 | args=training_args,
85 | train_dataset=train_set,
86 | eval_dataset=test_set
87 | )
88 |
89 | trainer.train()
90 | trainer.evaluate()
91 | ```
92 |
93 | ## 자연어 추론
94 |
95 | - Natural Language Inference
96 | - 가정이 주어진 전제에 참인지 거짓인지 중립인지 여부를 결정하는 태스크
97 | - (전제, 가설)에 대한 레이블이 주어짐
98 | - 전제와 가설 사이를 `[SEP]`으로 구분
99 | - `[CLS]` 토큰의 임베딩의 Classifier에 입력하면 참, 거짓, 중립일 확률을 반환
100 |
101 | ## 질문-응답(QA Task)
102 |
103 | - 목표: 주어진 질문에 대한 단락에서 답을 추출
104 | - BERT의 입력은 Question-Paragraph Pair
105 | - BERT는 Paragraph에서 Answer에 해당하는 텍스트의 범위를 반환해야 함
106 | - 단락 내 답의 시작과 끝 토큰의 확률을 구하면 답을 추출할 수 있음
107 | - 시작 벡터 S, 끝 벡터 E(Trainable)
108 | - Token 표현 벡터 R과 시작 벡터 S 사이의 내적 계산 → Softmax
109 | - 비슷하게 끝 벡터 E에 대해서도 학습
110 |
111 | ```python
112 | from transformer import BertForQuestionAnswering, BertTokenizer
113 |
114 | model = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-fine-tuned-squad')
115 | tokenizer = BertTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-fine-tuned-squad')
116 |
117 | question = "면역 체계는 무엇입니까?"
118 | paragraph = "면역 체계는 질병으로부터 보호하는 유기체 내의 다양한 생물학적 구조와 과정의 시스템입니다. 제대로 기능하려면 면역 체계가 바이러스에서 기생충에 이르기까지 병원균으로 알려진 다양한 물질을 탐지하고 유기체의 건강한 조직과 구별해야 합니다."
119 |
120 | question = '[CLS]' + question + '[SEP]'
121 | paragraph = paragraph + '[SEP]'
122 |
123 | question_tokens = tokenizer.tokenize(question)
124 | paragraph_tokens = tokenizer.tokenize(paragraph)
125 |
126 | tokens = question_tokens + paragraph_tokens
127 | input_ids = tokenizer.convert_to_ids(tokens)
128 |
129 | segment_ids = [0] * len(question_tokens)
130 | segment_ids += [1] * len(paragraph_tokens)
131 |
132 | input_ids = torch.tensor([input_ids])
133 | segment_ids = torch.tensor([segment_ids])
134 |
135 | start_scores, end_scores = model(input_ids, token_type_ids=segment_ids)
136 |
137 | start_index = torch.argmax(start_scores)
138 | end_index = torch.argmax(end_scores)
139 |
140 | print(' '.join(tokens[start_index:end_index+1]))
141 | ```
142 |
143 | ## 개체명 인식(NER)
144 |
145 | - 개체명을 미리 정의된 범주로 분류
146 | - 앞에 `[CLS]` 끝에 `[SEP]` 토큰 추가
147 | - BERT 모델에 토큰을 입력하고 표현 벡터 반환
148 | - Classifier에 입력
149 | - Classifier는 개체명이 속한 범주를 반환
150 |
151 | # 텐서플로 2와 머신러닝으로 시작하는 자연어 처리
152 |
153 | - LM이란 단어들의 시퀀스에 대한 확률 분포
154 | - 단어들의 모임(시퀀스)가 있을 때 해당 단어의 모음이 어떤 확률로 등장하는지를 나타내는 값
155 | - BERT Fine tuning 예시
156 | - 언어적 용인 가능성(Linguistic Acceptability)
157 | - 자연어 추론(Natural Language Inference)
158 | - 유사도 예측(Similiarity Predicition)
159 | - 감정 분석(Sentiment Analysis)
160 | - 개체명 인식(Named Entity Recognition)
161 | - 기계독해(Reading Comprehension)
162 | - BERT 파생모델 분류
163 | 1. BERT를 개선하려고 노력한 모델. 성능 향상, 속도 개선, 메모리 최적화 등 a.g.) SpanBERT, RoBERTa, ERNIE
164 | 2. BERT의 알고리즘 문제를 실험적으로 증명하며 개선하려는 모델 a.g.) XLNet
165 | 3. BERT를 NLP가 아닌 다른 분야에 사용하는 모델 a.g.) VideoBERT, VisualBERT
166 |
167 | # Questions
168 |
169 | ## 현업에서 Fine-tuning 어떻게 하는지?
170 | - https://klue-benchmark.com/
171 | - https://huffon.github.io/2019/11/16/glue/
172 | - https://gluebenchmark.com/
173 | - https://korquad.github.io/
174 | - https://blog.naver.com/skelterlabs/222025030327
175 |
176 |
177 | ## Weight를 freezing 하면 어떤 효과가 있는지?
178 | Layer Freezing을 한다는 것은 accuracy를 크게 떨어뜨리지 않으면서 computation cost를 절약하는 것이 목적이다. Dropout이나 Stochastic Depth 같은 것을 보면 모든 layer를 학습시키지 않으면서 네트워크를 효과적으로 학습할 수 있다는 것을 볼 수 있다.
179 |
180 | ### FreezeOut
181 | Vision 관련 논문. Pretraining 후에 Fine-tuning을 통해서 최종 Task에 맞는 Weight를 업데이트 함. 이 때, 앞쪽 layer들이 대부분 budget을 많이 차지하는 것에 비해 Parameter가 적고 상당히 간단한 설정으로 수렴하는데, 이는 대부분의 Parameter들이 있는 이후에 나오는 layer들에 비해서 fine-tuning이 필요하지는 않다고 가정할 수 있음. 이미 local minimum에 도달했다고 볼 수 있다.
182 |
183 | VGG에서의 실험결과에서 FreezeOut이 잘 맞지 않는 것으로 나타났는데, skip connection(dense나 residual도)이 FreezeOut이 동작 가능하게 해주는 중요한 요소인 것 같다고 함 → NLP에 적용했을 때는?
184 |
185 | ### References
186 | - https://raphaelb.org/posts/freezing-bert
187 | - https://analyticsindiamag.com/what-does-freezing-a-layer-mean-and-how-does-it-help-in-fine-tuning-neural-networks/
188 | - https://stats.stackexchange.com/questions/393168/what-does-it-mean-to-freeze-or-unfreeze-a-model/393171
189 | - https://arxiv.org/pdf/1706.04983.pdf
190 |
191 | # References
192 |
193 | https://mccormickml.com/2020/03/10/question-answering-with-a-fine-tuned-BERT/
194 |
--------------------------------------------------------------------------------
/summaries/chapter04/Chapter04_ALBERT_suyeon.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/summaries/chapter04/Chapter04_ALBERT_suyeon.pdf
--------------------------------------------------------------------------------
/summaries/chapter04/Chapter04_ELECTRA.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/summaries/chapter04/Chapter04_ELECTRA.pdf
--------------------------------------------------------------------------------
/summaries/chapter04/chapter04_SpanBERT.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Chapter 4 BERT 파생 모델 2
4 |
5 | 이번 장에서 다루는 BERT의 다양한 형태의 파생 모델
6 |
7 | - ALBERT
8 | - RoBERTa
9 | - ELECTRA
10 | - SpanBERT
11 |
12 | ## SpanBERT
13 |
14 | 📄 **[SpanBERT: Improving Pre-training by Representing and Predicting Spans](https://arxiv.org/pdf/1907.10529.pdf)**
15 |
16 | SpanBERT란 text span을 더 잘 표현하고 예측하기 위해 설계된 사전 학습 기법이다.
17 |
18 | - 다음과 같은 방식으로 BERT를 확장하였다.
19 |
20 | | | SpanBERT | BERT |
21 | | :-------------------------------------------: | :------------------------------------: | :-------------------------------------: |
22 | | **마스킹 방법** | 연속된 랜덤 spans 마스킹 | 랜덤 토큰 마스킹 |
23 | | **마스킹된 토큰 예측하기 위해 사용하는 표현** | span 경계 표현을 학습시켜서 예측 (SBO) | 마스킹된 개별 토큰의 표현을 이용해 예측 |
24 |
25 |
SpanBERT와 BERT
26 |
27 | 🤔 기존 많은 NLP tasks는 **두 개 이상의 text span의 관계 추론**을 포함했고, 이는 self supervision tasks를 더 어렵게 했다.
28 |
29 | ➡︎ SpanBERT는 **span-level** 사전학습 방식으로 항상 BERT보다 좋은 성능을 낸다.
30 |
31 | - 특히
span selection tasks에서 뛰어난 성능을 보인다.
32 |
33 | - question answering
34 | - coreference resolution (상호참조해결)
35 | - 데이터를 더 추가하거나 모델 크기를 키우지 않고, 좋은 사전학습 tasks와 objectives만으로도 좋은 성능을 낼 수 있다는 의의가 있다.
36 |
37 | ### Model
38 |
39 | - 연속된 랜덤 spans 마스킹
40 | - span boundary objective (SBO) 도입
41 |
42 | - 단일 연속 text segment 샘플링 ➡︎ BERT의 NSP 생략
43 |
44 | #### Span Masking
45 |
46 | `masking spans of full words using a geometric distribution based masking scheme`
47 |
48 | - 주어진 토큰 시퀀스 *X=(x1,…,xn)* 에서 masking budget(e.g. 15% of X)이 다 사용될 때까지 text span 샘플링
49 |
50 | 1. 각 iteration 마다 span length(단어 개수)를 샘플링
51 |
52 | - 짧은 span으로 치우친 geometric distribution *𝓵 ~ Geo(p)* 에서 샘플링
53 |
54 | 2. 마스킹될 span의 시작점을 랜덤(균일)하게 뽑는다.
55 |
56 | 완전한 단어 seqeunce를 샘플링한다. (subword tokens X)
57 |
58 | 3. span에 있는 모든 토큰들을 [MASK] 또는 sampled tokens로 대체한다. (span-level masking)
59 |
60 | *Cf. BERT는 80-10-10% 로 각 토큰을 개별적으로 대체*
61 |
62 | #### Span Boundary Objective (SBO)
63 |
64 | `optimizing an auxiliary span boundary objective (SBO) in addition to MLM`
65 |
66 | span selection model은 일반적으로 boundary 토큰을 이용하여 span의 고정된 길이 표현을 생성한다.
67 |
68 | ➡︎ **boundary 토큰의 표현만을 이용해 masked span의 각 토큰을 예측하는
Span boundary objective(SBO)** 도입했다.
69 |
70 | - SBO는 모델이 fine-tuning 시에 쉽게 접근할 수 있는 boundary 토큰에 span-level 정보를 저장하게 하여 span selection model을 지원한다.
71 |
72 | - span에 있는 마스킹된 토큰 `xi` *(target token: xi)* 을 예측하는 방법
73 | - xs와 xe를 각각 마스킹된 토큰에 대한 표현의 시작과 종료 지점이라고 할 때, 다음 3개의 값을 사용한다.
74 | - external boundary tokens `xs−1` and `xe+1`
75 | - position embedding of the target token `pi−s+1` (left boundary token xs-1로부터 상대 위치)
76 |
77 | - 3개의 값을 2 layer feed-forward network with GeLU activations and layer normalization 에 입력하여 얻은 출력값을 사용한다.
78 |
79 | - SpanBERT의 손실함수는 MLM과 SBO loss *(cross-entropy loss)*를 더한 값이다.
80 |
81 | #### Single-Sequence Training
82 |
83 | BERT의 examples는 두 개의 text sequence *(X_A, X_B)* 를 사용하고, 두 sequence의 연결 여부를 예측*(NSP)*하게 모델을 학습시켰다. *(bi-sequence training with NSP)*
84 |
85 | 하지만 single-sequence training이 bi-sequence training with NSP보다 우수했고, 이유는 다음과 같을 것이라고 가정했다.
86 |
87 | *: bi-sequence training은 모델이 더 긴 범위의 features를 학습하는 것을 방해하고, 결과적으로 많은 downstream tasks 에서 성능을 저하시킨다.*
88 |
89 | ➡︎ **NSP objective과 two-segment sampling procedure를 모두 제거하고,** 두 개의 half-segments를 합쳐서 n개의 토큰이 아닌,
90 |
91 | **최대 n=512의 토큰의 단일 연속 segment를 샘플링**해서 다양한 downstream tasks의 성능을 향상시켰다.
92 |
93 | ---
94 |
95 | 
96 |
97 |
SpanBERT 학습 과정
98 |
99 | ### Tasks
100 |
101 | - Extractive Question Answering
102 | - 짧은 글과 질문을 입력한 후에 글에서 답으로 연속적인 text span을 선택하는 task
103 |
104 | - Coreference Resolution
105 |
106 | - 동일한 개체(entity)를 표현하는 다양한 단어(mention)들을 찾아 연결해주는 task
107 |
108 | *[Coreference Resolution 관련 설명 및 논문이 정리된 블로그](https://jjdeeplearning.tistory.com/26)*
109 |
110 | - Relation Extraction
111 |
112 | - 두 span이 들어있는 한 문장이 주어졌을 때 42개의 사전 정의된 관계 타입으로부터 span 사이의 관계를 예측하는 task
113 |
114 | - GLUE
115 |
116 | - General Language Understanding Evaluation (GLUE) benchmark는 9개의 sentence-level 분류 tasks로 구성
117 |
118 | ### Results
119 |
120 | - SpanBERT는 거의 모든 task에 대해 BERT보다 뛰어나다.
121 | - SpanBERT는 특히 extractive question answering에 좋다.
122 | - single-sequence training이 bi-sequence with NSP 보다 상당히 잘 작동한다.
123 |
124 | ### Summary
125 |
126 | - 이 논문은 span 기반 사전 학습 방식인 SpanBERT를 제시했다.
127 |
128 | - SpanBERT는 BERT를 확장했다.
129 |
130 | (1) random 토큰 대신, 연속적인 랜덤 span을 마스킹한다.
131 |
132 | (2) 개별 토큰 표현이 아닌, span 경계 표현을 학습시켜 마스킹된 span의 전체 내용을 예측한다.
133 |
134 | - SpanBERT는 여러 task에 대해 모든 BERT baselines를 뛰어넘었다.
135 |
136 | - SpanBERT는 span selection tasks에 특히 좋은 성능을 보인다.
137 |
138 | ## 사전 학습된 SpanBERT를 질문-응답 태스크에 적용하기
139 |
140 | ```python
141 | from transformers import pipeline
142 |
143 | qa_pipeline = pipeline(
144 | "question-answering",
145 | model="mrm8488/spanbert-large-finetuned-squadv2",
146 | tokenizer="SpanBERT/spanbert-large-cased"
147 | )
148 |
149 | results = qa_pipeline({
150 | 'question': "What is machine learning?",
151 | 'context': "Machine learning is a subset of artificial intelligence. It is widely for creating a variety of applications such as email filtering and computer vision"
152 | })
153 |
154 | print(results['answer']) # a subset of artificial intelligence
155 | ```
156 |
157 | *SpanBert는 텍스트 범위를 예측하는 작업에 많이 사용된다.*
158 |
159 | ## 참고 자료
160 |
161 | - 구글 BERT의 정석 [book](http://www.yes24.com/Product/Goods/104491152)
--------------------------------------------------------------------------------
/summaries/chapter04/chapter04_roberta.md:
--------------------------------------------------------------------------------
1 | # Chatper 4 BERT의 파생 모델 1
2 |
3 | 이 챕터에서 다루는 BERT의 파생 모델들
4 |
5 | - ALBERT
6 | - RoBERTa
7 | - ELECTRA
8 | - SpanBERT
9 |
10 | ## RoBERTa
11 |
12 | - Robustly Optimized BERT pre-training Approach
13 | - BERT가 충분히 학습되지 않았음을 확인
14 | - BERT와의 차이
15 | - MLM에서 Dynamic Masking 사용
16 | - NSP 제거
17 | - 배치 크기 증가
18 | - BBPE Tokenizer 사용
19 |
20 | ### Dynamic Masking
21 |
22 | - Static Masking
23 | - BERT에서 Masking은 전처리 단계에서 한 번만 수행
24 | - Epoch 별로 동일한 Masking을 예측
25 | - Dynamic Masking
26 | - 문장 10개를 복사
27 | - 각각의 복사된 문장에 대해 무작위로 15%의 확률로 Masking
28 | - 40 Epoch이면 1,2,3,4,...,10,1,2,3,...와 같이 학습시킴
29 |
30 | ### NSP 제거
31 |
32 | - 연구원들은 NSP가 BERT에 유용하지 않다는 것을 발견
33 | - Ablation Study
34 | 1. Segment-Pair + NSP: NSP를 사용해서 BERT 학습. 원래 BERT 모델 학습 방법과 유사
35 | 2. Sentence-Pair + NSP: NSP를 사용해서 BERT 학습. 입력은 한 문서의 연속된 부분 또는 다른 문서에서 추출한 문장을 쌍으로 구성
36 | 3. Full Sentences: NSP를 사용하지 않고 BERT 학습. 입력은 하나 이상의 문서에서 지속적으로 샘플링한 결과를 사용. 하나의 문서에서 마지막까지 샘플링하면 다음 문서로 넘어감.
37 | 4. Doc Sentences: NSP를 사용하지 않고 BERT 학습. Full Sentences와 비슷하지만 입력값은 하나의 문서에서만 샘플링한 결과를 입력.
38 | - Results
39 |
40 | | Model | SQuAD 1.1/2.0 | MNLI-m | SST-2 | RACE |
41 | | -------------- | ------------- | ------ | ----- | ---- |
42 | | Segment-Pair | 90.4/78.7 | 84 | 92.9 | 64.2 |
43 | | Sentence-Pair | 88.7/76.2 | 82.9 | 92.1 | 63.0 |
44 | | Full-Sentences | 90.4/79.1 | 84.7 | 92.5 | 64.8 |
45 | | Doc-Sentences | 90.6/79.7 | 84.7 | 92.7 | 65.6 |
46 |
47 | - 결론적으로 NSP를 제거하는 것이 성능이 더 좋더라!
48 | - 성능은 Full-Sentences보다 Doc-Sentences가 더 좋지만 RoBERTa에서는 Doc-Sentences의 경우 문서에 따라 배치 크기가 달라지기 때문에 Full-Sentences를 사용하여 학습
49 |
50 | ### 더 많은 데이터로 학습
51 |
52 | - BERT에서 사용한 데이터는 16GB
53 | - RoBERTa에서 사용한 데이터는 160GB
54 |
55 | ### 큰 배치 크기로 학습
56 |
57 | - BERT: 256개 배치로 1M Step Pretrain
58 | - RoBERTa: 8000개 배치로 0.3M Step Pretrain
59 | - 배치 크기를 키우면
60 | - 학습 속도를 높일 수 있고,
61 | - 모델의 성능도 향상
62 |
63 | ### BBPE Tokenizer
64 |
65 | - BERT는 Wordpiece Tokenizer 사용
66 | - 캐릭터가 아니라 Byte 형태의 시퀀스 사용
67 | - BERT는 vocab size 30000, BBPE는 50000
68 |
69 | ```python
70 | from transformers import RobertaConfig, RobertaTokenizer
71 |
72 | model = RobertaModel.from_pretrained('roberta-base')
73 | model.config
74 |
75 | tokenizer = RobertaTokenizer.from_pretrained('roberta-base')
76 | tokenizer.tokenize('It was a great day')
77 | ```
78 |
79 | ### Summary
80 |
81 | - RoBERTa는 BERT의 파생모델
82 | - MLM Task로만 학습
83 | - Static Masking
84 | - 큰 Batch size
85 | - BBPE Tokenizer
86 |
87 | ## References
88 |
89 | - https://jeongukjae.github.io/posts/3-roberta-review/
90 | - https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=jjys9047&logNo=221671424019
91 | - https://brunch.co.kr/@choseunghyek/7
--------------------------------------------------------------------------------
/summaries/chapter05/chapter05_DistilBERT.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gubuzeong/Getting-Started-with-Google-BERT/ae04bb9d23b4423749f121162df878972989e23c/summaries/chapter05/chapter05_DistilBERT.pdf
--------------------------------------------------------------------------------
/summaries/chapter05/chapter05_TinyBERT.md:
--------------------------------------------------------------------------------
1 | # Chapter 5 BERT 파생 모델 2: 지식 증류 기반
2 |
3 | ## TinyBERT
4 |
5 | - Teacher model의 output layer 말고도 embedding, encoder layers에서 KD
6 | - 중간 layer에서의 지식도 전달
7 | - Student가 Teacher로부터 더 많은 것을 배울 수 있음
8 | - Attention Matrix는 언어 정보를 캡슐화하므로(?) Teacher의 Attention Matrix에서 Student에게 지식을 전달하면 도움이 많이 됨
9 | - 사전학습 뿐만 아니라 fine-tuning에서도 KD
10 | - (Teacher-Student) 아키텍쳐는 동일하지만 layer수가 다름
11 | - Embedding vector size d = 312
12 | - Teacher BERT
13 | - index 0 - Embedding layer
14 | - index 1 - 첫번째 encoder layer
15 | - index n - n번째 encoder layer
16 | - index n + 1 - prediction layer
17 | - 교사의 n번째 layer에서 학생의 m번째 layer로 지식을 전달
18 |
19 | ### Transformer layer distillation
20 |
21 | - Attention-based Distillation
22 | - Hidden state-based Distillation
23 |
24 | ### Attention-based Distillation
25 |
26 | - Attention Matrix에 대한 지식을 Teacher → Student 이전
27 | - Attention Matrix에는 언어 구문, 상호 참조 정보 등과 같은 정보가 포함됨
28 | - Student attention matrix와 Teacher attention matrix 사이의 MSE를 최소화 해 Student 학습
29 | - L_att = (sum(MSE(A_i^S, A_i^T)) / h
30 | - h: attention head 수
31 | - A_i^S: Student BERT의 ith head의 attention matrix
32 | - A_i^T: Teacher BERT의 ith head의 attention matrix
33 | - MSE는 Mean Squared Error
34 | - 정규화(Normalization)하지 않은 (Softmax가 없는) Attention Matrix 사용 → 비정규화된 Attention Matrix가 더 좋은 성능을 내고, 수렴 속도도 빠름
35 |
36 | ### Hidden state-based Distillation
37 |
38 | - Hidden state는 기본적으로 Encoder의 출력, representation vector
39 | - H^S와 H^T의 차원이 다를 수 있음
40 | - L_hidden = MSE(H^SW_h, H^T)
41 | - W_h는 학습을 통해 달라지는 값. H^S를 H^T와 같은 공간에 있을 수 있도록 선형변환
42 |
43 | ### Embedding layer Distillation
44 |
45 | - Hidden state와 유사하게 차원이 다를 수 있기 때문에 W_e로 선형 변환
46 | - L_embedding = MSE(E^SW_e, E^T)
47 |
48 | ### Prediction layer Distillation
49 |
50 | - Teacher model에서 생성한 최종 logit으로 학습. DistilBERT와 유사
51 | - Soft target - Soft prediction 사이의 Cross-entropy loss를 minimize
52 | - L_pred = -softmax(Z^T)* log_softmax(Z^S)
53 |
54 | ### 최종 loss function
55 |
56 |

57 |
58 | ## TinyBERT 학습
59 |
60 | - General Distillation
61 | - Task-specific Distillation
62 |
63 | ### General Distillation
64 |
65 | - 사전 학습 단계를 의미
66 | - Large BERT를 Teacher로 사용하고 Student model에게 지식을 전달
67 | - 모든 layer에 증류 적용
68 | - 증류 후 Student BERT는 Teacher의 지식으로 구성, 사전 학습된 Student BERT를 General TinyBERT라고 부름
69 | - Downstream task를 위해 General TinyBERT를 Fine-tuning 할 수 있음
70 |
71 | ### Task-specific Distillation
72 |
73 | - Fine-tuning
74 | - 특정 Task를 위해 General TinyBERT를 Fine-tuning
75 | - Teacher model을 먼저 Fine-tuning, 다시 General TinyBERT로 Distillation 진행
76 | - Fine-tuning 단계에서 Distillation을 하려면 더 많은 dataset 필요 → Data Augmentation
77 |
78 | ### Data Augmentation
79 |
80 | Tokenized sentence X의 각각 모든 단어에 대해,
81 |
82 | 1. X[i]가 단일 단어인지 확인. 단일 단어라면 [MASK] 토큰으로 masking. BERT-base로 masked token을 예측. 확률이 높은 상위 K개의 단어 candidates에 저장
83 | 2. X[i]가 단일 단어가 아니면 masking 하지 않음. GloVe Embedding을 사용해 X[i]와 가장 유사한 K 단어 확인하고 candidates에 저장. p~Uniform(0,1)에서 값 p를 무작위로 추출하고, threshold를 p_t = 0.4로 설정
84 | 3. p가 p_t보다 작거나 같으면 X_masked[i]를 후보 목록의 임의 단어로 교체
85 | 4. p가 p_t보다 크면 교체 안함
86 |
87 | - N번 반복하면 N개의 Augmented sentence가 생성
88 | - Augmented Data를 사용하여 General TinyBERT를 Fine-tuning
89 | - TinyBERT는 BERT-base 모델보다,
90 | - 96%의 추론 효율 향상
91 | - 7.5배 작음
92 | - 9.4배 빠름
93 |
94 | ## BERT에서 신경망으로 지식 전달
95 |
96 | - BERT에서 간단한 신경망으로 Distillation이 가능할까?
97 | - Teacher model - Pretrained BERT(여기서는 BERT-large)
98 | - Teacher model을 Downstream task에 맞게 fine-tuning
99 | - Student model - Bi-LSTM
100 | - Bi-LSTM은 양방향으로 문장을 읽음
101 | - 순방향, 역방향 hidden state를 FFN에 넣고 logit 출력
102 | - softmax → 확률
103 |
104 | ### Student network training
105 |
106 | - 일단 Teacher부터 Fine-tuning
107 | - L = a * L_student + b * L_distillation
108 | - L_distillation = MSE(Z^T, Z^S) → Soft target, Soft prediction에 대한 MSE
109 | - L_student: Hard target, Hard prediction에 대한 cross-entropy
110 | - Teacher BERT에서 Student Network로 KD를 수행하려면 큰 데이터셋 필요
111 | - Task-agnostic Data Augmentation
112 |
113 | ## Data Augmentation
114 |
115 | - Masking
116 | - POS based word replacement
117 | - n-gram sampling
118 |
119 | ### Masking
120 |
121 | - TinyBERT의 DA 방법
122 |
123 | ### POS based word replacement
124 |
125 | - p_pos 확률로 문장의 한 단어를 같은 품사 다른 단어로 대체
126 |
127 | ### n-gram Sampling
128 |
129 | - p_ng 확률로 문장에서 n-gram을 random sampling
130 | - n은 1~5까지 무작위
131 |
132 | ### Data Augmentation Process
133 |
134 | - X_i ~ Uniform(0,1)
135 | - X_i < p_mask이면 w_i 단어를 masking
136 | - p_mask ≤ X_i p_mask + p_pos이면 POS word replacement를 진행
137 | - Masking과 POS based WR은 겹치지 않음. 둘 중 하나만 적용 가능
138 | - 이 단계 이후, p_ng 확률로 n-gram sampling
139 | - N번 수행 → N개의 새로운 Augmented data
140 |
141 | 문장이 아니라 문장 쌍이라면?
142 |
143 | - 문장 1 합성 + 문장 2 유지
144 | - 문장 1 유지 + 문장 2 합성
145 | - 문장 1 합성 + 문장 2 합성
146 |
147 | 이런 식으로 Augmentation 가능
--------------------------------------------------------------------------------
/summaries/chapter06/chapter06_텍스트_요약을_위한_BERTSUM_탐색_(1).md:
--------------------------------------------------------------------------------
1 | # Chapter 6: 텍스트 요약을 위한 BERTSUM 탐색
2 |
3 | > Speaker: 남수연
4 |
5 |
6 | # 텍스트 요약
7 |
8 | NLP 분야의 주요 연구 분야 중 하나로, 주어진 긴 텍스트를 요약하는 것. 긴 문서, 뉴스 기사, 법률 문서, 블로그 게시물 등 다양한 영역에서 널리 사용됨.
9 |
10 | # 텍스트 요약 방식 이해하기
11 |
12 | 아래와 같은 텍스트를 요약해야 한다고 해보자.
13 |
14 | ```
15 | 나는 어제 신촌에서 동아리 운영진 동기 언니와 10시간 내내 먹었다. 점심으로
16 | 진돈부리를 가려고 했지만 딱 어제 휴업하는 바람에 반서울에 갔는데 엄청 맛있었다.
17 | 다음에 또 와야겠다고 생각했다. 후식으로 파이홀에 가서 오레오말차가나슈파이와 얼그
18 | 레이가나슈파이를 먹었다. 역시 다음에 또 와야겠다고 생각했다. 저녁으로 돈우마미에
19 | 가서 사케동을 먹었다. 가라아게 4조각을 시켰는데 서비스로 한 조각을 더 주셔서
20 | 돈우마미는 참 좋은 가게라는 생각이 들었다. 마지막으로 아워즈에 가서 칵테일을 조
21 | 졌다. 줄리엣이라는 칵테일을 주문했는데 요맘때 복숭아맛과 딸기맛을 섞어놓은 것 같은
22 | 것이 정말 정말 맛있었다. 정신을 차려보니 9시 30분이어서 허겁지겁 버스를 타고
23 | 집에 왔더니 월요일이 스터디 하는 날이랜다. 어이가 없어서 헛웃음이 나왔지만 지금
24 | 웃을 때가 아니므로 열심히 스터디 준비를 하는 중이다.
25 | ```
26 |
27 | ## 추출 요약
28 |
29 | 주어진 텍스트 안에서 중요한 문장만 추출해 요약한다. 입력의 문장 중 중요도가 높은 순으로 N개의 문장을 뽑는 식이다.
30 |
31 | ```
32 | 나는 어제 신촌에서 동아리 운영진 동기 언니와 10시간 내내 먹었다. 점심으로
33 | 진돈부리를 가려고 했는데 딱 어제만 휴업하는 바람에 반서울에 갔는데 엄청 맛있
34 | 었다. 후식으로 파이홀에 가서 오레오말차가나슈 파이와 얼그레이가나슈파이를 먹었다.
35 | 마지막으로 아워즈에 가서 칵테일을 조졌다. 어이가 없어서 헛웃음이 나왔지만 지금
36 | 웃을 때가 아니므로 열심히 스터디 준비를 하는 중이다.
37 | ```
38 |
39 | ## 생성 요약
40 |
41 | 주어진 텍스트를 의역해서 원래 문서에 포함되지 않은 문장으로 요약을 만든다.
42 |
43 | ```
44 | 어제의 나는 동아리 언니와 10시간동안 쉬지 않고 먹었다. 정신을 차려보니 발등에
45 | 불이 떨어진 상태여서 열심히 스터디 준비를 하는 중이다.
46 | ```
47 |
48 | ## Summary
49 |
50 | | | 추출 요약 | 생성 요약 |
51 | | --- | --- | --- |
52 | | 입력 문장을 그대로 사용하는가? | O | X |
53 | | 정보 누락 정도 | 많음 | 적음 |
54 | | 컴퓨팅 리소스 필요량 | 적음 | 많음 |
55 | | 학습 시간 필요량 | 적음 | 많음 |
56 |
57 | # 텍스트 요약에 맞춘 BERT 파인 튜닝
58 |
59 | ## BERT을 활용한 추출 요약
60 |
61 | 사전학습된 BERT를 사용해 추출 요약 태스크를 진행하려면 BERT 모델 입력 데이터 형태를 수정해야 한다. BERT 모델의 입력 데이터를 수정하여 각 문장의 표현을 얻는 방법에 대해 알아보자.
62 |
63 | - BERT 복습
64 | 1. 입력 문장을 토큰 형태로 변경한다.
65 | 2. 첫 문장의 시작 부분에만 `[CLS]` 토큰을 모든 문장의 마지막 부분에 `[SEP]` 토큰을 추가한다.
66 | 3. 입력 토큰을 토큰 임베딩, 세그먼트 임베딩, 위치 임베딩, 총 3개의 임베딩 레이어 형태로 각각 변환한다.
67 | 4. 모든 임베딩을 더한 다음 BERT에 입력한다.
68 | 5. BERT는 아웃풋으로 모든 토큰의 표현 벡터를 출력한다.
69 |
70 |
71 |
72 | ### 1) 토큰 임베딩
73 |
74 | 텍스트 요약 태스크에서는 BERT 모델에 여러 문장을 입력하고 입력한 모든 문장에 대한 표현이 필요하다. **모든 문장의 시작 부분에 `[CLS]` 토큰을 추가**하면 모든 문장에 대한 표현을 얻을 수 있다. 이 `[CLS]` 토큰은 각 문장을 대표하는 토큰으로서 문장의 특징을 뽑아낼 때 사용할 것이다.
75 |
76 | ```python
77 | input = ["[CLS]", "ban", "seoul", "[SEP]", "[CLS]", "pie", "hole", "[SEP]", "[CLS]", "don", "umami", "[SEP]"]
78 | ```
79 |
80 | ### 2) 세그먼트 임베딩
81 |
82 | 세그먼트 임베딩은 입력을 $E_A, E_B$ 형태로 반환한다. 그보다 훨씬 많은 수의 문장이 입력으로 들어오는 텍스트 요약 태스크에서는 $E_A, E_B$ 만으로 어떻게 문장을 구분할 수 있을까?
83 |
84 | 인터벌 세그먼트 임베딩을 통해 홀수번째 문장에서 발생한 토큰은 $E_A$, 짝수번째 문장에서 발생한 토큰은 $E_B$에 매핑한다. 한 문장을 앞뒤의 문장들과 구분하기만 하면 되므로 이런 방법을 사용할 수 있다.
85 |
86 | ### 3) 위치 임베딩
87 |
88 | 위치 임베딩은 모든 토큰의 위치 정보에 대한 임베딩값으로, 기존 방식과 동일하다.
89 |
90 | ## BERTSUM
91 |
92 | 
93 |
94 | BERT 모델을 사용해 입력 데이터 형식을 변경해서 텍스트 요약에 특화되도록 만든 모델을 BERTSUM이라고 한다. 처음부터 BERT를 학습시킬 필요는 없으며, 이미 사전학습된 BERT 모델에 앞서 설명한 입력 데이터 형태로 변경하여 파인 튜닝하면 된다.
95 |
96 | ### 1) 분류기가 있는 BERTSUM
97 |
98 |
99 | **모든 문장의 표현을 받아서 각 문장의 중요도를 판단하는 분류기 레이어**를 ****BERT에 이어붙인다. 분류기는 각 문장을 요약에 포함시킬지 여부에 대한 확률을 제공한다. Linear Layer 하나만 사용하며, BERT의 아웃풋을 분류기 레이어에 넣어 나온 값에 sigmoid 활성화 함수를 취한 값을 target으로 활용한다. 이렇게 계산된 target과 정답을 BCE를 통해 loss를 계산한다. loss 값을 최소화하도록 BERT 모델과 분류기 레이어를 함께 학습시킨다.
100 |
101 | $$
102 | \hat{Y} = \sigma(W_oT_i + b_o)
103 | $$
104 |
105 | ### 2) 🌟 트랜스포머와 LSTM을 활용한 BERTSUM
106 |
107 | **(1) 문장 간 트랜스포머(inter-sentence transformer)를 활용한 BERTSUM**
108 |
109 | 논문에 따르면 다른 2개의 Summarization layer보다 훨씬 좋은 결과를 보여주는 방법이다. BERT의 결과인 문장 표현 $R$을 트랜스포머 레이어에 입력한다. 트랜스포머는 BERT에서 얻은 표현을 가져와 은닉 상태로 변환하는데, 이 때 도입되는 트랜스포머는 문장 간 Attention을 계산하고 문장 단위가 아닌 전체 문서 관점에서 요약 태스크를 수행한다.
110 |
111 | BERT에서 얻은 문장 표현 R에 위치 임베딩 값을 추가하여 트랜스포머의 인코더에 입력한다($h^0=PosEmb(R)$) . 인코더 $l$에서 서브레이어는 다음과 같이 표현한다.
112 |
113 | 
114 |
115 | 최상위 인코더를 $L$, 최상위 인코더에서 나온 은닉 상태를 $h^L$이라고 했을 때 문장의 포함 여부를 계산하는 식은 다음과 같다.
116 |
117 | 
118 |
119 | **(2) LSTM을 활용한 BERTSUM**
120 |
121 | BERT의 last hidden layer에 RNN을 활용하면 성능이 좋을 수 있다는 논문을 참고하여 실험을 진행했으며, 훈련 과정을 안정화하기 위해 단순 LSTM이 아닌 pergate layer nomarlization을 사용했다.
122 |
123 | BERT에서 얻은 문장 $i$에 대한 표현 $R_i$를 LSTM에 입력하면 LSTM 셀은 은닉 상태 $h_i$를 출력한다. sigmoid에 $h_i$를 입력하면 각 문장을 요약에 포함시킬지에 대한 확률을 반환한다.
124 |
125 | 
126 |
127 | ### 참고: summarization layers에 대한 ROUGE 성능 평가
128 |
129 | 
130 |
131 | # References
132 |
133 | [[논문 리뷰] Fine-tune BERT for Extractive Summarization](https://medium.com/@eyfydsyd97/bert%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%9A%94%EC%95%BD-text-summary-b582b5cc7d)
134 |
135 | [BERT를 활용한 한국어 문서 추출요약 봇](https://velog.io/@raqoon886/KorBertSum-SummaryBot)
136 |
--------------------------------------------------------------------------------
/summaries/chapter06/chapter6_BERTSUM(2)_0hee0.md:
--------------------------------------------------------------------------------
1 | # Chapter 6 텍스트 요약을 위한 BERTSUM 탐색
2 |
3 | BERTSUM: 텍스트 요약에 맞춰 파인 튜닝된 BERT 모델
4 |
5 | ## BERTSUM 모델의 성능
6 |
7 | BERTSUM 모델의 성능은 ROUGE 점수를 사용하여 평가
8 |
9 | ### ROUGE 평가 지표
10 |
11 | **ROUGE(Recall-oriented Understudy for Gisting Evalutation)**
12 |
13 | - 텍스트 요약과 기계 번역 태스크를 평가하는 데 사용하는 평가 지표
14 | - 「[ROUGE: A Package for Automatic Evaluation of Summaries](https://aclanthology.org/W04-1013/)」
15 |
16 |
ROUGE의 다섯 가지 평가 지표 형태
17 |
18 | - ROUGE-N
19 | - ROUGE-L
20 | - ROUGE-W
21 | - ROUGE-S
22 | - ROUGE-SU
23 |
24 | *Cf. [ROUGE-an Evaluation Metric for Text Summarization](https://ilmoirfan.com/rouge-an-evaluation-metric-for-text-summarization/)*
25 |
26 | #### ROUGE-N
27 |
28 | 후보 요약(예측한 요약)과 참조 요약(실제 요약) 간의 n-gram 재현율(recall)
29 |
30 | ```
31 | 재현율 = (예측한 요약 결과와 실제 요약 사이의 서로 겹치는 n-gram 총 수) / (실제 요약의 n-gram의 총 수)
32 | ```
33 |
34 | *ROUGE-1(uni-gram)과 ROUGE-2(bi-gram)가 가장 많이 쓰인다.*
35 |
36 | #### ROUGE-L
37 |
38 | **가장 긴 공통 하위 시퀀스(LCS)**를 기반으로 하며, F-measure를 사용해 측정
39 |
40 | ### BERTSUM을 사용한 요약 태스크의 ROUGE 점수
41 |
42 | - 분류기, 트랜스포머, LSTM을 BERT에 적용한 BERTSUM 모델을 사용한 **추출 요약** 태스크의 ROUGE 점수
43 |
44 | *[Yang Liu. 2019. Fine-tune BERT for Extractive Summarization](https://arxiv.org/abs/1903.10318) 에서 CNN/DailyMail 테스트 데이터를 이용해 측정한 결과 (25/3/2019)*
45 |
46 | *Cf. https://github.com/nlpyang/BertSum*
47 |
48 | | 모델 | ROUGE-1 | ROUGE-2 | ROUGE-L |
49 | | :---------------------: | :-------: | :-------: | :-------: |
50 | | Transformer Baseline | 40.9 | 18.02 | 37.17 |
51 | | BERTSUM+classifier | 43.23 | 20.22 | 39.60 |
52 | | **BERTSUM+transformer** | **43.25** | **20.24** | **39.63** |
53 | | BERTSUM+LSTM | 43.22 | 20.17 | 39.59 |
54 |
55 | - BERTSUMABS 모델로 **생성 요약** 태스크를 수행했을 때의 ROUGE 점수
56 |
57 | *[Yang Liu, Mirella Lapata. 2019. Text Summarization with Pretrained Encoders](https://arxiv.org/abs/1908.08345) 에서 CNN/DailyMail 테스트 데이터를 이용해 측정한 결과 (20/8/2019)*
58 |
59 | *Cf. https://github.com/nlpyang/PreSumm*
60 |
61 | | 모델 | ROUGE-1 | ROUGE-2 | ROUGE-L |
62 | | :--------: | :-----: | :-----: | :-----: |
63 | | BERTSUMABS | 41.72 | 19.39 | 38.76 |
64 |
65 | ## BERTSUM 모델 학습
66 |
67 | ```python
68 | # Google Colab / Python 3.x / GPU
69 |
70 | %%capture
71 | !pip install pytorch_pretrained_bert
72 | !pip install torch==1.1.0 pytorch_transformers tensorboardX multiprocess pyrouge
73 | !pip install googleDriveFileDownloader
74 |
75 | cd /content/
76 |
77 | # BERTSUM 연구원들이 오픈 소스로 제공한 학습 코드
78 | !git clone https://github.com/nlpyang/BertSum.git
79 |
80 | # 데이터셋 다운로드 (전처리된 CNN/DailyMail 뉴스 데이터)
81 | cd /content/BertSum/bert_data/
82 | ### 다운로드 및 압축 해제 ###
83 |
84 | # BERTSUM 모델 학습
85 | cd /content/BertSum/src
86 |
87 | '''
88 | First run: For the first time, you should use single-GPU, so the code can download the BERT model. Change -visible_gpus 0,1,2 -gpu_ranks 0,1,2 -world_size 3 to -visible_gpus 0 -gpu_ranks 0 -world_size 1, after downloading, you could kill the process and rerun the code with multi-GPUs.
89 | '''
90 |
91 | # BERTSUM + classifier (number of parameters: 109483009)
92 | !python train.py -mode train -encoder classifier -dropout 0.1 -bert_data_path ../bert_data/cnndm -model_path ../models/bert_classifier -lr 2e-3 -visible_gpus 0 -gpu_ranks 0 -world_size 1 -report_every 50 -save_checkpoint_steps 1000 -batch_size 3000 -decay_method noam -train_steps 50 -accum_count 2 -log_file ../logs/bert_classifier -use_interval true -warmup_steps 10000
93 |
94 | # BERTSUM + transformer (* number of parameters: 120512513)
95 | !python train.py -mode train -encoder transformer -dropout 0.1 -bert_data_path ../bert_data/cnndm -model_path ../models/bert_transformer -lr 2e-3 -visible_gpus 0 -gpu_ranks 0 -world_size 1 -report_every 50 -save_checkpoint_steps 1000 -batch_size 3000 -decay_method noam -train_steps 50 -accum_count 2 -log_file ../logs/bert_transformer -use_interval true -warmup_steps 10000 -ff_size 2048 -inter_layers 2 -heads 8
96 |
97 | # BERTSUM + lstm (* number of parameters: 113041921)
98 | !python train.py -mode train -encoder rnn -dropout 0.1 -bert_data_path ../bert_data/cnndm -model_path ../models/bert_rnn -lr 2e-3 -visible_gpus 0 -gpu_ranks 0 -world_size 1 -report_every 50 -save_checkpoint_steps 1000 -batch_size 3000 -decay_method noam -train_steps 50 -accum_count 2 -log_file ../logs/bert_rnn -use_interval true -warmup_steps 10000 -rnn_size 768 -dropout 0.1
99 | ```
100 |
101 | ```
102 | usage: train.py [-h] [-encoder {classifier,transformer,rnn,baseline}]
103 | [-mode {train,validate,test}] [-bert_data_path BERT_DATA_PATH]
104 | [-model_path MODEL_PATH] [-result_path RESULT_PATH]
105 | [-temp_dir TEMP_DIR] [-bert_config_path BERT_CONFIG_PATH]
106 | [-batch_size BATCH_SIZE] [-use_interval [USE_INTERVAL]]
107 | [-hidden_size HIDDEN_SIZE] [-ff_size FF_SIZE] [-heads HEADS]
108 | [-inter_layers INTER_LAYERS] [-rnn_size RNN_SIZE]
109 | [-param_init PARAM_INIT]
110 | [-param_init_glorot [PARAM_INIT_GLOROT]] [-dropout DROPOUT]
111 | [-optim OPTIM] [-lr LR] [-beßta1 BETA1] [-beta2 BETA2]
112 | [-decay_method DECAY_METHOD] [-warmup_steps WARMUP_STEPS]
113 | [-max_grad_norm MAX_GRAD_NORM]
114 | [-save_checkpoint_steps SAVE_CHECKPOINT_STEPS]
115 | [-accum_count ACCUM_COUNT] [-world_size WORLD_SIZE]
116 | [-report_every REPORT_EVERY] [-train_steps TRAIN_STEPS]
117 | [-recall_eval [RECALL_EVAL]] [-visible_gpus VISIBLE_GPUS]
118 | [-gpu_ranks GPU_RANKS] [-log_file LOG_FILE] [-dataset DATASET]
119 | [-seed SEED] [-test_all [TEST_ALL]] [-test_from TEST_FROM]
120 | [-train_from TRAIN_FROM] [-report_rouge [REPORT_ROUGE]]
121 | [-block_trigram [BLOCK_TRIGRAM]]
122 | ```
123 |
124 | ## 참고 자료
125 |
126 | - 구글 BERT의 정석 [book](http://www.yes24.com/Product/Goods/104491152)
127 | - [Fine-tune BERT for Extractive Summarization (BERTSUM) github repository](https://github.com/nlpyang/BertSum)
128 | - [ROUGE-an Evaluation Metric for Text Summarization](https://ilmoirfan.com/rouge-an-evaluation-metric-for-text-summarization/)
129 |
130 |
--------------------------------------------------------------------------------
/summaries/chapter07/chapter07_M-BERT.md:
--------------------------------------------------------------------------------
1 | # Chapter 7. 다른 언어에 BERT 적용하기
2 |
3 | BERT를 영어가 아닌 다른 언어에도 적용할 수 있을까? 아래 모델을 통해서 BERT를 통해 다국어 표현을 어떻게 얻을 수 있는지 알아보자.
4 |
5 | - M-BERT(multilingual-BERT)
6 | - XLM(cross-lingual language model)
7 | - XLM-R(XLM-RoBERTa)
8 |
9 |
10 |
11 | ## M-BERT 이해하기
12 |
13 | **BERT**
14 |
15 | - Datasets: 영어 위키피디아, 토론토 책 말뭉치
16 | - PreTrain Task: MLM, NSP
17 |
18 | **M-BERT**
19 |
20 | - Datasets: 104개 언어 위키피디아
21 | - 각 언어들간의 비중이 다르다 -> overfitting을 방지하기 위해 언어별 under/over sampling 적용
22 | - 104개 언어, 11만개의 워드피스(BPE와 유사하지만 likelihood 사용하는 인코딩)
23 | - PreTrain Task: MLM, NSP
24 |
25 |
26 |
27 | M-BERT는 교차 언어를 고려하지 않고도 다른 언어들의 표현을 이해할 수 있다.
28 |
29 |
30 |
31 | ### NLI task 평가로 알아보는 M-BERT 평가하기
32 |
33 | - 두 문장(가설, 전제)을 바탕으로, 가설이 주어진 전제에 따라 진실/거짓/중립 여부를 판단하는 것
34 | - 일반적으로 SNLI(Stanford natural language inference) datasets 사용
35 | - 다국어 NLI 평가를 위해서는 교차 언어 자연어 추론(XNLI: cross-linugal NLI)사용
36 | - MultiNLI 말뭉치에서 약 43만개의 영어 문장 쌍을 사용
37 | - 평가셋을 위해 7,500개의 문장 쌍을 사용하며, 이를 15개의 서로 다른 언어로 번역하여 11만개의 문장 쌍을 사용
38 |
39 |
40 |
41 | 다양한 설정에서 NLI task를 수행해 M-BERT를 평가한다.
42 |
43 | #### 제로샷(zero-shot)
44 |
45 | - Fine-tuning: 영어 학습셋
46 | - Validation: 모든 언어 테스트셋
47 | - 영어로 학습하고 모든 언어로 평가
48 | - M-BERT의 교차 언어 능력을 이해하는데 도움
49 |
50 |
51 |
52 | #### 번역-테스트(Translate-Test)
53 |
54 | - Fine-tuning: 영어 학습셋
55 | - Validation: 영어로 번역된 테스트셋
56 | - 영어로 학습하고 영어로 평가
57 |
58 |
59 |
60 | #### 번역-학습(Translate-Train)
61 |
62 | - Fine-tuning: 영어에서 다른 언어로 번역된 학습셋
63 | - Validation: 모든 언어 테스트셋
64 | - 다른 언어로 학습하고 모든 언어로 평가
65 |
66 |
67 |
68 | #### 번역-학습-모두(Translate-Train-All)
69 |
70 | - Fine-tuning: 영어에서 다른 **모든 언어**로 번역된 학습셋
71 | - Validation: 모든 언어 테스트셋
72 | - 모든 언어로 학습하고 모든 언어로 평가
73 |
74 |
75 |
76 | | 모델 | 설정 | 영어 | 중국어 | 스페인어 | 독일어 | 아랍어 | 우루드어 |
77 | | ------------ | --------------- | ---- | ------ | -------- | ------ | ------ | -------- |
78 | | BERT-cased | Translate-Train | 81.9 | 76.6 | 77.8 | 75.9 | 70.7 | 61.6 |
79 | | BERT-uncased | Translate-Train | 81.4 | 74.2 | 77.3 | 75.2 | 70.5 | 61.7 |
80 | | BERT-uncased | Translate-Test | 81.4 | 70.1 | 74.9 | 74.4 | 70.4 | 62.1 |
81 | | BERT-uncased | Zero-shot | 81.4 | 74.3 | 74.3 | 70.3 | 60.1 | 58.3 |
82 |
83 | > M-BERT 모델은 제로샷을 포함해 모든 조건에서 좋은 성능을 보여준다.
84 |
85 |
86 |
87 | ### M-BERT는 다국어 표현이 어떻게 가능한가??
88 |
89 | 다른 언어들을 다 섞어서 학습한 것 뿐인데 어떻게 다국어 표현이 가능한 건지?
90 |
91 |
92 |
93 | #### 어휘 중복 효과?
94 |
95 | - 언어 간에 중복되는 어휘 때문??
96 |
97 | - overlap으로 파인튜닝 언어/평가 언어 간에 겹치는 워드피스 토큰 계산
98 | $$
99 | \left| \dfrac{E_{train}\cap E_{eva1}}{E_{train}\cup E_{era1}}\right|
100 | $$
101 |
102 | - 16개의 모든 언어 쌍에 대해 제로샷 F1 score를 계산한 결과 어휘 중복(overlap)이 적을 때에도 제로샷 F1이 높았음
103 |
104 | > zeroshot 지식 전이는 어휘 중복에 영향을 받지 않는다
105 | >
106 | > M-BERT가 다른 언어와의 관계성을 고려해 일반화를 잘 한다 = 단순한 어휘 암기가 아니라 다국어 표현을 더 깊게 학습한다
107 |
108 |
109 |
110 | #### 스크립트에 대한 일반화?
111 |
112 | - 서로 다른 스크립트를 따르는 언어들 사이에서도 일반화가 잘 될까?
113 |
114 | > 일부 언어 쌍의 스크립트에서는 일반화가 잘 되지만, 모든 언어에서 적용되지는 않는다.
115 |
116 |
117 |
118 | #### 유형학적 특징에 대한 일반화?
119 |
120 | - 주어, 동사, 목적어 등의 단어 순서가 다른 언어들 사이에서도 일반화가 잘 될까?
121 |
122 | > M-BERT의 zeroshot 전이는 단어 순서가 동일한 언어에서 더 잘 작동한다.
123 | >
124 | > M-BERT의 일반화 능력은 언어 간의 유형학적 유사성에 따라 달라진다 = M-BERT가 체계적인 변환을 학습하는 것은 아님
125 |
126 |
127 |
128 | #### 언어 유사성의 효과?
129 |
130 | - WALS: 문법, 어휘 및 음운 속성과 같은 언어의 구조적 속성을 포함하는 대규모 데이터베이스
131 | - WALS 공통 특징 수가 많을 수록 제로샷 정확도가 높은 경향
132 |
133 | > M-BERT는 유사한 언어 구조를 공유하는 언어 사이에서 더 잘 일반화된다
134 |
135 |
136 |
137 | #### 코드 스위칭과 음차의 효과?
138 |
139 | **코드 스위칭**
140 |
141 | - 다른 언어를 혼합하거나 교대로 사용하는 것
142 | - ex) Korean은 굉장히 kind하고 polite한 것 같아.
143 |
144 | **음차**
145 |
146 | - 발음하는 그대로 쓴거
147 | - ex) 코리안은 굉장히 카인드하고 폴라이트한 것 같아.
148 |
149 |
150 |
151 | M-BERT에서 코드 스위칭과 음차를 어떻게 다룰까?
152 |
153 | - 코드 스위칭된 힌디어/영어 UD 말뭉치를 사용
154 | - 음차: 힌디어 텍스트는 라틴 문자로 작성된다.
155 | - 코드 스위칭: 라틴어의 힌디어 텍스트가 데바나가리어 스크립트로 변환되어 재작성된다.
156 |
157 | | 말뭉치 | 평가셋 | 정확도 |
158 | | ------------------------ | ----------- | ------ |
159 | | 음차 | 음차 | 85.64 |
160 | | 단일 언어(영어 + 힌디어) | 음차 | 50.41 |
161 | | 코드 스위칭 | 코드 스위칭 | 90.56 |
162 | | 단일 언어(영어 + 힌디어) | 코드 스위칭 | 86.59 |
163 |
164 | > M-BERT는 음차 텍스트와 비교해 코드 스위칭 텍스트에서 수행 능력이 좋다
165 |
166 |
167 |
168 | #### 결론
169 |
170 | - M-BERT의 일반화 가능성은 어휘 중복에 의존하지 않는다.
171 | - M-BERT의 일반화 가능성은 유형학 및 언어 유사성에 따라 다르다.
172 | - M-BERT는 코드 스위칭 텍스트를 처리할 수 있지만 음차 텍스트는 처리할 수 없다.
173 |
174 |
175 |
176 | ## XLM
177 |
178 | - 다국어를 목표로 BERT를 사전학습 시킨 모델로 M-BERT보다 다국어 표현 학습을 할 때 성능이 더 뛰어나다
179 |
180 | - 단일 언어 / 병렬 데이터셋을 사용해 사전 학습된다
181 | - 병렬 데이터셋: 언어 쌍의 텍스트(2개의 다른 언어로 된 동일한 텍스트)
182 | - 단일 언어 데이터셋: 위키피디아
183 | - 병렬 데이터셋: 다국어 유엔 말뭉치(MultiUN), 개방형 병렬 말뭉치(OPUS), IIT 봄베이 말뭉치 등의 여러 소스
184 |
185 | - BPE 사용
186 |
187 | - 언어 임베딩을 사용해서 해당 토큰이 어떤 언어인지 알려준다
188 |
189 |
190 |
191 | ### CLM
192 |
193 | - 인과 언어 모델링(CLM: Causal Language Modeling)
194 |
195 | - 이전 단어셋을 바탕으로 현재 단어의 확률 예측
196 |
197 |
198 |
199 | ### MLM
200 |
201 | - 마스크 언어 모델링(MLM: Masked Language Modeling)
202 |
203 | - BERT에서는 NSP를 위해 두 개의 문장 쌍을 입력했지만, XLM에서는 임의의 문장을 모델에 입력할 수 있다(총 토큰의 길이는 256)
204 | - 단어의 빈도수에 따라 샘플링 빈도가 달라진다(sqrt(1/빈도수)의 다항분포에서 샘플링)
205 |
206 |
207 |
208 | ### TLM
209 |
210 | - 번역 언어 모델링(TLM: Translation Language Modeling)
211 |
212 | - 서로 다른 두 언어/동일한 내용의 텍스트로 구성된 병렬 교차 언어 데이터를 이용
213 | - Masked token을 맞추는 것은 MLM과 동일하지만, 교차 언어 표현을 학습시키려는 의도
214 | - 마스크된 토큰을 맞추기 위해서 다른 언어의 표현을 이해할 수 있다(교차 언어 표현이 정렬(align)된다)
215 |
216 |
217 |
218 | ### XLM 사전 학습
219 |
220 | - CLM or MLM
221 | - 단일 언어 데이터셋
222 | - 총 256개의 토큰으로 된 임의의 문장
223 | - TLM + MLM
224 | - TLM의 경우 병렬 데이터셋 사용
225 |
226 |
227 |
228 | ### XLM 평가
229 |
230 | 
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/summaries/chapter07/chapter07_XLMR_multilingual.md:
--------------------------------------------------------------------------------
1 | # Chapter 7 다른 언어에 BERT 적용하기
2 |
3 | ## XLM-R 이해하기
4 |
5 | - XLM에서 몇 가지를 보완한 확장 버전
6 | - XLM-RoBERTa
7 | - 자료가 적은 언어의 경우 병렬 데이터셋을 구하는 것이 쉽지 않아 MLM만 학습
8 | - 커먼 크롤 데이터셋에서 별도 레이블이 없는 100개의 언어 텍스트를 필터링하여 얻은 2.5TB의 데이터셋으로 학습
9 | - 비중이 적은 언어는 oversampling
10 | - Common crawl이 Wikipedia에 비해 자료가 적은 언어에서 데이터가 더 많음
11 | - Sentencepiece Tokenizer, 25만 개의 Token
12 | - Model Architecture
13 | - XLM-R_base: 12개의 Encoder layers, 12개의 Attention heads, 768 Hidden size
14 | - XLM-R: 24개의 Encoder layers, 16개의 Attention heads, 1024 Hidden size
15 | - M-BERT와 XLM보다 더 뛰어난 성능
16 | - XLM-R의 교차 언어 분류 태스크로 모델을 평가
17 | - 15개의 서로 다른 XNLI 데이터셋으로 평가
18 | - 가장 낮은 점수인 스웨덴어에서 M-BERT 50.4% → XLM-R 73.9%
19 | - XLM-R의 평균 정확도가 80.9%로 다른 모델보다 비교적 높음
20 |
21 | ## 언어별 BERT
22 |
23 | - 여러 언어 대신 특정 단일 언어만 이용해 BERT 학습
24 |
25 | ### 프랑스어 FlauBERT
26 |
27 | - 사용 말뭉치: Wikipedia, 도서, 내부 크롤링, WMT19, OPUS(오픈 소스 병렬 코퍼스)의 프랑스어 텍스트 등의 24개
28 | - Moses Tokenizer: URL, 날짜 등을 포함한 특수 토큰 보존
29 | - 전처리 및 토큰화 후 BPE 사용, vocab building
30 | - 50,000개의 Token
31 | - MLM만 수행, Dynamic masking 사용
32 | - small-cased, base-uncased, base-cased, large-cased
33 | - HuggingFace에서 사용 가능
34 | - FLUE(French Language Understanding Evaluation)
35 | - CLS-FR
36 | - PAWS-X-FR
37 | - XNLI-FR
38 | - French Treebank
39 | - FrechSemEval
40 |
41 | ### 스페인어 BETO
42 |
43 | - WWM(Whole Word Masking) + MLM
44 | - POS, NER-C, MLDoc, PAWS-X, XNLI로 테스트
45 | - HuggingFace에서 사용 가능
46 |
47 | ```python
48 | from transformers import pipeline
49 |
50 | predict_mask = pipeline(
51 | "fill-mask",
52 | model = "dccuchile/bert-base-spanish-wwm-uncased",
53 | tokenizer = "dccuchile/bert-base-spanish-wwm-uncased"
54 | )
55 |
56 | result = predict_mask('[MASK] los caminos llevan a Roma')
57 | ```
58 |
59 | ### 네덜란드어 BERTje
60 |
61 | - WWM과 MLM 및 SOP를 동시에 진행
62 | - 사용 말뭉치: TwNC(네덜란드 뉴스 말뭉치), SoNAR-500(다중 장르 참조 말뭉치), 네덜란드 위키피디아 텍스트, 웹 뉴스 및 서적
63 | - 100만 번의 iteration으로 학습
64 | - HuggingFace에서 사용 가능
65 |
66 | ### 독일어 BERT
67 |
68 | - Cloud TPU v2에서 9일 동안 Wikipedia text, 뉴스, OpenLegalData
69 |
70 | ### 중국어 BERT
71 |
72 | - 12개의 Encoder layers, 12개의 Attention heads, 768개의 hidden unit, 110M
73 | - WWM + MLM
74 | - WWM을 사용해 pretrain → 하위 단어가 masking 되면 하위 단어를 포함하는 전체 단어를 마스킹
75 | - LTP(Language Technology Platform)를 사용
76 | - LTP는 단어 분할, 형태소 분석, 구문 분석을 수행하는데 사용
77 | - 중국어 단어 경계를 식별하는 데도 이용
78 |
79 | ### 일본어 BERT
80 |
81 | - 일본어 Wikipedia를 사용해 WWM으로 학습
82 | - MeCab으로 Tokenization → Wordpiece Tokenizer로 subword를 얻음
83 |
84 | ### 핀란드어 FinBERT
85 |
86 | - M-BERT보다 성능이 좋음
87 | - Wikipedia에서 핀란드 텍스트의 비중은 3%에 불과
88 | - FinBERT는 핀란드어 뉴스 기사, 온라인 토론 및 인터넷 크롤링 텍스트로 학습
89 | - FinBERT-cased, FinBERT-uncased
90 | - WWM을 이용해 MLM과 NSP로 Pretrained
91 |
92 | ### 이탈리아어 UmBERTo
93 |
94 | - RoBERTa 아키텍쳐를 따름
95 | - MLM Task시에 Dynamic Masking 사용
96 | - NSP 제거 MLM만 사용
97 | - 큰 batch size 사용
98 | - Byte-level BPE Tokenizer
99 | - RoBERTa에 Sentencepiece + WWM 사용
100 |
101 | ### 포르투갈어 BERTimbau
102 |
103 | - brWaC: 포르투갈어 대규모 오픈 소스 말뭉치
104 | - WWM + MLM 100만 iteration
105 |
106 | ### 러시아어 RuBERT
107 |
108 | - M-BERT에서 Knowledge Distillation
109 | - 학습 전에 Word Embedding을 제외하고 RuBERT의 변수를 M-BERT 모델의 변수로 초기화
110 | - 러시아어 Wikipedia text와 뉴스 기사를 사용해 학습
111 | - Subword NMT로 텍스트를 subword로 나누는 데 사용
112 | - RuBERT의 Subword vocab은 M-BERT의 vocab에 비해 더 길고 더 많은 러시아어롤 구성
113 | - M-BERT와 RuBERT 어휘 모두에서 나타나는 일반적인 단어는 M-BERT의 임베딩으로 직접 사용 가능
--------------------------------------------------------------------------------
/summaries/chapter08/S-BERT.md:
--------------------------------------------------------------------------------
1 | # Sentence-BERT 및 domain-BERT 살펴보기
2 |
3 | > Speaker: 남수연(@mori8)
4 | >
5 | > 회사에서 molrae 쓰는 중
6 |
7 | ## Sentence-BERT
8 |
9 | Sentence-BERT는 vanila BERT/RoBERTa를 fine-tuning하여 문장 임베딩 성능을 우수하게 개선한 모델이다. BERT/RoBERTa는 STS 태스크에서도 좋은 성능을 보여주었지만 매우 큰 연산 비용이 단점이었는데, Sentence-BERT는 학습하는 데 20분이 채 걸리지 않으면서 다른 문장 임베딩보다 좋은 성능을 자랑한다.
10 |
11 |
12 |
13 | ### 등장 배경
14 |
15 | **기존의 BERT로는 large-scale의 유사도 비교, 클러스터링, 정보 검색 등에 많은 시간 비용이 들어간다.**
16 |
17 | - BERT로 유사한 두 문장을 찾으려면 두 개의 문장을 한 개의 BERT 모델에 넣어야 유사도가 평가된다.
18 | - 따라서 문장이 10000개 있으면 10C2 번의 연산 후에 유사도 랭킹을 얻을 수 있다.
19 | - 클러스터링이나 검색에서는 각 문장을 벡터 공간에 매핑하는데, BERT를 이용할 때는 단어 표현을 평균내거나 `[CLS]` 토큰의 값을 이용하지만 이랬을 때의 결과는 각 단어의 GloVe 벡터를 평균낸 것보다 나쁘다.
20 |
21 |
22 |
23 | ## Sentence-BERT의 문장 임베딩
24 |
25 | 1. BERT의 `[CLS]` 토큰의 표현 벡터를 문장 표현으로 사용한다.
26 | 2. BERT의 모든 단어의 표현 벡터를 평균 풀링하여 만든 벡터를 문장 표현으로 사용한다.
27 | 3. BERT의 모든 단어의 표현 벡터를 최대 풀링하여 만든 벡터를 문장 표현으로 사용한다.
28 |
29 | Sentence-BERT(이후 SBERT로 표기)는 BERT의 출력에 풀링 연산을 추가한 모델이며, 풀링 방법은 `[CLS]` 토큰의 결과를 사용하는 방법, 모든 출력 벡터를 평균내어 사용, 출력 벡터의 max-over-time*을 계산해 사용하는 방법이 있다. 기본적으로 SBERT는 평균 풀링을 사용하며, 평균 풀링으로 문장 표현을 얻으면 이 표현은 본질적으로 모든 단어의 의미를 갖는다. 반면 최대 풀링으로 문장 표현을 얻을 경우 문장 표현은 본질적으로 중요한 단어의 의미를 갖는다.
30 |
31 | > Max-over-time pooling: 문장의 길이가 다 다르면 문장마다의 feature map 개수가 달라지는데, 모든 문장마다 하나의 값을 갖도록 feature map 벡터 중 가장 큰 값 하나만 사용하는 것
32 |
33 |
34 |
35 | ## Fine Tuning 전략: 문장 쌍 분류, 회귀 태스크
36 |
37 | 신체의 일부를 공유하는 샴 쌍둥이처럼, 샴 네트워크는 두 네트워크가 weight를 공유한다. SBERT는 동일한 사전 학습된 BERT 모델 2개를 사용하여 문장 1의 토큰은 한 BERT로, 문장 2의 토큰은 또 다른 BERT로 입력하고 주어진 문장의 표현을 계산한다. 두 문장을 `[SEP]`으로 구분하여 한 BERT 모델에 같이 집어넣는 게 아니라, 같은 가중치를 갖는 서로 다른 BERT 모델 2개에 각각 넣는 것이다.
38 |
39 |
40 |
41 | ## Objective Functions
42 |
43 | 
44 |
45 | SBERT 모델의 구조는 학습 데이터에 따라 다르다. 아래 구조에 따라 목적 함수와 모델 구조를 달리 하였다.
46 |
47 | - 두 문장의 출력값인 u, v 그리고 element-wise 차이값인 |u-v|를 concatenate한 후 파라미터를 추가하여 학습한다.
48 | - 실제 inference할 때나, regression 방식의 loss function을 쓸 때는 cosine-similarity를 이용한다. Training할 때, 계산된 cosine similarity와 gold label 간의 MSE를 minimize하는 방식으로 학습했다.
49 |
50 |
51 |
52 | ### Classification Objective Function
53 |
54 | 두 문장이 유사한지(1), 유사하지 않은지(0) 판단하는 태스크를 위한 모델이다. 두 문장 임베딩 *u*와 *v*를 그 차이 ∣*u*−*v*∣와 concat해 3*n* 차원의 텐서를 만들고, 이를 가중치 *W**t*∈R3*n*×*k*에 곱한다. 이를 softmax함수에 넣으면 *k*개 label에 대한 분류 작업이 가능해진다. loss는 cross-entropy로 설정했다.
55 |
56 | $$O=softmax(W_t(u,v,∣u−v∣))$$
57 |
58 |
59 |
60 | ### Regression Objective Function
61 |
62 | 회귀 태스크의 목표는 주어진 두 문장 사이의 의미 유사도를 예측하는 것이다. 두 문장의 임베딩($u$, $v$) 사이의 코사인 유사도를 계산한다.
63 |
64 |
65 |
66 | ### Triplet Objective Function
67 |
68 | #### Siamese, Triplet의 등장 배경: One-shot
69 |
70 | 조금의 데이터만으로도 학습할 수 있도록 하는 것이 `Few-shot`, 한 장의 사진만으로 학습하도록 하자는 게 `One-shot`
71 |
72 |
73 |
74 | $$max(∣∣s_a−s_p∣∣−∣∣s_a−s_n∣∣+ϵ,0)$$
75 |
76 | anchor/positive/negative 문장 *a*,*p*,*n*에 대해 triplet loss는 모델이 *a*와 *p* 사이 거리가 *a*와 *n*사이 거리보다 작게 하도록 학습시킨다. $s_x$는 문장 *x*의 임베딩이고, ∣∣⋅∣∣은 거리고, *ϵ*은 margin이다. margin은 *s**p*가 *s**n*보다 최소한 *ϵ*만큼 *s**a*에 가깝도록 하는 장치이다. 이 논문에서는 Euclidean 거리를 단위로 *ϵ*=1로 설정했다.
77 |
78 |
79 |
80 | ## Evaluation
81 |
82 | 
83 |
84 | - 보다시피 BERT의 output을 그대로 쓰는 건 성능이 별로다. InferSent* - GloVe보다 못한 걸 알 수 있다.
85 | - 제안된 siamese 네트워크 구조와 fine-tuning 메커니즘은 InferSent나 Universal Sentence Encoder를 유의미하게 앞서는 결과를 내었다. SBERT가 좋은 성적을 내지 못한 유일한 데이터셋은 SICK-R이다.
86 | - Universal Sentence Encoder는 뉴스, QA 페이지, 토론 포럼처럼 SICK-R 벤치마킹에 적합한 데이터셋에 학습되었다. 반면 SBERT는 위키피디아와 NLI 데이터에만 학습되었다.
87 | - SRoBERTa는 성능이 좋긴 한데, SBERT에 비해 큰 차이를 보이진 않았다.
88 |
89 | > InferSent는 siamse BiLSTM에 max pooling을 적용한 문장 임베딩 모델
90 |
91 |
92 |
93 | ## References
94 |
95 | - https://velog.io/@ysn003/%EB%85%BC%EB%AC%B8-Sentence-BERT-Sentence-Embeddings-using-Siamese-BERT-Networks
96 | - http://mlgalaxy.blogspot.com/2020/09/sentence-bert-sentence-embeddings-using.html
97 | - https://tyami.github.io/deep%20learning/Siamese-neural-networks/
98 |
--------------------------------------------------------------------------------
/summaries/chapter08/chapter08_domain-BERT.md:
--------------------------------------------------------------------------------
1 | # Chapter 8 sentence-BERT 및 domain-BERT 살펴보기
2 |
3 | ## 내용
4 |
5 | - sentence-BERT
6 | - 지식 증류로 다국어 임베딩 학습
7 | - domain-BERT (ClinicalBERT 및 BioBERT)
8 |
9 | ## 지식 증류를 이용한 다국어 임베딩 학습
10 |
11 | *Q. 영어 외의 다른 언어에는 어떻게 sentence-BERT를 사용할까?*
12 |
13 | *A. sentence-BERT에서 생성된 단일 언어 문장 임베딩을 **지식 증류**를 통해 다국어로 만들어 다양한 언어에 sentence-BERT를 적용할 수 있다.*
14 |
15 | sentence-BERT 지식 ➡︎ 다국어 모델 (e.g. XLM-R) ➡︎ 다국어 모델이 사전 학습된 sentence-BERT와 동일한 임베딩 형성
16 |
17 | 학생 모델 S로 계산한 소스 문장(s_j) 표현과 타깃 문장(t_j) 표현 모두 교사 모델 T로 계산한 소스 문장(s_j) 표현과 동일해지는 방향으로 다음 속성을 학습
18 |
19 | 1. 벡터 공간이 언어 간 정렬 i.e., 다른 언어의 같은 문장은 가까이 위치
20 | 2. 교사 모델 T로 계산한 소스 언어의 벡터 공간 특성을 채택하여 다른 언어로 전이
21 |
22 |
23 |
24 | 

25 |
26 | : 미니배치 B에 대한 평균 제곱 오차(MSE)들을 최소화하도록 학생 네트워크 학습
27 |
28 | ## domain-BERT
29 |
30 | *BERT : 일반 위키피디아 말뭉치를 사용해 BERT를 사전 학습시키고 이를 파인튜닝해 다운스트림 태스크에 사용*
31 |
32 | 일반 위키피디아 말뭉치에서 사전학습된 BERT 사용 vs 특정 도메인 말뭉치에서 BERT를 처음부터 학습
33 |
34 | ➡︎ BERT가 특정(일반 위키피디아 말뭉치에 없을 수도 있는) 도메인 임베딩을 학습시키는데 도움
35 |
36 | ### ClinicalBERT
37 |
38 | 📄 [ClinicalBERT: Modeling Clinical Notes and Predicting Hospital Readmission](https://arxiv.org/pdf/1904.05342.pdf)
39 |
40 | 임상 텍스트의 콘텍스트 표현을 이해하기 위해 대규모 임상 말뭉치에서 사전학습된 임상 domain-BERT 모델
41 |
42 |

43 |
44 | #### 사전 학습
45 |
46 | - Medical Information Mart for Intensive Care III (MIMIC-III) dataset 사용
47 |
48 | - BERT와 마찬가지로 MLM과 NSP 태스크를 이용해 사전 학습
49 |
50 | #### 파인 튜닝
51 |
52 | 재입원 예측, 입원 기간, 사망 위험 추정, 진단 예측 등 다양한 다운스트림 태스크에 맞춰 파인 튜닝
53 |
54 | 
55 |
56 |

57 |
58 | *e.g. 30일 이내 재입원 예측 테스크*
59 |
60 | - 사전학습된 ClincalBERT에 임상 메모를 입력하고 임상 메모의 표현 반환
61 | - `[CLS]` 토큰의 표현을 가져와 분류기(피드포워드 + 시그모이드 활성화 함수)에 입력
62 | - 분류기는 30일 이내에 환자가 다시 입원할 확률 반환
63 |
64 | #### Empirical Study
65 |
66 | **Empirical Study I: Language Modeling and Clinical Word Similarity**
67 |
68 | - Clinical language model에서 ClinicalBERT가 BERT보다 좋은 성능
69 |
70 |

71 |
72 | - 임상 단어 유사도 추출
73 |
74 | - ClinicalBERT에서 배운 표현을 경험적으로 평가하기 위해 의학 용어 표현 계산
75 |
76 |

77 |
78 | - 신체기관이 서로 관련된 의학 용어끼리 가까이 있는 것을 확인 가능
79 |
80 | ➡︎ ClinicalBERT의 표현이 의학 용어에 대한 콘텍스트 정보를 갖고 있음을 나타냄
81 |
82 | **Empirical Study II: 30-Day Hospital Readmission Prediction**
83 |
84 | - Scalable Readmission Prediction
85 |
86 | **💡 BERT 최대 토큰의 길이 512보다 더 많은 토큰으로 구성된 경우?**
87 |
88 | - 512보다 더 많은 토큰으로 구성된 긴 시퀀스를 여러 서브시퀀스로 분할
89 | - 각 서브시퀀스를 모델에 입력한 후 모든 서브시퀀스를 개별적으로 예측
90 | - 다음 식을 이용해 점수 계산 :

91 | - 재입원 예측과 관련된 서브시퀀스 : 확률이 높은 것
92 | - 노이즈가 포함된 서브시퀀스 방지를 위해 평균 확률 사용
93 | - 평균 확률에 중요성 부여
94 |
95 | ### BioBERT
96 |
97 | 📄 [BioBERT: a pre-trained biomedical language representation model for biomedical text mining](https://arxiv.org/pdf/1901.08746.pdf)
98 |
99 | 생물 의학 텍스트 이해를 위해 대규모 생물 의학 코퍼스에서 사전학습된 생물 의학 domain-BERT
100 |
101 | 
102 |
103 | #### 사전 학습
104 |
105 | - 생물 의학 도메인 텍스트를 이용해 사전학습
106 |
107 | - PubMed, PMC
108 |
109 | - 사전학습 전에 먼저, 영어 위키피디아 및 토론토 책 말뭉치 데이터셋으로 구성된 일반 도메인 말뭉치를 사용해 사전 학습된 일반 BERT로 BioBERT의 가중치 초기화
110 |
111 | - 워드피스 토크나이저로 토큰화
112 |
113 | - 생물 의학 코퍼스의 새로운 어휘를 사용하는 대신, BERT 기반 모델에서 사용되는 원래 어휘로 워드피스 어휘를 구성
114 |
115 | - BioBERT와 BERT 간의 호환성
116 |
117 | - 본 적 없는 단어도 원래 BERT 기반 어휘를 사용해 표현하고 파인튜닝
118 |
119 | - 대소문자가 있는 어휘를 사용하는 것이 다운스트림 태스크에서 더 좋은 성능을 얻을 수 있음을 발견
120 |
121 | #### 파인 튜닝
122 |
123 | 📌 코드 [github.com/dmis-lab/biobert](https://github.com/dmis-lab/biobert?fbclid=IwAR3te48b9-SsBBmybH8MrQMLxX5RlDbYTfpBZQGLp5ki1B8jq-2M15t3skA)
124 |
125 | **개체명 인식(NER) 태스크를 위한 BioBERT**
126 |
127 | - 생물 의학 코퍼스에서 특정 도메인의 다양한 고유명사 인식
128 | - BERT를 파인튜닝하는 법과 동일
129 | - 데이터셋
130 | - 질병 관련된 개체명: NCBI, 2010 i2b2/VA, BC5CDR
131 | - 약물 및 화학 관련된 개체명: BC5CDR, BC4CHEMD
132 | - 유전자와 관련된 개체명: BC2GM, JNLPBA
133 | - 종과 관련된 개체명: LINNAEUS, Species-800
134 |
135 | **관계 추출(RE)을 위한 BioBERT**
136 |
137 | - 생물 의학 코퍼스에서 명명된 개체들의 관계 분류
138 |
139 | - `[CLS]` 토큰 표현을 사용하는 BERT의 sentence classifier 사용
140 |
141 | **질문-응답(QA)을 위한 BioBERT**
142 |
143 | - BioASQ 데이터셋으로 파인튜닝
144 | - 생물 의학 질문-응답 데이터셋으로 널리 사용
145 | - SQuAD의 형식과 동일
146 | - BERT를 파인튜닝하는 법과 동일
147 |
148 |
--------------------------------------------------------------------------------
/summaries/chapter09/chapter09_BART.md:
--------------------------------------------------------------------------------
1 | # Chapter 9.2~
2 |
3 | BART에 대해서 알아보고 Hugging Face의 BERT관련 라이브러리를 다룬다.
4 |
5 |
6 |
7 | ## BART
8 |
9 | BERT는 bidirection encoder로 MASK token을 예측하는데, 이러한 구조로 인해 generation task에서 BERT의 사용이 어렵다. 왜냐하면 각각의 MASK token이 softmax/피드포워드 네트워크를 통해 독립적으로 예측되기 때문이다.
10 |
11 | GPT는 autoregressive한 구조로 다음 token을 예측할 수 있지만, BERT처럼 bidirection이 아니다.
12 |
13 |
14 |
15 | ### BART Architecture
16 |
17 | 그래서 두 architecture를 합친다.
18 |
19 | 
20 |
21 | BART는 BERT와 GPU 모델의 구조를 결합하였기 때문에, bidirection으로 문장을 살펴보며 attention representation을 얻어 디코더를 통해 seq2seq 구조로 generation을 수행한다.
22 |
23 | **이 때문에 MLM과는 달리 여러 task에 대해 응용성이 높다**
24 |
25 |
26 |
27 | BART는 seq2seq transformer 구조를 사용했고, GeLUs 활성화 함수를 사용한다. (파라미터 초기화는 N(0, 0.2)) 인코더와 디코더의 layer 수는 같으며, bsae model은 6 layer, large model은 12 layer를 사용한다. 기존의 트랜스포머 디코더와 동일하게, 디코더의 각 레이어에서는 인코더의 마지막 hidden layer와 cross-attention을 한다.
28 |
29 | > self-attention: keys와 values가 queries와 똑같은 임베딩에서 나왔을 때
30 | >
31 | > cross-attention: keys와 values가 queires와 다른 임베딩에서 나왔을 때
32 |
33 |
34 |
35 | ### 노이징 기술 (Pretraining BART)
36 |
37 | BART에서 알아볼 수 있는 핵심은 noising 기술의 유연함이다. 다양한 변형 noising 기법들을 적용시킬 수 있으며, 이 중에서는 문장의 순서를 바꾸거나, 길이를 변경하는 등의 방법론도 있다. 가장 좋은 성능을 보이는 노이징 기법은 문장의 순서를 랜덤하게 섞고, 임의의 길이의 텍스트를 단일 마스크 토큰으로 교체하는 것이다.
38 |
39 | > 모델이 전체적인 문장 길이에 대해 학습해야 하고, 변형된 입력에 많은 집중을 요구하는 효과가 있다고 한다.
40 |
41 |
42 |
43 | 
44 |
45 | **토큰 마스킹(Token Masking)**
46 |
47 | - 랜덤하게 바뀐 [MASK] 토큰 맞추기
48 |
49 | **토큰 삭제(Token Deletion)**
50 |
51 | - 토큰이 랜덤하게 제거된다.
52 | - 모델은 어떤 위치의 토큰이 없어졌는지에 대해서도 맞춰야 한다.
53 |
54 | **토큰 채우기(Text Infilling)**
55 |
56 | - 람다 3을 따르는 포아송 분포에서 span의 길이가 샘플링되고, 각 span은 한개의 [MASK] 토큰으로 치환된다.
57 | - span의 길이가 0일 때도 [MASK] 토큰이 생성된다.
58 | - 모델은 [MASK]에 해당하는 단어들을 맞춰야 한다. 즉 얼마나 많은 토큰이 없어졌는지 예측해야 한다.
59 |
60 | **문장 셔플(Sentence Permutation)**
61 |
62 | - 문장의 순서를 랜덤으로 섞는다.
63 | - 모델은 섞인 토큰들을 원래의 순서로 배열해야 한다. (XLnet에서 영감)
64 |
65 | **문서 회전(Document Rotation)**
66 |
67 | - 하나의 토큰이 랜덤하게 선택되고, 해당 토큰이 문서의 시작지점이 된다.
68 | - 모델은 해당 문서의 시작점을 찾아야 한다.
69 |
70 |
71 |
72 | ### Fine-tuning BART
73 |
74 | 번역 테스크?? 몇개의 추가적인 transformer 레이어를 쌓아 올리는 것으로 기계 번역의 새로운 방법론을 제시하기도 하였음. 추가된 레이어는 외국어를 noise가 적용된 영어로 번역하는 것이 학습되며, BART 전반적으로 학습되게 되어 BART를 사전 학습된 target-side 언어 모델로 사용ㅎ나다. WMT 루마니안-영어 벤치마크에서 1.1 BELU만큼 성능이 향상되었다고 한다.
75 |
76 |
77 |
78 | 
79 |
80 |
81 |
82 | **Sequence Classification Tasks - 시퀀스 단위의 분류 문제**
83 |
84 | - 시퀀스 분류 문제. BERT에서 [CLS] 토큰으로 classification task를 수행하는 것에서 영감. BART에서는 디코더에서 마지막 토큰을 추가하여 해당 토큰의 representation이 전체 입력과 attention을 수행할 수 있게 한다. -> output은 모든 입력을 반영
85 |
86 | - CoLA: 문장이 문법적으로나 영어적으로 합당한지 분류
87 |
88 | **Token Classification Tasks - 토큰 단위의 분류 문제**
89 |
90 | - 디코더 가장 위의 hidden state를 각 토큰의 representation으로 사용 -> classification
91 | - SQuAD: 정답에 해당되는 start point, end point 토큰 찾기
92 |
93 | **Sequence Generation Tasks - 시퀀스 생성 문제**
94 |
95 | - Abstractive QA(question answering), 요약 등의 generation task
96 | - 이러한 테스크는 입력 시퀀스의 내용을 조정하는 특징이 있는데, denoising pre-training objective와 밀접하게 연관되어 있다고 한다.
97 |
98 | **Machine Translation**
99 |
100 | - 몇개의 추가적인 transformer layer를 쌓아 올려 기계 번역의 새로운 방법론 제시 -> BART 전체를 decoder로 사용
101 | - BART 인코더의 embedding layer를 새롭게 초기화된 인코더로 교체 -> 해당 인코더를 학습시키는 것으로 영어가 아닌 다른 단어들을 영어로 매핑하여 BART가 외국어를 denoise할 수 있게 한다.
102 | - 인코더를 2가지 step으로 학습시킨다.
103 | - BART 모델의 output에 대한 cross-entropy loss 사용
104 | - step1) 새롭게 초기화된 인코더, BART의 positional embedding, 첫번째 인코더 layer의 self-attention input projection matrix 학습
105 | - step2) 모든 모델 parameter를 작은 iteration으로 학습
106 |
107 |
108 |
109 | ### Comparing pre-training objectives
110 |
111 | 실험한 언어 모델의 종류
112 |
113 | - Language Model
114 | - Permuted Language Model
115 | - Masked Language Model
116 | - Multitask Masked Language Model
117 | - Masked Seq2Seq
118 |
119 |
120 |
121 | **Tasks**
122 |
123 | **SQuAD**
124 |
125 | - 위키 문단에 대한 QA task로, 위키피디아에서 가져온 본문과 질문이 주어지면, 주어진 본문으로부터 정답에 해당되는 span을 찾아야 한다. -> BART에서는 start point, end point의 두개를 예측하는 분류기 사용
126 |
127 | **MNLI**
128 |
129 | - NLI task와 비슷하며, 이전 문장과 이후 문장의 관계 성립 예측. -> BART에서는 두 개의 문장을 [EOS] token으로 합치고, [EOS] 토큰의 representation으로 classification 수행
130 |
131 | **[ELI5](https://facebookresearch.github.io/ELI5/)**
132 |
133 | - Long form QA task.
134 |
135 | **[XSum](https://arxiv.org/pdf/1808.08745v1.pdf)**
136 |
137 | - 뉴스 요약 테스크 -> 함축된 요약을 만들어야 한다.
138 |
139 | **ConvAI2**
140 |
141 | - 대화의 답변 만들기 -> context와 화자가 주어진다.
142 |
143 | **CNN/DM**
144 |
145 | - 뉴스 요약 테스크 -> 요약본이 입력 문서와 밀접하게 연관되어 있어 XSum과는 약간 다르다.
146 |
147 | 
148 |
149 |
150 |
151 | ### Result
152 |
153 | - **Performance of pre-training methods varies significantly across tasks**
154 |
155 | - **Token masking is crucial**
156 |
157 | - **Left-to-right pre-training improves generation**
158 |
159 | - **Bidirectional encoders are crucial for SQuAD**
160 |
161 | - **The pre-training objective is not the only important factor**
162 |
163 | - **Pure language models perform best on ELI5**
164 |
165 | - **BART achieves the most consistently strong performance.**
166 |
167 |
168 |
169 |
170 |
171 | ## BERT 라이브러리 탐색
172 |
173 | BERT 관련 모델을 쉽게 학습하거나 pre train model을 쉽게 사용 할 수 있는 라이브러리들이 있다.
174 |
175 |
176 |
177 | ### ktrain
178 |
179 | https://github.com/amaiya/ktrain
180 |
181 |
182 |
183 | ### bert-as-service
184 |
185 | https://github.com/hanxiao/bert-as-service
186 |
187 |
--------------------------------------------------------------------------------
/summaries/chapter09/chapter09_VideoBERT.md:
--------------------------------------------------------------------------------
1 | # Chapter 9. VideoBERT
2 |
3 | ## VideoBert로 언어 및 비디오 표현 학습
4 |
5 | **VideoBERT** 📄 [VideoBERT: A Joint Model for Video and Language Representation Learning](https://arxiv.org/pdf/1904.01766.pdf)
6 |
7 | 
8 |
9 | - 영상과 언어의 표현을 동시에 배우는 최초의 BERT 모델
10 | - 이미지 캡션 생성, 비디오 캡션, 비디오의 다음 프레임 예측 등과 같은 태스크에 사용
11 |
12 | ### VideoBERT 사전 학습
13 |
14 | - **MLM(cloze 태스크)과 언어-시각(linguistic-visual) 정렬이라는 새로운 태스크를 사용하여 사전학습**
15 |
16 | - 데이터: 교육용 비디오(e.g., 요리 비디오)
17 |
18 | - 교육자의 말과 해당 시각 자료(영상)가 서로 일치해 언어와 비디오의 표현을 동시에 배우는데 도움
19 |
20 | - 비디오에서 언어 토큰과 시각 토큰을 추출하여 학습에 사용
21 |
22 | - 언어 토큰 추출 방법
23 |
24 | 1. 비디오에 사용된 오디오를 추출
25 |
26 | 2. 오디오를 텍스트로 변환
27 |
28 | **자동 음성 인식**(automatic speech recognition) 툴킷을 활용
29 | _Cf. https://cloud.google.com/speech-to-text_
30 |
31 | 3. 텍스트를 토큰화하면 언어 토큰 생성
32 |
33 | - 시각 토큰 추출 방법
34 |
35 | 1. 비디오의 이미지 프레임을 20fps(초당 프레임)로 샘플링
36 | 2. 이미지 프레임을 1.5초의 구간으로 시각 토큰들로 변환
37 |
38 | - 입력 토큰
39 |
40 | 1. 언어와 시각 토큰 결합
41 |
42 | 특수 토큰 `[>]` 으로 언어 및 시각적 토큰 결합
43 |
44 | 2. 언어 토큰의 시작 부분에 `[CLS]` 토큰 추가, 시각 토큰 끝에만 `[SEP]` 토큰 추가
45 |
46 | 3. 언어 및 시각 토큰 중 몇 가지 토큰들을 무작위로 마스킹
47 |
48 | - **cloze 태스크**
49 |
50 | - VideoBERT에서 반환된 마스크된 표현을 분류기(피드포워드 + 소프트맥스)에 입력하면, 분류기는
마스크된 토큰 예측
51 |
52 | 
53 |
54 | - **언어-시각 정렬**
55 |
56 | - NSP 태스크와 유사한 분류 태스크
57 |
58 | - 언어와 시각 토큰이 시간적으로 서로 정렬되어 있는지 예측
59 |
60 | =
텍스트(언어 토큰)가 비디오(시각적 토큰)와 일치하는지 여부 예측
61 |
62 | - `[CLS]` 토큰의 표현을 가져온 다음 주어진 언어 및 시각 토큰이 일시적으로 정렬되는지 여부를 분류하는 분류기에 입력
63 |
64 | _Cf. NSP는 `[CLS]` 표현을 이용해 주어진 문장 다음에 출현하는 문장이 다음 문장인지 예측_
65 |
66 | - **최종 사전 학습 목표**
67 |
68 | - 세 가지 목표: 텍스트, 비디오, 비디오-텍스트
69 |
70 | - **텍스트**
71 |
72 | 언어 토큰을 마스킹하고 마스크 언어 토큰을 예측하도록 모델을 학습시켜서 모델이 언어 표현을 더 잘 이해하도록 함
73 |
74 | - **비디오**
75 |
76 | 시각 토큰을 마스킹하고 마스크된 시각 토큰을 예측하도록 모델을 학습시켜서 모델이 비디오 표현을 더 잘 이해하도록 함
77 |
78 | - **비디오-텍스트**
79 |
80 | 언어 및 시각적 토큰을 마스킹하고 모델을 학습시켜 언어 및 시각 토큰을 예측하고, 언어-시각 정렬을 학습하게 해서 모델이 언어와 시각 토큰 간의 관계를 이해하게 함
81 |
82 | - 최종 사전 학습 목표: 세 가지 방법을 모두 활용한 가중치 조합
83 | - 4개의 TPU를 사용해 2일 동안 50만 번 반복해 최종 사전 학습 목표를 수행하며 학습
84 |
85 | ### 데이터 소스 및 전처리
86 |
87 | **데이터셋**
88 |
89 | - 유튜브의 교육용 비디오 사용
90 |
91 | - 유튜브 동영상 주석(annotation) 시스템을 이용해 요리와 관련된 유튜브 동영상 추출
92 |
93 | - 15분 미만 영상 길이, 31만 2000개의 동영상
94 |
95 | - 유튜브 API에서 제공하는 자동 음성 인식 도구(ASR)를 사용해 텍스트 추출
96 |
97 | - 텍스트를 타임 스탬프와 함께 갖고오기 위함 (비디오에 사용된 언어에 대한 정보도 반환)
98 |
99 | - 31만 2000개의 동영상 중 18만 개의 동영상에만 ASR을 적용할 수 있었고, 그 중 영어로 된 동영상은 12만개로 추정
100 |
101 | ➡︎ 텍스트 및 비디오-텍스트 목표를 위해 12만 개의 비디오만 사용하고, 비디오 목표는 31만 2000개의 비디오 사용
102 |
103 | **비디오 및 언어 전처리**
104 |
105 | - 시각 토큰
106 | 1. 비디오의 이미지 프레임을 20fps(초당 프레임)로 샘플링
107 | 2. 이미지 프레임을 1.5초의 구간으로 시각 토큰들로 변환 (= 30-frame clip 생성)
108 | 3. 각 30-frame clip에 사전 학습된 비디오 컨볼루셔널 뉴럴넷을 적용해 특징 추출
109 | 3. 계층적 k-평균 알고리즘을 적용해 시각 특징 토큰화
110 | - 언어 토큰
111 | 1. 상용 LSTM 기반 언어 모델을 이용해 각 ASR 단어 시퀀스에 구두점을 추가하여 단어 스트림을 문장으로 나눔
112 | 2. 각 문장에 대해 BERT의 텍스트 전처리와 동일한 방식을 따르며, 텍스트 토큰화
113 |
114 | > 💡 자연스럽게 문장으로 나뉘는 언어와 달리, 비디오는 어떻게 의미론적으로 나눌까?
115 | >
116 | > - 휴리스틱 사용
117 | > - ASR 문장이 존재할 경우, 문장의 시작 및 종료 timestamp 사이에 해당하는 비디오 토큰을 세그먼트로 취급
118 | > - ASR 문장이 존재하지 않을 경우, 하나의 세그먼트를 16개의 토큰으로 취급
119 |
120 | ### VideoBERT의 응용
121 |
122 | 사전학습된 VideoBERT 모델을 사용해 다양한
다운스트림 태스크에 맞춰 파인튜닝
123 |
124 | - 시각 토큰을 입력해 상위 3개의 다음 시각 토큰 예측
125 | - 텍스트가 주어지면 해당하는 비디오 생성
126 | - 비디오에 자막 생성
127 |
128 | ## Transformers in vision
129 |
130 | 📄 [Transformers in Vision: A Survey](https://arxiv.org/pdf/2101.01169.pdf)
131 |
132 | - Computer Vision 분야에서 Transformer가 활용된 연구들 정리한 survey paper
133 |
134 | ### Background
135 |
136 | RNN to Transformer in NLP ⇨ CNN에 self-attention 적용 ⇨ Transformer 모델 자체를 CV 태스크에 사용
137 |
138 | ### Task
139 |
140 | 
141 |
142 | ***Table 1 from Transformers in Vision: A survey***
143 |
144 | *A summary of key design choices adopted in different variants of transformers for a representative set of computer vision applications. The main changes relate to specific loss function choices, architectural modifications, different position embeddings and variations in input data modalities.*
145 |
146 | ### Model
147 |
148 | #### Transformers for Multi-Modal Tasks
149 |
150 | *Multi-modal learning: 다양한 데이터 타입, 데이터 형태, 다양한 특성을 갖는 데이터를 사용하는 학습법*
151 |
152 | - Transformer 모델은
vision-language 태스크에도 광범위하게 사용
153 | - visual question answering (VQA)
154 | - visual commonsense reasoning (VCR)
155 | - cross-modal retrieval
156 | - image captioning
157 |
158 | 
159 |
160 | *An overview of Transformer models used for multi-modal tasks in computer vision*
161 |
162 | #### Vision Transformer (ViT)
163 |
164 | 📄 [AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE](https://arxiv.org/pdf/2010.11929.pdf)
165 |
166 | 
167 |
168 | - CNN 구조였던 computer vision 문제를 Transformer 구조로 대체
169 | - Transformer 구조를 사용한 Architecture가 수 많은 SOTA를 찍고 있으며, **ViT 논문이 그 시작점**
170 | - Transformer 구조를 활용하여 image classification을 수행한 방법론
171 | - 더 많은 데이터를 더 적은 비용으로 사전 학습
172 |
173 | - 구조
174 |
175 | - Transformer encoder 사용
176 | - 한 이미지를 여러 patch로 분할 (patch를 단어같이 취급)
177 | - patch, classification token, position embedding을 입력하여 최종 classification 결과 생성
178 |
179 | > CNN vs Transformer
180 | >
181 | > - Layer
182 | >
183 | > - CNN: 이미지 전체의 정보를 통합하기 위해서는 몇 개의 layer 통과
184 | > - Transformer: 하나의 layer로 전체 이미지 정보 통합 가능
185 | >
186 | > - Inductive bias
187 | >
188 | > _새로운 데이터에 대해 좋은 성능을 내기 위해 모델에 사전적으로 주어지는 가정_
189 | >
190 | > - CNN: 2차원의 지역적인 특성 유지, 학습 후 weight 고정
191 | >
192 | > → 인접한 픽셀 간 강한 상관관계가 있다는 특징을 살려 inductive bias가 적절하게 만들어짐으로써 이미지 특징 효과적 추출
193 | >
194 | > - Transformer: 1차원 벡터로 만든 후 self attention (2차원의 지역적인 정보 유지 x), weight가 input에 따라 유동적으로 변함
195 | >
196 | > → inductive bias가 적고, 모델의 자유도가 높아 데이터로부터 더 많은 정보를 얻을 수 있음
197 |
198 | - 한계
199 |
200 | - 학습 데이터가 충분하지 않을 경우 CNN 모델보다 성능 감소 (∵ inductive bias ↓)
201 |
202 | ➡︎ 대용량의 학습 자원과 데이터가 필요
203 |
204 | #### Data efficient image Transformer (DeiT)
205 |
206 | 📄 [Training data-efficient image transformers & distillation through attention](https://arxiv.org/abs/2012.12877)
207 |
208 | - 많은 데이터가 필요한 ViT 한계 극복
209 | - Knowledge Distilation
210 | - Data Augmentation
211 |
212 | ## 참고 자료
213 |
214 | #### 개념
215 |
216 | - [Multimodal Deep Learning](https://towardsdatascience.com/multimodal-deep-learning-ce7d1d994f4)
217 |
218 | #### 세미나
219 |
220 | - [DMQA Transformer in Computer Vision](http://dmqm.korea.ac.kr/activity/seminar/316)
221 |
222 | #### 논문
223 |
224 | - [VideoBERT: A Joint Model for Video and Language Representation Learning](https://arxiv.org/pdf/1904.01766.pdf)
225 | - [Transformers in Vision: A Survey](https://arxiv.org/pdf/2101.01169.pdf)
226 | - **리뷰**
227 | - [Transformers in Vision: A Survey [1] Transformer 소개 & Transformers for Image Recognition](https://hoya012.github.io/blog/Vision-Transformer-1/)
228 | - [AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE](https://arxiv.org/pdf/2010.11929.pdf)
229 | - **리뷰**
230 | - https://engineer-mole.tistory.com/133
231 | - https://kmhana.tistory.com/27
232 |
233 | #### 책
234 |
235 | - [구글 BERT의 정석](http://www.yes24.com/Product/Goods/104491152)
236 |
--------------------------------------------------------------------------------
/summaries/chapter10/chapter10_kobert_kogpt2_kobart.md:
--------------------------------------------------------------------------------
1 | # Chapter 10 한국어 언어 모델: KoBERT, KoGPT2, KoBART
2 |
3 | - 다국어 모델들은 한국어 데이터의 부족 때문에 좋은 성능을 보이지 못함
4 |
5 | ## KoBERT
6 |
7 | - 한국어 위키피디아에서 500만 개의 문장과 5400만 개의 단어 학습
8 | - Huggingface, MXNet-Gluon, ONNX 등 여러 플랫폼에서 사용 가능
9 | - Sentencepiece를 이용해 Tokenizer 학습
10 | - 8,002개의 vocab size
11 |
12 | ## KoGPT2
13 |
14 | - 한국어에 특화된 GPT-2 모델
15 | - 주어진 텍스트를 기반으로 다음 단어를 잘 예측할 수 있도록 학습됨
16 | - 문장 생성에 최적화
17 | - 125M parameter
18 | - 한국어 위키피디아, 뉴스, 모두의 말뭉치 v1.0, 청와대 국민청원 등 40GB의 한국어 텍스트 사용
19 | - BPE Tokenizer
20 | - 51,200 vocab
21 | - 이모티콘, 이모지도 추가
22 |
23 | ## KoBART
24 |
25 | - text infilling 노이즈 함수만 적용
26 | - 40GB 이상의 한국어 텍스트로 사전 학습
27 | - Denoising AutoEncoder
28 | - 6 encoder layers
29 | - 6 decoder layers
30 | - 16 attention heads
31 | - 768 FFN hidden unit
32 | - 120M parameters
--------------------------------------------------------------------------------