sigmadream commited on
Commit
7eb81bd
·
1 Parent(s): 593a37b
app.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import fasttext
3
+
4
+ from transformers import AutoModelForSequenceClassification
5
+ from transformers import AutoTokenizer
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+ import torch
10
+
11
+
12
+ id2label = {0: "NEGATIVE", 1: "POSITIVE"}
13
+ label2id = {"NEGATIVE": 0, "POSITIVE": 1}
14
+
15
+
16
+ title = "Movie Review Score Discriminator"
17
+ description = "It is a program that classifies whether it is positive or negative by entering movie reviews. \
18
+ You can choose between the Korean version and the English version. \
19
+ It also provides a version called ""Default"", which determines whether it is Korean or English and predicts it."
20
+
21
+
22
+ class LanguageIdentification:
23
+ def __init__(self):
24
+ pretrained_lang_model = "./lid.176.ftz"
25
+ self.model = fasttext.load_model(pretrained_lang_model)
26
+
27
+ def predict_lang(self, text):
28
+ predictions = self.model.predict(text, k=200) # returns top 200 matching languages
29
+ return predictions
30
+
31
+ LANGUAGE = LanguageIdentification()
32
+
33
+
34
+
35
+ def tokenized_data(tokenizer, inputs):
36
+ return tokenizer.batch_encode_plus(
37
+ [inputs],
38
+ return_tensors="pt",
39
+ padding="max_length",
40
+ max_length=64,
41
+ truncation=True)
42
+
43
+
44
+
45
+ examples = []
46
+ df = pd.read_csv('examples.csv', sep='\t', index_col='Unnamed: 0')
47
+ np.random.seed(100)
48
+
49
+ idx = np.random.choice(50, size=5, replace=False)
50
+ eng_examples = [ ['Eng', df.iloc[i, 0]] for i in idx ]
51
+ kor_examples = [ ['Kor', df.iloc[i, 1]] for i in idx ]
52
+ examples = eng_examples + kor_examples
53
+
54
+
55
+
56
+ eng_model_name = "roberta-base"
57
+ eng_step = 1900
58
+ eng_tokenizer = AutoTokenizer.from_pretrained(eng_model_name)
59
+ eng_file_name = "{}-{}.pt".format(eng_model_name, eng_step)
60
+ eng_state_dict = torch.load(eng_file_name)
61
+ eng_model = AutoModelForSequenceClassification.from_pretrained(
62
+ eng_model_name, num_labels=2, id2label=id2label, label2id=label2id,
63
+ state_dict=eng_state_dict
64
+ )
65
+
66
+
67
+ kor_model_name = "klue/roberta-small"
68
+ kor_step = 2400
69
+ kor_tokenizer = AutoTokenizer.from_pretrained(kor_model_name)
70
+ kor_file_name = "{}-{}.pt".format(kor_model_name.replace('/', '_'), kor_step)
71
+ kor_state_dict = torch.load(kor_file_name)
72
+ kor_model = AutoModelForSequenceClassification.from_pretrained(
73
+ kor_model_name, num_labels=2, id2label=id2label, label2id=label2id,
74
+ state_dict=kor_state_dict
75
+ )
76
+
77
+
78
+ def builder(Lang, Text):
79
+ percent_kor, percent_eng = 0, 0
80
+ text_list = Text.split(' ')
81
+
82
+
83
+ # [ output_1 ]
84
+ if Lang == '언어감지 기능 사용':
85
+ pred = LANGUAGE.predict_lang(Text)
86
+ if '__label__en' in pred[0]:
87
+ Lang = 'Eng'
88
+ idx = pred[0].index('__label__en')
89
+ p_eng = pred[1][idx]
90
+ if '__label__ko' in pred[0]:
91
+ Lang = 'Kor'
92
+ idx = pred[0].index('__label__ko')
93
+ p_kor = pred[1][idx]
94
+ # Normalize Percentage
95
+ percent_kor = p_kor / (p_kor+p_eng)
96
+ percent_eng = p_eng / (p_kor+p_eng)
97
+
98
+ if Lang == 'Eng':
99
+ model = eng_model
100
+ tokenizer = eng_tokenizer
101
+ if percent_eng==0: percent_eng=1
102
+
103
+ if Lang == 'Kor':
104
+ model = kor_model
105
+ tokenizer = kor_tokenizer
106
+ if percent_kor==0: percent_kor=1
107
+
108
+
109
+ # [ output_2 ]
110
+ inputs = tokenized_data(tokenizer, Text)
111
+ model.eval()
112
+ with torch.no_grad():
113
+ logits = model(input_ids=inputs['input_ids'],
114
+ attention_mask=inputs['attention_mask']).logits
115
+
116
+ m = torch.nn.Softmax(dim=1)
117
+ output = m(logits)
118
+ # print(logits, output)
119
+
120
+
121
+ # [ output_3 ]
122
+ output_analysis = []
123
+ for word in text_list:
124
+ tokenized_word = tokenized_data(tokenizer, word)
125
+ with torch.no_grad():
126
+ logit = model(input_ids=tokenized_word['input_ids'],
127
+ attention_mask=tokenized_word['attention_mask']).logits
128
+ word_output = m(logit)
129
+ if word_output[0][1] > 0.99:
130
+ output_analysis.append( (word, '+++') )
131
+ elif word_output[0][1] > 0.9:
132
+ output_analysis.append( (word, '++') )
133
+ elif word_output[0][1] > 0.8:
134
+ output_analysis.append( (word, '+') )
135
+ elif word_output[0][1] < 0.01:
136
+ output_analysis.append( (word, '---') )
137
+ elif word_output[0][1] < 0.1:
138
+ output_analysis.append( (word, '--') )
139
+ elif word_output[0][1] < 0.2:
140
+ output_analysis.append( (word, '-') )
141
+ else:
142
+ output_analysis.append( (word, None) )
143
+
144
+
145
+ return [ {'Kor': percent_kor, 'Eng': percent_eng},
146
+ {id2label[1]: output[0][1].item(), id2label[0]: output[0][0].item()},
147
+ output_analysis ]
148
+
149
+ # prediction = torch.argmax(logits, axis=1)
150
+ return id2label[prediction.item()]
151
+
152
+
153
+ # demo3 = gr.Interface.load("models/mdj1412/movie_review_score_discriminator_eng", inputs="text", outputs="text",
154
+ # title=title, theme="peach",
155
+ # allow_flagging="auto",
156
+ # description=description, examples=examples)
157
+
158
+
159
+
160
+ # demo = gr.Interface(builder, inputs=[gr.inputs.Dropdown(['Default', 'Eng', 'Kor']), gr.Textbox(placeholder="리뷰를 입력하시오.")],
161
+ # outputs=[ gr.Label(num_top_classes=3, label='Lang'),
162
+ # gr.Label(num_top_classes=2, label='Result'),
163
+ # gr.HighlightedText(label="Analysis", combine_adjacent=False)
164
+ # .style(color_map={"+++": "#CF0000", "++": "#FF3232", "+": "#FFD4D4", "---": "#0004FE", "--": "#4C47FF", "-": "#BEBDFF"}) ],
165
+ # # outputs='label',
166
+ # title=title, description=description, examples=examples)
167
+
168
+
169
+
170
+ with gr.Blocks() as demo1:
171
+ gr.Markdown(
172
+ """
173
+ <h1 align="center">
174
+ Movie Review Score Discriminator
175
+ </h1>
176
+ """)
177
+
178
+ gr.Markdown(
179
+ """
180
+ 영화 리뷰를 입력하면, 리뷰가 긍정인지 부정인지 판별해주는 모델이다. \
181
+ 영어와 한글을 지원하며, 언어를 직접 선택할수도, 혹은 모델이 언어감지를 직접 하도록 할 수 있다.
182
+ 리뷰를 입력하면, (1) 감지된 언어, (2) 긍정 리뷰일 확률과 부정 리뷰일 확률, (3) 입력된 리뷰의 어느 단어가 긍정/부정 결정에 영향을 주었는지 \
183
+ (긍정일 경우 빨강색, 부정일 경우 파란색)를 확인할 수 있다.
184
+ """)
185
+
186
+ with gr.Accordion(label="모델에 대한 설명 ( 여기를 클릭 하시오. )", open=False):
187
+ gr.Markdown(
188
+ """
189
+ 영어 모델은 bert-base-uncased 기반으로, 영어 영화 리뷰 분석 데이터셋인 SST-2로 학습 및 평가되었다.
190
+ 한글 모델은 klue/roberta-base 기반이다. 기존 한글 영화 리뷰 분석 데이터셋이 존재하지 않아, 네이버 영화의 리뷰를 크롤링해서 영화 리뷰 분석 데이터셋을 제작하고, 이를 이용하여 모델을 학습 및 평가하였다.
191
+ 영어 모델은 SST-2에서 92.8%, 한글 모델은 네이버 영화 리뷰 데이터셋에서 94%의 정확도를 가진다 (test set 기준).
192
+ 언어감지는 fasttext의 language detector를 사용하였다. 리뷰의 단어별 영향력은, 단어 각각을 모델에 넣었을 때 결과가 긍정으로 나오는지 부정으로 나오는지를 바탕으로 측정하였다.
193
+ """)
194
+
195
+ with gr.Row():
196
+ with gr.Column():
197
+ inputs_1 = gr.Dropdown(choices=['언어감지 기능 사용', 'Eng', 'Kor'], value='언어감지 기능 사용', label='Lang')
198
+ inputs_2 = gr.Textbox(placeholder="리뷰를 입력하시오.", label='Text')
199
+ with gr.Row():
200
+ # btn2 = gr.Button("클리어")
201
+ btn = gr.Button("제출하기")
202
+ with gr.Column():
203
+ output_1 = gr.Label(num_top_classes=3, label='Lang')
204
+ output_2 = gr.Label(num_top_classes=2, label='Result')
205
+ output_3 = gr.HighlightedText(label="Analysis", combine_adjacent=False) \
206
+ .style(color_map={"+++": "#CF0000", "++": "#FF3232", "+": "#FFD4D4", "---": "#0004FE", "--": "#4C47FF", "-": "#BEBDFF"})
207
+
208
+ # btn2.click(fn=fn2, inputs=[None, None], output=[output_1, output_2, output_3])
209
+ btn.click(fn=builder, inputs=[inputs_1, inputs_2], outputs=[output_1, output_2, output_3])
210
+ gr.Examples(examples, inputs=[inputs_1, inputs_2])
211
+
212
+
213
+
214
+ if __name__ == "__main__":
215
+ # print(examples)
216
+ # demo.launch()
217
+ demo1.launch()
examples.csv ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ eng kor
2
+ 0 of saucy 1점도아깝다4명보다재미없어서2명나감
3
+ 1 cold movie 매트릭스?ㄴㄴ 짜장 묻은 존윅
4
+ 2 redundant concept 개인의 선택으로 1점을 줬습니다
5
+ 3 in world cinema 보는내내 니 생각만 났다.
6
+ 4 on all cylinders 영화보다가 잠든적은 처음이네요
7
+ 5 sit through , 따뜻한 영화에요~^^추천해요!
8
+ 6 heroes 별로에요 생각보다 노잼임
9
+ 7 sharply 좋아요 가족들과 보기 좋아요
10
+ 8 sometimes dry ♡ 재밌게 잘봤습니다ㅎㅎ
11
+ 9 disappointments 반제 호빗 사랑해요~
12
+ 10 the horrors 똥도 이런 거대한 똥이 없었다..
13
+ 11 many pointless 개지립니다 나만당할순없지
14
+ 12 a beautifully 이게무슨...만화네 만화 ㅉㅉㅉ
15
+ 13 a doa 7광구와 쌍벽을 이루는 망작
16
+ 14 no apparent joy 영화 보다가 중간에 나왔습니다
17
+ 15 seem fresh 최악 그냥 보지 마세요진짜 노잼
18
+ 16 weak and 짱구 극장판은 언제나 최고에요
19
+ 17 skip this dreck , 내 시간은 소중한 거다.
20
+ 18 generates 겁나 재밌는디,,,,
21
+ 19 funny yet 그냥 개재밌음 평점 믿으면 안됨
22
+ 20 in memory 재밋게 잘봣습니다 너무좋습니다요
23
+ 21 hawaiian shirt 밥 먹으면서 보기 좋은 영화
24
+ 22 grievous but 재미와 감동을 겸비한 명작입니다!!
25
+ 23 hopeless 재개봉 감사합니다.정말로
26
+ 24 bring tissues . 끝더 이상 설명이 필요할까.
27
+ 25 just too silly 역시 믿보 황.정.민 배우님~^^
28
+ 26 cinematic bon bons 연출+연기+스토리+영상미+OST
29
+ 27 irritates and 추억에 묻어두지 그랬냐
30
+ 28 collapse 이시대 최고의 코미디 영화
31
+ 29 no lika da 재미있게 관람하였습니다
32
+ 30 a welcome relief 스마우그랑 있을땐 스릴이 많다.
33
+ 31 , compelling 처음으로 극장에서 잤습니다
34
+ 32 infectiously 너무나도 잘봤어요 굿입니댜
35
+ 33 imax in short ㅈㄹ게 웃기고 잼있네.ㅋ
36
+ 34 i hate it . 연말에 보면 뭉클하다 정말
37
+ 35 a good one 그냥 게임으로 내지 그랬냐.
38
+ 36 , plodding picture 진짜 강추 최고의 한국영화
39
+ 37 inane and awful 진짜최악입니다...명절에보세요
40
+ 38 whole mess 대망작 보지마세요 돈 아까움
41
+ 39 enjoy the ride 이거 볼 시간에 야동이나 봐라
42
+ 40 the horror 너무너무 재밌음 버즈 최고
43
+ 41 a dim 3시간이 전혀 아깝지 않은
44
+ 42 amazingly lame . 졸작이다..
45
+ 43 to spare wildlife 노우잼스ㅡ 이만잡 열자 채우기
46
+ 44 carnage and 2022년 최고 한국영화
47
+ 45 second fiddle 재미없다너무재미없다OST지겹다
48
+ 46 a stylish exercise 나름 재밌게 봄 가볍게 보기 좋은듯
49
+ 47 than this mess 와...감독판이 더좋다... 더긴데
50
+ 48 valuable messages 갑자기 도게자 ㄹㅇㅋㅋ
51
+ 49 usual worst 별점 1점도 주기가 아까운 영화..
gitattributes.txt ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tflite filter=lfs diff=lfs merge=lfs -text
29
+ *.tgz filter=lfs diff=lfs merge=lfs -text
30
+ *.wasm filter=lfs diff=lfs merge=lfs -text
31
+ *.xz filter=lfs diff=lfs merge=lfs -text
32
+ *.zip filter=lfs diff=lfs merge=lfs -text
33
+ *.zst filter=lfs diff=lfs merge=lfs -text
34
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
klue_roberta-small-2400.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1b572a576888999c3696750507168b1ec8c194b93e3b0a5fb69d5932cb61a410
3
+ size 272408049
lid.176.ftz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8f3472cfe8738a7b6099e8e999c3cbfae0dcd15696aac7d7738a8039db603e83
3
+ size 938013
model-1900.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1f0dcb5d42751656f47868d0b1cd793c33bd2c497df57dde5514a2b15a791d05
3
+ size 498658641
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio
2
+ datasets
3
+ transformers
4
+ torch
5
+ pandas
6
+ numpy
7
+ fasttext
roberta-base-1900.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1f0dcb5d42751656f47868d0b1cd793c33bd2c497df57dde5514a2b15a791d05
3
+ size 498658641