김봉민

Update README.md

Showing 1 changed file with 240 additions and 1 deletions
1 -test
...\ No newline at end of file ...\ No newline at end of file
1 +# Ko-Sentence-BERT
2 +https://github.com/BM-K/KoSentenceBERT <br>
3 +Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks (EMNLP 2019) 논문에서 공개한 코드, kakaobrain 팀이 공개한 KorNLUDatasets 과 ETRI KorBERT를 통해 Korea Sentence BERT를 학습하였습니다.
4 +
5 +## Installation
6 +ETRI KorBERT는 transformers 2.4.1 ~ 2.8.0에서만 동작하고 Sentence-BERT는 3.1.0 버전 이상에서 동작하여 라이브러리를 수정하였습니다. <br>
7 +**huggingface transformer, sentence transformers, tokenizers** 라이브러리 코드를 직접 수정하므로 가상환경 사용을 권장합니다. <br>
8 +사용한 Docker image는 Docker Hub에 첨부합니다. https://hub.docker.com/r/klbm126/kosbert_image/tags <br>
9 +ETRI KoBERT를 사용하여 학습하였고 본 레파지토리에선 ETRI KoBERT를 제공하지 않습니다.
10 +```
11 +git clone https://github.com/BM-K/KoSentenceBERT.git
12 +python -m venv .KoSBERT
13 +. .KoSBERT/bin/activate
14 +pip install -r requirements.txt
15 +```
16 +transformer, tokenizers, sentence_transformers 디렉토리를 .KoSBERT/lib/python3.7/site-packages/ 로 이동합니다. <br>
17 +ETRI_KoBERT 모델과 tokenizer가 KoSentenceBERT 디렉토리 안에 존재하여야 합니다.<br>
18 +ETRI 모델과 tokenizer는 다음 예시와 같이 불러옵니다 :
19 +
20 +```python
21 +from ETRI_tok.tokenization_etri_eojeol import BertTokenizer
22 +self.auto_model = BertModel.from_pretrained('./ETRI_KoBERT/003_bert_eojeol_pytorch')
23 +self.tokenizer = BertTokenizer.from_pretrained('./ETRI_KoBERT/003_bert_eojeol_pytorch/vocab.txt', do_lower_case=False)
24 +```
25 +
26 +## Train Models
27 +모델 학습을 원하시면 KoSentenceBERT 디렉토리 안에 KorNLUDatasets이 존재하여야 합니다. <br>
28 +저는 STS를 학습할 때에 모델 구조에 맞게 STS데이터를 수정하여 사용하였고 데이터와 학습 방법은 아래와 같습니다 : <br><br>
29 +KoSentenceBERT/KorNLUDatates/KorSTS/tune_test.tsv <br>
30 +<img src="https://user-images.githubusercontent.com/55969260/93304207-97afec00-f837-11ea-88a2-7256f2f1664e.png"></img>
31 +*STS test 데이터셋의 일부* <br>
32 +```
33 +python training_nli.py # NLI 데이터로만 학습
34 +python training_sts.py # STS 데이터로만 학습
35 +python con_training_sts.py # NLI 데이터로 학습 후 STS 데이터로 Fine-Tuning
36 +```
37 +
38 +## Pre-Trained Models
39 +**pooling mode****MEAN-strategy**를 사용하였으며, 학습시 모델은 output 디렉토리에 저장 됩니다. <br>
40 +<img src='https://user-images.githubusercontent.com/55969260/99897241-43176a00-2cdb-11eb-8359-957667e4ac42.png'>
41 +
42 +## Performance
43 +Seed 고정, Dev set
44 +<img src='https://user-images.githubusercontent.com/55969260/99897252-5aeeee00-2cdb-11eb-9b14-bc412ae0fb8b.png'>
45 +
46 +향상된 모델 성능은 다음 레파지토리에 있습니다. <br> https://github.com/BM-K/KoSentenceBERT_V2
47 +
48 +## Application Examples
49 +생성 된 문장 임베딩을 다운 스트림 애플리케이션에 사용할 수 있는 방법에 대한 몇 가지 예를 제시합니다.
50 +<br> 제일 높은 성능을 내는 STS + NLI pretrained 모델을 통해 진행합니다.
51 +
52 +### Semantic Search
53 +SemanticSearch.py는 주어진 문장과 유사한 문장을 찾는 작업입니다.<br>
54 +먼저 Corpus의 모든 문장에 대한 임베딩을 생성합니다.
55 +```python
56 +from sentence_transformers import SentenceTransformer, util
57 +import numpy as np
58 +
59 +model_path = './output/training_nli_sts_ETRI_KoBERT-003_bert_eojeol'
60 +
61 +embedder = SentenceTransformer(model_path)
62 +
63 +# Corpus with example sentences
64 +corpus = ['한 남자가 음식을 먹는다.',
65 + '한 남자가 빵 한 조각을 먹는다.',
66 + '그 여자가 아이를 돌본다.',
67 + '한 남자가 말을 탄다.',
68 + '한 여자가 바이올린을 연주한다.',
69 + '두 남자가 수레를 숲 속으로 밀었다.',
70 + '한 남자가 담으로 싸인 땅에서 백마를 타고 있다.',
71 + '원숭이 한 마리가 드럼을 연주한다.',
72 + '치타 한 마리가 먹이 뒤에서 달리고 있다.']
73 +
74 +corpus_embeddings = embedder.encode(corpus, convert_to_tensor=True)
75 +
76 +# Query sentences:
77 +queries = ['한 남자가 파스타를 먹는다.',
78 + '고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.',
79 + '치타가 들판을 가로 질러 먹이를 쫓는다.']
80 +
81 +# Find the closest 5 sentences of the corpus for each query sentence based on cosine similarity
82 +top_k = 5
83 +for query in queries:
84 + query_embedding = embedder.encode(query, convert_to_tensor=True)
85 + cos_scores = util.pytorch_cos_sim(query_embedding, corpus_embeddings)[0]
86 + cos_scores = cos_scores.cpu()
87 +
88 + #We use np.argpartition, to only partially sort the top_k results
89 + top_results = np.argpartition(-cos_scores, range(top_k))[0:top_k]
90 +
91 + print("\n\n======================\n\n")
92 + print("Query:", query)
93 + print("\nTop 5 most similar sentences in corpus:")
94 +
95 + for idx in top_results[0:top_k]:
96 + print(corpus[idx].strip(), "(Score: %.4f)" % (cos_scores[idx]))
97 +
98 +```
99 +<br> 결과는 다음과 같습니다 :
100 +```
101 +========================
102 +
103 +
104 +Query: 한 남자가 파스타를 먹는다.
105 +
106 +Top 5 most similar sentences in corpus:
107 +한 남자가 음식을 먹는다. (Score: 0.7557)
108 +한 남자가 빵 한 조각을 먹는다. (Score: 0.6464)
109 +한 남자가 담으로 싸인 땅에서 백마를 타고 있다. (Score: 0.2565)
110 +한 남자가 말을 탄다. (Score: 0.2333)
111 +두 남자가 수레를 숲 속으로 밀었다. (Score: 0.1792)
112 +
113 +
114 +========================
115 +
116 +
117 +Query: 고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.
118 +
119 +Top 5 most similar sentences in corpus:
120 +원숭이 한 마리가 드럼을 연주한다. (Score: 0.6732)
121 +치타 한 마리가 먹이 뒤에서 달리고 있다. (Score: 0.3401)
122 +두 남자가 수레를 숲 속으로 밀었다. (Score: 0.1037)
123 +한 남자가 음식을 먹는다. (Score: 0.0617)
124 +그 여자가 아이를 돌본다. (Score: 0.0466)
125 +
126 +
127 +=======================
128 +
129 +
130 +Query: 치타가 들판을 가로 질러 먹이를 쫓는다.
131 +
132 +Top 5 most similar sentences in corpus:
133 +치타 한 마리가 먹이 뒤에서 달리고 있다. (Score: 0.7164)
134 +두 남자가 수레를 숲 속으로 밀었다. (Score: 0.3216)
135 +원숭이 한 마리가 드럼을 연주한다. (Score: 0.2071)
136 +한 남자가 빵 한 조각을 먹는다. (Score: 0.1089)
137 +한 남자가 음식을 먹는다. (Score: 0.0724)
138 +```
139 +### Clustering
140 +Clustering.py는 문장 임베딩 유사성을 기반으로 유사한 문장을 클러스터링하는 예를 보여줍니다. <br>
141 +이전과 마찬가지로 먼저 각 문장에 대한 임베딩을 계산합니다. <br>
142 +```python
143 +from sentence_transformers import SentenceTransformer, util
144 +import numpy as np
145 +
146 +model_path = './output/training_nli_sts_ETRI_KoBERT-003_bert_eojeol'
147 +
148 +embedder = SentenceTransformer(model_path)
149 +
150 +# Corpus with example sentences
151 +corpus = ['한 남자가 음식을 먹는다.',
152 + '한 남자가 빵 한 조각을 먹는다.',
153 + '그 여자가 아이를 돌본다.',
154 + '한 남자가 말을 탄다.',
155 + '한 여자가 바이올린을 연주한다.',
156 + '두 남자가 수레를 숲 속으로 밀었다.',
157 + '한 남자가 담으로 싸인 땅에서 백마를 타고 있다.',
158 + '원숭이 한 마리가 드럼을 연주한다.',
159 + '치타 한 마리가 먹이 뒤에서 달리고 있다.',
160 + '한 남자가 파스타를 먹는다.',
161 + '고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.',
162 + '치타가 들판을 가로 질러 먹이를 쫓는다.']
163 +
164 +corpus_embeddings = embedder.encode(corpus)
165 +
166 +# Then, we perform k-means clustering using sklearn:
167 +from sklearn.cluster import KMeans
168 +
169 +num_clusters = 5
170 +clustering_model = KMeans(n_clusters=num_clusters)
171 +clustering_model.fit(corpus_embeddings)
172 +cluster_assignment = clustering_model.labels_
173 +
174 +clustered_sentences = [[] for i in range(num_clusters)]
175 +for sentence_id, cluster_id in enumerate(cluster_assignment):
176 + clustered_sentences[cluster_id].append(corpus[sentence_id])
177 +
178 +for i, cluster in enumerate(clustered_sentences):
179 + print("Cluster ", i+1)
180 + print(cluster)
181 + print("")
182 +
183 +```
184 +결과는 다음과 같습니다 :
185 + ```
186 + Cluster 1
187 +['두 남자가 수레를 숲 속으로 밀었다.', '치타 한 마리가 먹이 뒤에서 달리고 있다.', '치타가 들판을 가로 질러 먹이를 쫓는다.']
188 +
189 +Cluster 2
190 +['한 남자가 말을 탄다.', '한 남자가 담으로 싸인 땅에서 백마를 타고 있다.']
191 +
192 +Cluster 3
193 +['한 남자가 음식을 먹는다.', '한 남자가 빵 한 조각을 먹는다.', '한 남자가 파스타를 먹는다.']
194 +
195 +Cluster 4
196 +['그 여자가 아이를 돌본다.', '한 여자가 바이올린을 연주한다.']
197 +
198 +Cluster 5
199 +['원숭이 한 마리가 드럼을 연주한다.', '고릴라 의상을 입은 누군가가 드럼을 연주하고 있다.']
200 +```
201 +<img src = "https://user-images.githubusercontent.com/55969260/96250228-78001500-0fe9-11eb-9ee5-914705182a55.png">
202 +
203 +## Downstream Tasks Demo
204 +<img src = "https://user-images.githubusercontent.com/55969260/99897723-73610780-2cdf-11eb-9b71-3d31a309a53a.gif"> <br>
205 +<img src = "https://user-images.githubusercontent.com/55969260/99897743-94295d00-2cdf-11eb-9b16-d6fec66e43d0.gif"> <br>
206 +<img src = "https://user-images.githubusercontent.com/55969260/99897764-a73c2d00-2cdf-11eb-8bcf-0235d1fda0f7.gif"> <br>
207 +데모 영상으로 제작된 버전은 다음 레파지토리에 있습니다. <br> https://github.com/BM-K/KoSentenceBERT_V2
208 +
209 +## Citing
210 +### KorNLU Datasets
211 +```bibtex
212 +@article{ham2020kornli,
213 + title={KorNLI and KorSTS: New Benchmark Datasets for Korean Natural Language Understanding},
214 + author={Ham, Jiyeon and Choe, Yo Joong and Park, Kyubyong and Choi, Ilji and Soh, Hyungjoon},
215 + journal={arXiv preprint arXiv:2004.03289},
216 + year={2020}
217 +}
218 +```
219 +### Sentence Transformers: Multilingual Sentence Embeddings using BERT / RoBERTa / XLM-RoBERTa & Co. with PyTorch
220 +```bibtex
221 +@inproceedings{reimers-2019-sentence-bert,
222 + title = "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks",
223 + author = "Reimers, Nils and Gurevych, Iryna",
224 + booktitle = "Proceedings of the 2019 Conference on Empirical Methods in Natural Language Processing",
225 + month = "11",
226 + year = "2019",
227 + publisher = "Association for Computational Linguistics",
228 + url = "http://arxiv.org/abs/1908.10084",
229 +}
230 +
231 +@article{reimers-2020-multilingual-sentence-bert,
232 + title = "Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation",
233 + author = "Reimers, Nils and Gurevych, Iryna",
234 + journal= "arXiv preprint arXiv:2004.09813",
235 + month = "04",
236 + year = "2020",
237 + url = "http://arxiv.org/abs/2004.09813",
238 +}
239 +```
240 +
......