SlideShare une entreprise Scribd logo
1  sur  65
Télécharger pour lire hors ligne
PyCon Korea 2019
한국어 띄어쓰기 프로그램 도전기
Taekyoon Choi
(tgchoi03@gmail.com)
Contents
• 서론
• 띄어쓰기 프로그램
• 띄어쓰기 모델 개발
• Korean BERT 적용
• 결론
서론
자연어처리에서 띄어쓰기
• 자연어처리에서는 텍스트를 토큰 단위로 구분하여 다룸
• 쉽게 토크나이징을 할 수 있는 방법은 띄어 쓴 단어를 구분하는 것
• 한국어에서 띄어쓰기는 텍스트 의미를 구분하는데 큰 영향을 줄 수 있음
띄어쓰기로 인한 문제
• 문맥 없이 띄어쓰기로 의미 구분을 명확히 하기 어려움
>>> text = '학교종이 땡땡땡’
>>> print(text.split())
[‘학교종이’, ‘땡땡땡’]
# [‘학교종이’] or [‘학교’,‘종이’]?
띄어쓰기로 인한 문제
• 띄어쓰기를 잘못하면 전처리 분석에서 어려워짐
# 형태소 분석 Case
>>> import konlpy
>>> morph_analyzer = konlpy.tag.Okt()
>>> morph_analyzer.pos('너무기대안하고갔나 재밌게봤다’)
[('너', 'Modifier'), ('무기', 'Noun'), ('대안', 'Noun’),
('하고', 'Josa’), ('갔나', 'Verb'), ('재밌게', 'Adjective'), … ]
# 띄어쓰기에 따라 분석이 제대로 안 될 수도 있음
참고링크: https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/05/10/postag/
띄어쓰기 알고리즘 개발의 한계
• 대체로 띄어쓰기 오픈소스는 이미 수집한 데이터에 학습된 알고리즘으로 구성
• 코퍼스 도메인에 따라 띄어쓰기 성능이 달라질 수 있음
• 목적 도메인에 맞는 띄어쓰기 문제를 해결하기에 한계가 있음
>>> from pykospacing import spacing
>>> spacing('너는나의원수야').replace(' ', '_’)
'너는_나_의원수야’
띄어쓰기 프로그램
띄어쓰기 프로그램 실행 구조
“오늘서울 날씨 어때” “오늘서울날씨어때” “오늘 서울 날씨 어때”
1.입력 텍스트에
모든 공백을 없앰
2. 모델에 입력하여
띄어쓰기가 된
문장을 출력
전처리 문장입력 문장 띄어 쓴 문장
띄어쓰기 모델 학습 구조
Candidate Models
Train
Test
&
Update
Training Data
N-Iteration
works
1. 학습 데이터 구성 2. 모델 학습
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
DataManager
Object
Trainer
Object
Evaluator
Object
Model
Tokenizer
Vocabulary
Configs.json
띄어쓰기 프로그램 구조 설계
Agent
Object
Model
Tokenizer
Vocabulary
Configs.json
1. 띄어쓰기 프로그램 설정을
Configs.json으로 정의하여
Agent 객체에 등록
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
Model
Tokenizer
Vocabulary
2. Agent 객체를 활용하여
학습과 평가, 실행 기능을
수행하도록 함
띄어쓰기 프로그램 구조 설계
Agent
Object
Train()
Run()
Eval()
DataManager
Object
Trainer
Object
Evaluator
Object
Model
Tokenizer
Vocabulary
3. 기능 수행하기 위해
학습, 데이터 관리, 평가 객체를
통해 수행하도록 함
띄어쓰기 프로그램 실행 구현
>>> from takos.agents.word_segment import WordSegmentAgent
>>> spacing_agent = WordSegmentAgent('your_config.json’) # 설정파일 등록
>>> spacing_agent.train() # 학습
>>> spacing_agent.eval() # 평가
>>> spacing_agent('학교종이땡땡땡’) # 실행
'학교종이 땡땡땡’
{ .......
"dataset": {
"name": "your_dataset",
"train": {
"input":"./samples/train.txt"
},
"test": {
"input": "./samples/test.txt"
}
} .......
}
띄어쓰기 모델 개발
Baseline 모델 설계
• 시퀀스 분류 모델: CRF, RNN, RNN-CRF 등
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
BiLSTM
-CRF
오 늘 서 울 날 씨
B I B I B I
띄어쓰는 지점에 대해
‘B’ 태그로 예측 하도록 학습
BiLSTM-CRF
• BiLSTM을 통해 입력한 토큰과 앞뒤 시퀀스
정보를 토대로 띄어쓰기 지점을 예측
• Conditional Random Field (CRF) 를 통해
시퀀스 태그의 순서를 보정
BiLSTM-CRF 모델 예시
Embedding
BiLSTM
CRF
참고링크: https://towardsdatascience.com/implementing-a-linear-chain-conditional-random-field-crf-in-pytorch-16b0b9c4b4ea
BiLSTM-CRF 구현 - Initialize
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
Word
Embedding
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
BiLSTM-CRF 구현 - Initialize
BiLSTM
import torch
import torch.nn as nn
class BilstmCRF(nn.Module):
def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim,
pad_idx=0):
super(BilstmCRF, self).__init__()
self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx
self._embedding = nn.Embedding(vocab_size, embedding_dim,
padding_idx=0)
self._bilstm = BiLSTM(embedding_dim, hidden_dim)
self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx))
self._crf = CRF(len(self._tag_to_idx))
BiLSTM-CRF 구현 - Initialize
CRF
BiLSTM-CRF 구현 - Loss
class BilstmCRF(nn.Module):
def loss(self, x: torch.Tensor, y: torch.Tensor):
masking = x.ne(self._pad_idx).float()
fmap = self._embedding(x)
hiddens, _ = self._bilstm(fmap, masking)
emissions = self._fc(hiddens)
nll = self._crf(emissions, y, mask=masking)
return nll
CRF Layer에서 loss
값을 출력
Pad 정보를
없애기 위한
Masking 처리
모델 연산
BiLSTM-CRF 구현 - Inference
class BilstmCRF(nn.Module):
def forward(self, x: torch.Tensor):
masking = x.ne(self._pad_idx).float()
fmap = self._embedding(x)
hiddens, _ = self._bilstm(fmap, masking)
emissions = self._fc(hiddens)
_, path = self._crf.decode(emissions, mask=masking)
return path
Viterbi 디코딩을 통해
최적의 시퀀스를 출력
세종 코퍼스 데이터셋 수집
• Github에 coolengineer/sejong-corpus
프로젝트를 다운로드
• 커멘드를 통해 문장 추출
# bash command
$ cd sejong-corpus
$ make
$ bash 50.sent_extract.sh corpus-utf8
$ cat tmp/s/* > corpus.txt
Sejong-corpus Github 프로젝트
세종 코퍼스 데이터셋 구성
• 전체 코퍼스 수 (str.split() 기준): 1,664,458 개 (문어 92.5%, 구어 7.5%)
• Unique 코퍼스 수: 1,537,741 개
• 전체 문장 수 (str.split(‘n’) 기준): 1,038,087 개 (문어 79.3%, 구어 20.7%)
세종 코퍼스 문장 길이 분석
• 어절 토큰 길이는 100이 가장 긴 경우
• 음절의 경우 대부분의 토큰 길이가 130 미만
토큰 단위 별 문장 길이 분포
세종 코퍼스 어절 단어 분포 분석
• 동사와 관련된 어휘가 많이 분포
• ‘하다’와 관련된 파생어들도 많이 보임
• ‘이’나 ‘그’ 와 같은 지칭 대명사와 같은 단어가 많이
발생
세종 데이터 어절 분포
Self Supervised Learning
• 데이터 자체만으로 학습하는 방법
• 입력 데이터에 의해 Labeling 이 가능
• 띄어쓰기의 경우 단어의 시작 지점 또는 끝 지점으로 Label 생성
학습 labeling 방식
• 기존 띄어쓰기 모델은 띄어쓰기 경계를 예측하는 `경계 인식 방식`으로 함
• 경계 인식 방식의 경우 입력한 토큰이 경계 지점인지 판별하는 학습만 함
• 단어 영역을 예측하는 `영역 인식 방식`을 통해 경계 지점 외에 띄어쓰기에 필요한 정보를
학습하도록 함
V
학습 labeling 방식
• 경계 인식 방식
VVV
나 는 오 늘 학 교 에 갈 수 있 다
B I B I B I I B B B I
띄어 쓰는 경계 지점을 학습하는 방식
- B: Begin
- I : Inside
VV
학습 Labeling 방식
• 영역 인식 방식
- B: Begin
- I : Inside
- E: End
- S: Single
단어 영역을 학습하는 방식
나 는 오 늘 학 교 에 갈 수 있 다
B E B E B I E S S B E
참고논문: Universal Word Segmentation: Implementation and Interpretation Shao et al. [ACL 2018]
학습 데이터셋 구성
• 학습 데이터셋: 934,278 (전체 90%)
• 평가 데이터셋: 103,809 (전체 10%)
**검증 데이터셋 은 학습 데이터셋에 10%를 무작위 추출 함
모델 학습 하이퍼파라메터
• Vocab Size & Embedding Dim: 3710 개, 32
• BiLSTM Feature Dim: 64 * 2
• Optimizer: torch.optim.Adam(3e-4)
• Batch size: 128
• Limit Sequence Length: 100
• Validation F1 Score가 수렴 될 때까지 학습
Baseline 성능 평가 기준
• F1 Score (띄어쓰기 경계 인식 기준)
• WER (Word Error Rate) Score
• SER (Sentence Error Rate) Score
WER 계산 방식
Baseline 성능 평가
KoSpacing 경계 인식 방식 영역 인식 방식
F1 Score - 97.71 97.83
WER Score 18.05 12.47 11.91
SER Score 49.77 40.84 39.11
False Case 분석
• 복합 명사의 띄어쓰기 문제
예측 문장 정답 문장
초고액 상품권이 빚어낼 사회 심리적 영향을
짚어봐야 한다.
초고액 상품권이 빚어낼 사회심리적 영향을
짚어봐야 한다.
물론 이 일이 실현되려면 과학기술의 측면에서
수많은 장벽을 넘어서야 한다.
물론 이 일이 실현되려면 과학 기술의 측면에서
수많은 장벽을 넘어서야 한다.
False Case 분석
• 한 글자 어절의 띄어쓰기 문제
예측 문장 정답 문장
방랑시인 김입은 때 마침 길에서
가난한 농부에게 식사를 대접받았다.
방랑시인 김입은 때마침 길에서
가난한 농부에게 식사를 대접받았다.
승리의 기쁨에 도취된 트로이군은 성안으로
목마를 들여놓고 축제를 벌인다.
승리의 기쁨에 도취된 트로이군은 성 안으로
목마를 들여놓고 축제를 벌인다.
경계 인식 방식 VS 영역 인식 방식
• False Case 를 통해서 두 방식의 차이가 무엇인지 파악하기 어려움
• Labeling 방식 차이가 모델 띄어쓰기 예측에 어떤 영향을 주는가?
• 띄어쓰기를 판별하는데 어떤 입력 정보가 가장 영향력이 있는가?
Local Interpretable Model-agnostic
Explanations (LIME) 알고리즘 분석
• 모델 예측을 할 때 크게 영향을 주는 입력 요소를 찾는 알고리즘
• 모델이 어떻게 예측 했는지 입력 데이터를 통해 시각적으로 표현
LIME 알고리즘 분석 예시
참고링크: https://dreamgonfly.github.io/2017/11/05/LIME.html
안 녕 하 세 요 저 _ 홍 길 동 입 니 다
안 녕 하 세 요 _ 는 홍 길 _ 입 니 다
안 녕 하 _ 요 저 는 홍 길 동 입 니 다
안 녕 _ _ 요 저 는 홍 _ _ 입 니 다
띄어쓰기 모델에서 LIME 알고리즘 활용
• ‘홍’ 이란 어절을 띄어쓰기를 하는데 어느 음절 토큰이 얼마나 기여하는가?
안녕하세요저는홍길동입니다 ➔ 안녕하세요 저는 홍길동입니다
띄어쓰기: 0.2
띄어쓰기: 0.5
띄어쓰기: 0.8
띄어쓰기: 0.7
LIME을 통한 띄어쓰기 모델 분석
• 경계 인식 모델
띄어 쓰기 전 토큰의 영향을 많이 받음
• 영역 인식 모델
띄어 쓰는 지점 주변 토큰의 영향을 고르게 받음
• 상대적으로 “입력 정보를 편향적으로 받지 않는”
점이 좋은 띄어쓰기 예측하는 것으로 보임
경계 인식 모델 분석 영역 인식 모델 분석
입력: 안녕하세요저는홍길동입니다
출력: 안녕하세요 저는 홍길동입니다
Korean BERT 모델 적용
Transformer Network
• Self Attention 기법으로 시퀀스 정보들 간의 관계를 학습
• Multi-head Attention 으로 다양한 관점에서 시퀀스 관계를 볼 수 있도록 함
Transformer EncoderSelf Attention
참고링크: http://jalammar.github.io/illustrated-transformer/
Korean BERT (ETRI ver.)
• Transformer Encoder로 구성된 모델
• 한국어 텍스트 데이터를 Semi-Unsupervised
Learning 하여 언어 모델로 학습
• Fine-tuning 만으로 여러 NLP Task에서 좋은 성능을
보임
ETRI Korean BERT
참고링크: http://jalammar.github.io/illustrated-bert/
Korean BERT 구현 - Initialize
import torch.nn as nn
from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel
class BertTagger(BertPreTrainedModel):
def __init__(self, config, tag_size, pad_idx=0, cls_idx=2):
super(BertTagger, self).__init__(config)
self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size
self.bert = BertModel(config)
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
self.activation = nn.Tanh()
self.dense_2 = nn.Linear(config.hidden_size, tag_size)
self.ce_loss = nn.CrossEntropyLoss(reduction='none')
BERT Layer
Korean BERT 구현 - Initialize
import torch.nn as nn
from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel
class BertTagger(BertPreTrainedModel):
def __init__(self, config, tag_size, pad_idx=0, cls_idx=2):
super(BertTagger, self).__init__(config)
self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size
self.bert = BertModel(config)
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
self.activation = nn.Tanh()
self.dense_2 = nn.Linear(config.hidden_size, tag_size)
self.ce_loss = nn.CrossEntropyLoss(reduction='none')
Dense Layer
Korean BERT 구현 - Inference
class BertTagger(BertPreTrainedModel):
def forward(self, x: torch.Tensor):
batch_size = x.size(0)
cls_mark = torch.full((batch_size, 1), self._cls_idx).to(self.device)
x = torch.cat([x, cls_mark], dim=-1)
masking = x.ne(self._pad_idx)
encoder_layer, _ = self.bert(x, attention_mask=masking,
output_all_encoded_layers=False)
dense_layer = self.activation(self.dense(encoder_layer [:, 1:]))
emissions = nn.functional.softmax(self.dense_2(dense_layer),
dim=-1)
path = torch.argmax(emissions, dim=-1)
return path
BERT 모델
입력값 준비
Masking
Korean BERT 성능 결과
KoSpacing BiLSTM-CRF (영역)
KoBERT
(3 Layers)
KoBERT
(6 Layers)
F1 Score - 97.83 98.62 98.70
WER Score 18.05 11.91 8.08 7.63
SER Score 49.77 39.11 30.24 28.65
Korean BERT 처리 속도 비교
length BiLSTM-CRF (영역)
15 0.004 (± 0.001)
50 0.014 (± 0.001)
100 0.03 (± 0.001)
KoBERT (3 Layers)
0.018 (± 0.003)
0.038 (± 0.002)
0.073 (± 0.003)
KoBERT (6 Layers)
0.035 (± 0.003)
0.076 (± 0.003)
0.141 (± 0.003)
*처리속도 (1건 당 sec)
- CPU model: AMD Ryzen 7 1700 8-core. - RAM: 64GB
결론
정리
• 수집 데이터를 활용한 띄어쓰기 프로그램 개발 (세종 코퍼스 데이터셋으로 검증)
• 학습한 모델이 모든 범주에 대한 띄어쓰기를 잘 할 수 있지는 않음
• 띄어 쓴 정보를 수용할 수 있는 공백 정보 반영 학습을 적용해 볼 필요 있음
• 가급적 띄어쓰기가 잘 된 데이터를 많이 학습해 볼 것
TaKos Project
TaKos(Train-able Korean spacing) Project
• 데이터 학습 가능한 띄어쓰기 알고리즘을
만들기 위한 프로젝트
• Github에서 TaKos 프로젝트를 다운로드
• 프로젝트 내에서 명령어 실행
pip install -r requirements
python setup.py install
TaKos Project Repo:
github.com/Taekyoon/takos-alpha
TaKos(Train-able Korean spacing) Project
• 띄어쓰기 데이터만 주어지면 모델 학습하여 제공
# 간단하게 띄어쓰기 모델을 만들어 봅시다
from takos.agents.word_segment import WordSegmentAgent
spacing_agent = WordSegmentAgent('your_config.json’)
spacing_agent.train()
spacing_agent.eval()
spacing_agent('학교종이땡땡땡')
{ .......
"dataset": {
"name": "your_dataset",
"train": {
"input":"./samples/train.txt"
},
"test": {
"input": "./samples/test.txt"
}
} .......
}
Q & A
Appendix
띄어쓰기로 인한 문제 (추가-1)
• 띄어쓰기를 잘못하면 토큰 인덱싱에서 어려워짐
# BertTokenizer or WordPiece case (ETRI Bert)
tokenizer = BertTokenizer.from_pretrained('vocab.korean.rawtext.list’)
tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무 기대 안하고 갔나’)
>>> [1051, 5132, 129, 58, 1976, 230]
tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무기대 안하고갔나’))
>>> [567, 69, 5132, 129, 660, 1976, 230]
# 띄어쓰기에 따라 변환된 인덱스 값이 다름
띄어쓰기가 필요한 문제 (추가-2)
• Speech to Text Case (Google Speech API)
“콜라는_하나만_가져_주_셔도_될_것_같_아요_여기_위치는_올림픽_공원_평화의
문_부분이고요 _만나서_결제할게요”
• configs.json
{
"type": "word_segment",
"gpu_device": 0,
"dataset": {
"name": "sejong_spacing",
"train": {
"bi_tags_only": false,
"vocab_min_freq": 10,
"input": "train.txt"},
"test": {
"limit_len": 150,
"input": "test.txt"}
},
"deploy": {
"path": "./tmp/test_model"},
"model": {
"type": "bilstm_crf",
"parameters": {
"word_embedding_dims": 32,
"hidden_dims": 64}
},
"train": {
"epochs": 50,
"eval_steps": 1000,
"eval_batch_size": 512,
"batch_size": 128,
"sequence_length": 100
}
띄어쓰기 프로그램 설정 구성
띄어쓰기 프로그램 실행 구현
def run(self, query):
prepro_query = self.preprocess(query)
tokenized_query = self.tokenizer.tokenize(prepro_query).split()
model_inputs = torch.Tensor([self.vocab.to_indices(tokenized_query)])
pred_score, tag_seq = self.model(model_inputs)
labeled_tag_seq = self.label.to_tokens(tag_seq[0].tolist())
post_processed = self.postprocess(prepro_query, labeled_tag_seq)
outputs = {'output': post_processed}
return outputs
입력 텍스트 전처리
띄어쓰기 처리
띄어쓰기 모델 학습 구현
def train(self):
train_configs = self.configs['train']
train_dataset_configs = self.configs['dataset']['train']
data_builder = create_builder(self.task_type, train_dataset_configs)
model = create_model(self.task_type, tag_to_idx, self.model_configs)
trainer = create_trainer(self.task_type, model, data_builder,
train_configs)
trainer.train()
기능 수행을 위한 객체 생성
띄어쓰기 모델 평가 구현
def eval(self):
test_dataset_configs = self.configs['dataset']['test']
train_dataset_configs = self.configs['dataset']['train']
data_builder = create_builder(self.task_type, train_dataset_configs)
evaluator = create_evaluator(self.task_type, self.model, data_builder,
test_dataset_configs, limit_len)
evaluator.eval()
logger.info(evaluator.summary()) 기능 수행을 위한 객체 생성
모델 개발에 활용한 리서치 자료
• PyKoSpacing
• 2018년 HCLT 학술대회에 나온 논문들
• 문장 정보를 고려한 딥러닝 기반 자동 띄어쓰기의 개념 및 활용
• 띄어쓰기 및 문장 경계 인식을 위한 다중 손실 선형 결합 기반의 다중 클래스 분류 시스템
• CRFs와 Bi-LSTM/CRFs의 비교 분석: 자동 띄어쓰기 관점에서
• 자동띄어쓰기 오류 수정 및 복합명사 분해 개요: 2018 차세정 언어처리 경진대회
False Case 분석 (추가)
• 그 외 띄어쓰기 문제
예측 문장 정답 문장
소독용에 탄 올 스프레이를 수시로 뿌린다. 소독용 에탄올 스프레이를 수시로 뿌린다.
주말쯤 작전이 시작될 것이라고
미국 방부 및 나토 의미 관계자들이 23일 밝혔다.
주말쯤 작전이 시작될 것이라고
미 국방부 및 나토의 미 관계자들이 23일 밝혔다.
LIME을 통한 띄어쓰기 모델 분석 (추가)
경계 인식 모델 분석
영역 인식 모델 분석
입력: 세종대왕께서한글을창조하셨다
출력: 세종대왕께서 한글을 창조하셨다
경계 인식 모델 분석
영역 인식 모델 분석
입력: 세종대왕께서한글을창조하셨다
출력: 세종대왕께서 한글을 창조하셨다

Contenu connexe

Tendances

Tendances (20)

Word Embeddings - Introduction
Word Embeddings - IntroductionWord Embeddings - Introduction
Word Embeddings - Introduction
 
1910 HCLT
1910 HCLT1910 HCLT
1910 HCLT
 
딥러닝 기반의 자연어처리 최근 연구 동향
딥러닝 기반의 자연어처리 최근 연구 동향딥러닝 기반의 자연어처리 최근 연구 동향
딥러닝 기반의 자연어처리 최근 연구 동향
 
딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향
 
RoFormer: Enhanced Transformer with Rotary Position Embedding
RoFormer: Enhanced Transformer with Rotary Position EmbeddingRoFormer: Enhanced Transformer with Rotary Position Embedding
RoFormer: Enhanced Transformer with Rotary Position Embedding
 
A Simple Introduction to Word Embeddings
A Simple Introduction to Word EmbeddingsA Simple Introduction to Word Embeddings
A Simple Introduction to Word Embeddings
 
[224] 번역 모델 기반_질의_교정_시스템
[224] 번역 모델 기반_질의_교정_시스템[224] 번역 모델 기반_질의_교정_시스템
[224] 번역 모델 기반_질의_교정_시스템
 
Information Extraction
Information ExtractionInformation Extraction
Information Extraction
 
Neural Machine Translation (D3L4 Deep Learning for Speech and Language UPC 2017)
Neural Machine Translation (D3L4 Deep Learning for Speech and Language UPC 2017)Neural Machine Translation (D3L4 Deep Learning for Speech and Language UPC 2017)
Neural Machine Translation (D3L4 Deep Learning for Speech and Language UPC 2017)
 
Context2Vec 기반 단어 의미 중의성 해소, Word Sense Disambiguation
Context2Vec 기반 단어 의미 중의성 해소, Word Sense DisambiguationContext2Vec 기반 단어 의미 중의성 해소, Word Sense Disambiguation
Context2Vec 기반 단어 의미 중의성 해소, Word Sense Disambiguation
 
생초보를 위한 한글 형태소 분석하기
생초보를 위한 한글 형태소 분석하기생초보를 위한 한글 형태소 분석하기
생초보를 위한 한글 형태소 분석하기
 
Python을 활용한 챗봇 서비스 개발 1일차
Python을 활용한 챗봇 서비스 개발 1일차Python을 활용한 챗봇 서비스 개발 1일차
Python을 활용한 챗봇 서비스 개발 1일차
 
IE: Named Entity Recognition (NER)
IE: Named Entity Recognition (NER)IE: Named Entity Recognition (NER)
IE: Named Entity Recognition (NER)
 
Introduction to Named Entity Recognition
Introduction to Named Entity RecognitionIntroduction to Named Entity Recognition
Introduction to Named Entity Recognition
 
BERT - Part 1 Learning Notes of Senthil Kumar
BERT - Part 1 Learning Notes of Senthil KumarBERT - Part 1 Learning Notes of Senthil Kumar
BERT - Part 1 Learning Notes of Senthil Kumar
 
Switch transformers paper review
Switch transformers paper reviewSwitch transformers paper review
Switch transformers paper review
 
한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기
한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기
한국어 문서 추출요약 AI 경진대회- 좌충우돌 후기
 
파이썬을 활용한 챗봇 서비스 개발 3일차
파이썬을 활용한 챗봇 서비스 개발 3일차파이썬을 활용한 챗봇 서비스 개발 3일차
파이썬을 활용한 챗봇 서비스 개발 3일차
 
A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)A Review of Deep Contextualized Word Representations (Peters+, 2018)
A Review of Deep Contextualized Word Representations (Peters+, 2018)
 
Python을 활용한 챗봇 서비스 개발 2일차
Python을 활용한 챗봇 서비스 개발 2일차Python을 활용한 챗봇 서비스 개발 2일차
Python을 활용한 챗봇 서비스 개발 2일차
 

Similaire à 한국어 띄어쓰기 프로그램 도전기

제3장 색인어 추출을 위한 언어학적 처리
제3장 색인어 추출을 위한 언어학적 처리제3장 색인어 추출을 위한 언어학적 처리
제3장 색인어 추출을 위한 언어학적 처리
Chang-yong Jung
 
영어 말하기 자동채점 프로그램의 현재와 미래
영어 말하기 자동채점 프로그램의 현재와 미래	영어 말하기 자동채점 프로그램의 현재와 미래
영어 말하기 자동채점 프로그램의 현재와 미래
engedukamall
 
C 언어 스터디 01 - 기초
C 언어 스터디 01 - 기초C 언어 스터디 01 - 기초
C 언어 스터디 01 - 기초
Yu Yongwoo
 

Similaire à 한국어 띄어쓰기 프로그램 도전기 (20)

댓글 감성 분석 상용화 개발기(Ver. 2)
댓글 감성 분석 상용화 개발기(Ver. 2)댓글 감성 분석 상용화 개발기(Ver. 2)
댓글 감성 분석 상용화 개발기(Ver. 2)
 
단어 의미 중의성 해소, Word Sense Disambiguation(WSD)
단어 의미 중의성 해소, Word Sense Disambiguation(WSD)단어 의미 중의성 해소, Word Sense Disambiguation(WSD)
단어 의미 중의성 해소, Word Sense Disambiguation(WSD)
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
소프트웨어 2.0을 활용한 게임 어뷰징 검출
소프트웨어 2.0을 활용한 게임 어뷰징 검출소프트웨어 2.0을 활용한 게임 어뷰징 검출
소프트웨어 2.0을 활용한 게임 어뷰징 검출
 
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
Senti prompt sentiment knowledge enhanced prompt tuning for aspect-based sent...
 
Pycon Korea 2020
Pycon Korea 2020 Pycon Korea 2020
Pycon Korea 2020
 
2206 Modupop!
2206 Modupop!2206 Modupop!
2206 Modupop!
 
제3장 색인어 추출을 위한 언어학적 처리
제3장 색인어 추출을 위한 언어학적 처리제3장 색인어 추출을 위한 언어학적 처리
제3장 색인어 추출을 위한 언어학적 처리
 
파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초
 
Sharing development experience of educational apps for the hard of hearing (P...
Sharing development experience of educational apps for the hard of hearing (P...Sharing development experience of educational apps for the hard of hearing (P...
Sharing development experience of educational apps for the hard of hearing (P...
 
Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)Open domain dialogue Chatbot(잡담봇 삽질기)
Open domain dialogue Chatbot(잡담봇 삽질기)
 
파이썬을 활용한 자연어 분석
파이썬을 활용한 자연어 분석파이썬을 활용한 자연어 분석
파이썬을 활용한 자연어 분석
 
[224] backend 개발자의 neural machine translation 개발기 김상경
[224] backend 개발자의 neural machine translation 개발기 김상경[224] backend 개발자의 neural machine translation 개발기 김상경
[224] backend 개발자의 neural machine translation 개발기 김상경
 
영어 말하기 자동채점 프로그램의 현재와 미래
영어 말하기 자동채점 프로그램의 현재와 미래	영어 말하기 자동채점 프로그램의 현재와 미래
영어 말하기 자동채점 프로그램의 현재와 미래
 
[2D2]다국어음성합성시스템(NVOICE)개발
[2D2]다국어음성합성시스템(NVOICE)개발[2D2]다국어음성합성시스템(NVOICE)개발
[2D2]다국어음성합성시스템(NVOICE)개발
 
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
[Langcon2020]롯데의 딥러닝 모델은 어떻게 자기소개서를 읽고 있을까?
 
C 언어 스터디 01 - 기초
C 언어 스터디 01 - 기초C 언어 스터디 01 - 기초
C 언어 스터디 01 - 기초
 
Deep Learning for Chatbot (1/4)
Deep Learning for Chatbot (1/4)Deep Learning for Chatbot (1/4)
Deep Learning for Chatbot (1/4)
 
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
(Kor ver.)NLP embedding(word2vec) tutorial & implementation(Tensorflow)
 
Character-Aware Neural Language Models
Character-Aware Neural Language ModelsCharacter-Aware Neural Language Models
Character-Aware Neural Language Models
 

Dernier

Dernier (8)

JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement MethodologyJMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
 
JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!
 
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
 
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
 
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
 
데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법
 
JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례
 
공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화
 

한국어 띄어쓰기 프로그램 도전기

  • 1. PyCon Korea 2019 한국어 띄어쓰기 프로그램 도전기 Taekyoon Choi (tgchoi03@gmail.com)
  • 2. Contents • 서론 • 띄어쓰기 프로그램 • 띄어쓰기 모델 개발 • Korean BERT 적용 • 결론
  • 4. 자연어처리에서 띄어쓰기 • 자연어처리에서는 텍스트를 토큰 단위로 구분하여 다룸 • 쉽게 토크나이징을 할 수 있는 방법은 띄어 쓴 단어를 구분하는 것 • 한국어에서 띄어쓰기는 텍스트 의미를 구분하는데 큰 영향을 줄 수 있음
  • 5. 띄어쓰기로 인한 문제 • 문맥 없이 띄어쓰기로 의미 구분을 명확히 하기 어려움 >>> text = '학교종이 땡땡땡’ >>> print(text.split()) [‘학교종이’, ‘땡땡땡’] # [‘학교종이’] or [‘학교’,‘종이’]?
  • 6. 띄어쓰기로 인한 문제 • 띄어쓰기를 잘못하면 전처리 분석에서 어려워짐 # 형태소 분석 Case >>> import konlpy >>> morph_analyzer = konlpy.tag.Okt() >>> morph_analyzer.pos('너무기대안하고갔나 재밌게봤다’) [('너', 'Modifier'), ('무기', 'Noun'), ('대안', 'Noun’), ('하고', 'Josa’), ('갔나', 'Verb'), ('재밌게', 'Adjective'), … ] # 띄어쓰기에 따라 분석이 제대로 안 될 수도 있음 참고링크: https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/05/10/postag/
  • 7. 띄어쓰기 알고리즘 개발의 한계 • 대체로 띄어쓰기 오픈소스는 이미 수집한 데이터에 학습된 알고리즘으로 구성 • 코퍼스 도메인에 따라 띄어쓰기 성능이 달라질 수 있음 • 목적 도메인에 맞는 띄어쓰기 문제를 해결하기에 한계가 있음 >>> from pykospacing import spacing >>> spacing('너는나의원수야').replace(' ', '_’) '너는_나_의원수야’
  • 9. 띄어쓰기 프로그램 실행 구조 “오늘서울 날씨 어때” “오늘서울날씨어때” “오늘 서울 날씨 어때” 1.입력 텍스트에 모든 공백을 없앰 2. 모델에 입력하여 띄어쓰기가 된 문장을 출력 전처리 문장입력 문장 띄어 쓴 문장
  • 10. 띄어쓰기 모델 학습 구조 Candidate Models Train Test & Update Training Data N-Iteration works 1. 학습 데이터 구성 2. 모델 학습
  • 11. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() DataManager Object Trainer Object Evaluator Object Model Tokenizer Vocabulary Configs.json
  • 12. 띄어쓰기 프로그램 구조 설계 Agent Object Model Tokenizer Vocabulary Configs.json 1. 띄어쓰기 프로그램 설정을 Configs.json으로 정의하여 Agent 객체에 등록
  • 13. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() Model Tokenizer Vocabulary 2. Agent 객체를 활용하여 학습과 평가, 실행 기능을 수행하도록 함
  • 14. 띄어쓰기 프로그램 구조 설계 Agent Object Train() Run() Eval() DataManager Object Trainer Object Evaluator Object Model Tokenizer Vocabulary 3. 기능 수행하기 위해 학습, 데이터 관리, 평가 객체를 통해 수행하도록 함
  • 15. 띄어쓰기 프로그램 실행 구현 >>> from takos.agents.word_segment import WordSegmentAgent >>> spacing_agent = WordSegmentAgent('your_config.json’) # 설정파일 등록 >>> spacing_agent.train() # 학습 >>> spacing_agent.eval() # 평가 >>> spacing_agent('학교종이땡땡땡’) # 실행 '학교종이 땡땡땡’ { ....... "dataset": { "name": "your_dataset", "train": { "input":"./samples/train.txt" }, "test": { "input": "./samples/test.txt" } } ....... }
  • 17. Baseline 모델 설계 • 시퀀스 분류 모델: CRF, RNN, RNN-CRF 등 BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF BiLSTM -CRF 오 늘 서 울 날 씨 B I B I B I 띄어쓰는 지점에 대해 ‘B’ 태그로 예측 하도록 학습
  • 18. BiLSTM-CRF • BiLSTM을 통해 입력한 토큰과 앞뒤 시퀀스 정보를 토대로 띄어쓰기 지점을 예측 • Conditional Random Field (CRF) 를 통해 시퀀스 태그의 순서를 보정 BiLSTM-CRF 모델 예시 Embedding BiLSTM CRF 참고링크: https://towardsdatascience.com/implementing-a-linear-chain-conditional-random-field-crf-in-pytorch-16b0b9c4b4ea
  • 19. BiLSTM-CRF 구현 - Initialize import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) Word Embedding
  • 20. import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) BiLSTM-CRF 구현 - Initialize BiLSTM
  • 21. import torch import torch.nn as nn class BilstmCRF(nn.Module): def __init__(self, vocab_size, tag_to_idx, embedding_dim, hidden_dim, pad_idx=0): super(BilstmCRF, self).__init__() self._pad_idx, self._tag_to_idx = pad_idx, tag_to_idx self._embedding = nn.Embedding(vocab_size, embedding_dim, padding_idx=0) self._bilstm = BiLSTM(embedding_dim, hidden_dim) self._fc = nn.Linear(2 * hidden_dim, len(tag_to_idx)) self._crf = CRF(len(self._tag_to_idx)) BiLSTM-CRF 구현 - Initialize CRF
  • 22. BiLSTM-CRF 구현 - Loss class BilstmCRF(nn.Module): def loss(self, x: torch.Tensor, y: torch.Tensor): masking = x.ne(self._pad_idx).float() fmap = self._embedding(x) hiddens, _ = self._bilstm(fmap, masking) emissions = self._fc(hiddens) nll = self._crf(emissions, y, mask=masking) return nll CRF Layer에서 loss 값을 출력 Pad 정보를 없애기 위한 Masking 처리 모델 연산
  • 23. BiLSTM-CRF 구현 - Inference class BilstmCRF(nn.Module): def forward(self, x: torch.Tensor): masking = x.ne(self._pad_idx).float() fmap = self._embedding(x) hiddens, _ = self._bilstm(fmap, masking) emissions = self._fc(hiddens) _, path = self._crf.decode(emissions, mask=masking) return path Viterbi 디코딩을 통해 최적의 시퀀스를 출력
  • 24. 세종 코퍼스 데이터셋 수집 • Github에 coolengineer/sejong-corpus 프로젝트를 다운로드 • 커멘드를 통해 문장 추출 # bash command $ cd sejong-corpus $ make $ bash 50.sent_extract.sh corpus-utf8 $ cat tmp/s/* > corpus.txt Sejong-corpus Github 프로젝트
  • 25. 세종 코퍼스 데이터셋 구성 • 전체 코퍼스 수 (str.split() 기준): 1,664,458 개 (문어 92.5%, 구어 7.5%) • Unique 코퍼스 수: 1,537,741 개 • 전체 문장 수 (str.split(‘n’) 기준): 1,038,087 개 (문어 79.3%, 구어 20.7%)
  • 26. 세종 코퍼스 문장 길이 분석 • 어절 토큰 길이는 100이 가장 긴 경우 • 음절의 경우 대부분의 토큰 길이가 130 미만 토큰 단위 별 문장 길이 분포
  • 27. 세종 코퍼스 어절 단어 분포 분석 • 동사와 관련된 어휘가 많이 분포 • ‘하다’와 관련된 파생어들도 많이 보임 • ‘이’나 ‘그’ 와 같은 지칭 대명사와 같은 단어가 많이 발생 세종 데이터 어절 분포
  • 28. Self Supervised Learning • 데이터 자체만으로 학습하는 방법 • 입력 데이터에 의해 Labeling 이 가능 • 띄어쓰기의 경우 단어의 시작 지점 또는 끝 지점으로 Label 생성
  • 29. 학습 labeling 방식 • 기존 띄어쓰기 모델은 띄어쓰기 경계를 예측하는 `경계 인식 방식`으로 함 • 경계 인식 방식의 경우 입력한 토큰이 경계 지점인지 판별하는 학습만 함 • 단어 영역을 예측하는 `영역 인식 방식`을 통해 경계 지점 외에 띄어쓰기에 필요한 정보를 학습하도록 함
  • 30. V 학습 labeling 방식 • 경계 인식 방식 VVV 나 는 오 늘 학 교 에 갈 수 있 다 B I B I B I I B B B I 띄어 쓰는 경계 지점을 학습하는 방식 - B: Begin - I : Inside VV
  • 31. 학습 Labeling 방식 • 영역 인식 방식 - B: Begin - I : Inside - E: End - S: Single 단어 영역을 학습하는 방식 나 는 오 늘 학 교 에 갈 수 있 다 B E B E B I E S S B E 참고논문: Universal Word Segmentation: Implementation and Interpretation Shao et al. [ACL 2018]
  • 32. 학습 데이터셋 구성 • 학습 데이터셋: 934,278 (전체 90%) • 평가 데이터셋: 103,809 (전체 10%) **검증 데이터셋 은 학습 데이터셋에 10%를 무작위 추출 함
  • 33. 모델 학습 하이퍼파라메터 • Vocab Size & Embedding Dim: 3710 개, 32 • BiLSTM Feature Dim: 64 * 2 • Optimizer: torch.optim.Adam(3e-4) • Batch size: 128 • Limit Sequence Length: 100 • Validation F1 Score가 수렴 될 때까지 학습
  • 34. Baseline 성능 평가 기준 • F1 Score (띄어쓰기 경계 인식 기준) • WER (Word Error Rate) Score • SER (Sentence Error Rate) Score WER 계산 방식
  • 35. Baseline 성능 평가 KoSpacing 경계 인식 방식 영역 인식 방식 F1 Score - 97.71 97.83 WER Score 18.05 12.47 11.91 SER Score 49.77 40.84 39.11
  • 36. False Case 분석 • 복합 명사의 띄어쓰기 문제 예측 문장 정답 문장 초고액 상품권이 빚어낼 사회 심리적 영향을 짚어봐야 한다. 초고액 상품권이 빚어낼 사회심리적 영향을 짚어봐야 한다. 물론 이 일이 실현되려면 과학기술의 측면에서 수많은 장벽을 넘어서야 한다. 물론 이 일이 실현되려면 과학 기술의 측면에서 수많은 장벽을 넘어서야 한다.
  • 37. False Case 분석 • 한 글자 어절의 띄어쓰기 문제 예측 문장 정답 문장 방랑시인 김입은 때 마침 길에서 가난한 농부에게 식사를 대접받았다. 방랑시인 김입은 때마침 길에서 가난한 농부에게 식사를 대접받았다. 승리의 기쁨에 도취된 트로이군은 성안으로 목마를 들여놓고 축제를 벌인다. 승리의 기쁨에 도취된 트로이군은 성 안으로 목마를 들여놓고 축제를 벌인다.
  • 38. 경계 인식 방식 VS 영역 인식 방식 • False Case 를 통해서 두 방식의 차이가 무엇인지 파악하기 어려움 • Labeling 방식 차이가 모델 띄어쓰기 예측에 어떤 영향을 주는가? • 띄어쓰기를 판별하는데 어떤 입력 정보가 가장 영향력이 있는가?
  • 39. Local Interpretable Model-agnostic Explanations (LIME) 알고리즘 분석 • 모델 예측을 할 때 크게 영향을 주는 입력 요소를 찾는 알고리즘 • 모델이 어떻게 예측 했는지 입력 데이터를 통해 시각적으로 표현 LIME 알고리즘 분석 예시 참고링크: https://dreamgonfly.github.io/2017/11/05/LIME.html
  • 40. 안 녕 하 세 요 저 _ 홍 길 동 입 니 다 안 녕 하 세 요 _ 는 홍 길 _ 입 니 다 안 녕 하 _ 요 저 는 홍 길 동 입 니 다 안 녕 _ _ 요 저 는 홍 _ _ 입 니 다 띄어쓰기 모델에서 LIME 알고리즘 활용 • ‘홍’ 이란 어절을 띄어쓰기를 하는데 어느 음절 토큰이 얼마나 기여하는가? 안녕하세요저는홍길동입니다 ➔ 안녕하세요 저는 홍길동입니다 띄어쓰기: 0.2 띄어쓰기: 0.5 띄어쓰기: 0.8 띄어쓰기: 0.7
  • 41. LIME을 통한 띄어쓰기 모델 분석 • 경계 인식 모델 띄어 쓰기 전 토큰의 영향을 많이 받음 • 영역 인식 모델 띄어 쓰는 지점 주변 토큰의 영향을 고르게 받음 • 상대적으로 “입력 정보를 편향적으로 받지 않는” 점이 좋은 띄어쓰기 예측하는 것으로 보임 경계 인식 모델 분석 영역 인식 모델 분석 입력: 안녕하세요저는홍길동입니다 출력: 안녕하세요 저는 홍길동입니다
  • 43. Transformer Network • Self Attention 기법으로 시퀀스 정보들 간의 관계를 학습 • Multi-head Attention 으로 다양한 관점에서 시퀀스 관계를 볼 수 있도록 함 Transformer EncoderSelf Attention 참고링크: http://jalammar.github.io/illustrated-transformer/
  • 44. Korean BERT (ETRI ver.) • Transformer Encoder로 구성된 모델 • 한국어 텍스트 데이터를 Semi-Unsupervised Learning 하여 언어 모델로 학습 • Fine-tuning 만으로 여러 NLP Task에서 좋은 성능을 보임 ETRI Korean BERT 참고링크: http://jalammar.github.io/illustrated-bert/
  • 45. Korean BERT 구현 - Initialize import torch.nn as nn from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel class BertTagger(BertPreTrainedModel): def __init__(self, config, tag_size, pad_idx=0, cls_idx=2): super(BertTagger, self).__init__(config) self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size self.bert = BertModel(config) self.dense = nn.Linear(config.hidden_size, config.hidden_size) self.activation = nn.Tanh() self.dense_2 = nn.Linear(config.hidden_size, tag_size) self.ce_loss = nn.CrossEntropyLoss(reduction='none') BERT Layer
  • 46. Korean BERT 구현 - Initialize import torch.nn as nn from pytorch_pretrained_bert.modeling import BertPreTrainedModel, BertModel class BertTagger(BertPreTrainedModel): def __init__(self, config, tag_size, pad_idx=0, cls_idx=2): super(BertTagger, self).__init__(config) self._pad_idx, self._cls_idx, self._tag_size = pad_idx, cls_idx, tag_size self.bert = BertModel(config) self.dense = nn.Linear(config.hidden_size, config.hidden_size) self.activation = nn.Tanh() self.dense_2 = nn.Linear(config.hidden_size, tag_size) self.ce_loss = nn.CrossEntropyLoss(reduction='none') Dense Layer
  • 47. Korean BERT 구현 - Inference class BertTagger(BertPreTrainedModel): def forward(self, x: torch.Tensor): batch_size = x.size(0) cls_mark = torch.full((batch_size, 1), self._cls_idx).to(self.device) x = torch.cat([x, cls_mark], dim=-1) masking = x.ne(self._pad_idx) encoder_layer, _ = self.bert(x, attention_mask=masking, output_all_encoded_layers=False) dense_layer = self.activation(self.dense(encoder_layer [:, 1:])) emissions = nn.functional.softmax(self.dense_2(dense_layer), dim=-1) path = torch.argmax(emissions, dim=-1) return path BERT 모델 입력값 준비 Masking
  • 48. Korean BERT 성능 결과 KoSpacing BiLSTM-CRF (영역) KoBERT (3 Layers) KoBERT (6 Layers) F1 Score - 97.83 98.62 98.70 WER Score 18.05 11.91 8.08 7.63 SER Score 49.77 39.11 30.24 28.65
  • 49. Korean BERT 처리 속도 비교 length BiLSTM-CRF (영역) 15 0.004 (± 0.001) 50 0.014 (± 0.001) 100 0.03 (± 0.001) KoBERT (3 Layers) 0.018 (± 0.003) 0.038 (± 0.002) 0.073 (± 0.003) KoBERT (6 Layers) 0.035 (± 0.003) 0.076 (± 0.003) 0.141 (± 0.003) *처리속도 (1건 당 sec) - CPU model: AMD Ryzen 7 1700 8-core. - RAM: 64GB
  • 51. 정리 • 수집 데이터를 활용한 띄어쓰기 프로그램 개발 (세종 코퍼스 데이터셋으로 검증) • 학습한 모델이 모든 범주에 대한 띄어쓰기를 잘 할 수 있지는 않음 • 띄어 쓴 정보를 수용할 수 있는 공백 정보 반영 학습을 적용해 볼 필요 있음 • 가급적 띄어쓰기가 잘 된 데이터를 많이 학습해 볼 것
  • 53. TaKos(Train-able Korean spacing) Project • 데이터 학습 가능한 띄어쓰기 알고리즘을 만들기 위한 프로젝트 • Github에서 TaKos 프로젝트를 다운로드 • 프로젝트 내에서 명령어 실행 pip install -r requirements python setup.py install TaKos Project Repo: github.com/Taekyoon/takos-alpha
  • 54. TaKos(Train-able Korean spacing) Project • 띄어쓰기 데이터만 주어지면 모델 학습하여 제공 # 간단하게 띄어쓰기 모델을 만들어 봅시다 from takos.agents.word_segment import WordSegmentAgent spacing_agent = WordSegmentAgent('your_config.json’) spacing_agent.train() spacing_agent.eval() spacing_agent('학교종이땡땡땡') { ....... "dataset": { "name": "your_dataset", "train": { "input":"./samples/train.txt" }, "test": { "input": "./samples/test.txt" } } ....... }
  • 55. Q & A
  • 57. 띄어쓰기로 인한 문제 (추가-1) • 띄어쓰기를 잘못하면 토큰 인덱싱에서 어려워짐 # BertTokenizer or WordPiece case (ETRI Bert) tokenizer = BertTokenizer.from_pretrained('vocab.korean.rawtext.list’) tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무 기대 안하고 갔나’) >>> [1051, 5132, 129, 58, 1976, 230] tokenizer.convert_tokens_to_ids(tokenizer.tokenize('너무기대 안하고갔나’)) >>> [567, 69, 5132, 129, 660, 1976, 230] # 띄어쓰기에 따라 변환된 인덱스 값이 다름
  • 58. 띄어쓰기가 필요한 문제 (추가-2) • Speech to Text Case (Google Speech API) “콜라는_하나만_가져_주_셔도_될_것_같_아요_여기_위치는_올림픽_공원_평화의 문_부분이고요 _만나서_결제할게요”
  • 59. • configs.json { "type": "word_segment", "gpu_device": 0, "dataset": { "name": "sejong_spacing", "train": { "bi_tags_only": false, "vocab_min_freq": 10, "input": "train.txt"}, "test": { "limit_len": 150, "input": "test.txt"} }, "deploy": { "path": "./tmp/test_model"}, "model": { "type": "bilstm_crf", "parameters": { "word_embedding_dims": 32, "hidden_dims": 64} }, "train": { "epochs": 50, "eval_steps": 1000, "eval_batch_size": 512, "batch_size": 128, "sequence_length": 100 } 띄어쓰기 프로그램 설정 구성
  • 60. 띄어쓰기 프로그램 실행 구현 def run(self, query): prepro_query = self.preprocess(query) tokenized_query = self.tokenizer.tokenize(prepro_query).split() model_inputs = torch.Tensor([self.vocab.to_indices(tokenized_query)]) pred_score, tag_seq = self.model(model_inputs) labeled_tag_seq = self.label.to_tokens(tag_seq[0].tolist()) post_processed = self.postprocess(prepro_query, labeled_tag_seq) outputs = {'output': post_processed} return outputs 입력 텍스트 전처리 띄어쓰기 처리
  • 61. 띄어쓰기 모델 학습 구현 def train(self): train_configs = self.configs['train'] train_dataset_configs = self.configs['dataset']['train'] data_builder = create_builder(self.task_type, train_dataset_configs) model = create_model(self.task_type, tag_to_idx, self.model_configs) trainer = create_trainer(self.task_type, model, data_builder, train_configs) trainer.train() 기능 수행을 위한 객체 생성
  • 62. 띄어쓰기 모델 평가 구현 def eval(self): test_dataset_configs = self.configs['dataset']['test'] train_dataset_configs = self.configs['dataset']['train'] data_builder = create_builder(self.task_type, train_dataset_configs) evaluator = create_evaluator(self.task_type, self.model, data_builder, test_dataset_configs, limit_len) evaluator.eval() logger.info(evaluator.summary()) 기능 수행을 위한 객체 생성
  • 63. 모델 개발에 활용한 리서치 자료 • PyKoSpacing • 2018년 HCLT 학술대회에 나온 논문들 • 문장 정보를 고려한 딥러닝 기반 자동 띄어쓰기의 개념 및 활용 • 띄어쓰기 및 문장 경계 인식을 위한 다중 손실 선형 결합 기반의 다중 클래스 분류 시스템 • CRFs와 Bi-LSTM/CRFs의 비교 분석: 자동 띄어쓰기 관점에서 • 자동띄어쓰기 오류 수정 및 복합명사 분해 개요: 2018 차세정 언어처리 경진대회
  • 64. False Case 분석 (추가) • 그 외 띄어쓰기 문제 예측 문장 정답 문장 소독용에 탄 올 스프레이를 수시로 뿌린다. 소독용 에탄올 스프레이를 수시로 뿌린다. 주말쯤 작전이 시작될 것이라고 미국 방부 및 나토 의미 관계자들이 23일 밝혔다. 주말쯤 작전이 시작될 것이라고 미 국방부 및 나토의 미 관계자들이 23일 밝혔다.
  • 65. LIME을 통한 띄어쓰기 모델 분석 (추가) 경계 인식 모델 분석 영역 인식 모델 분석 입력: 세종대왕께서한글을창조하셨다 출력: 세종대왕께서 한글을 창조하셨다 경계 인식 모델 분석 영역 인식 모델 분석 입력: 세종대왕께서한글을창조하셨다 출력: 세종대왕께서 한글을 창조하셨다