├── .idea
├── .gitignore
├── inspectionProfiles
│ └── profiles_settings.xml
├── modules.xml
├── misc.xml
└── Douban_Bert.iml
├── static
├── images
│ ├── 1.png
│ ├── 231156ce864cdf68ce8ec4da608f6c5.jpg
│ ├── 57cd2966e2199a959f6b956d2741ce4.jpg
│ ├── 595d7f60e388652232aeda9a3f4f096.jpg
│ ├── 7c62f9fc1b977eee788f421e5145fa7.jpg
│ ├── c2054c88b61683933031860d6838197.jpg
│ ├── cebeb11125c6c963b6a04fc48f61182.jpg
│ ├── e8be7a6fb5c361ddba9dfcf8bbb8116.jpg
│ └── cebeb11125c6c963b6a04fc48f61182-4.jpg
├── Home.css
├── Home.html
├── index.html
└── jquery.js
├── __pycache__
├── app.cpython-39.pyc
├── predict.cpython-39.pyc
└── data_process.cpython-39.pyc
├── requirements.txt
├── templates
├── output.html
├── input.html
├── index.html
└── Home.html
├── README.md
├── app.py
├── predict.py
├── data_process.py
├── cache
└── logs
│ ├── 2022-04-09-20-42.log
│ └── 2022-04-09-23-54.log
└── model.py
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/static/images/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/1.png
--------------------------------------------------------------------------------
/__pycache__/app.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/__pycache__/app.cpython-39.pyc
--------------------------------------------------------------------------------
/__pycache__/predict.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/__pycache__/predict.cpython-39.pyc
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask==1.1.2
2 | matplotlib==3.4.3
3 | numpy==1.20.3
4 | pandas==1.3.4
5 | torch==1.10.1
6 | transformers==4.7.0
7 |
--------------------------------------------------------------------------------
/__pycache__/data_process.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/__pycache__/data_process.cpython-39.pyc
--------------------------------------------------------------------------------
/static/images/231156ce864cdf68ce8ec4da608f6c5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/231156ce864cdf68ce8ec4da608f6c5.jpg
--------------------------------------------------------------------------------
/static/images/57cd2966e2199a959f6b956d2741ce4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/57cd2966e2199a959f6b956d2741ce4.jpg
--------------------------------------------------------------------------------
/static/images/595d7f60e388652232aeda9a3f4f096.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/595d7f60e388652232aeda9a3f4f096.jpg
--------------------------------------------------------------------------------
/static/images/7c62f9fc1b977eee788f421e5145fa7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/7c62f9fc1b977eee788f421e5145fa7.jpg
--------------------------------------------------------------------------------
/static/images/c2054c88b61683933031860d6838197.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/c2054c88b61683933031860d6838197.jpg
--------------------------------------------------------------------------------
/static/images/cebeb11125c6c963b6a04fc48f61182.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/cebeb11125c6c963b6a04fc48f61182.jpg
--------------------------------------------------------------------------------
/static/images/e8be7a6fb5c361ddba9dfcf8bbb8116.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/e8be7a6fb5c361ddba9dfcf8bbb8116.jpg
--------------------------------------------------------------------------------
/static/images/cebeb11125c6c963b6a04fc48f61182-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ezreal-Jing/Douban_BERT/HEAD/static/images/cebeb11125c6c963b6a04fc48f61182-4.jpg
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/Douban_Bert.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/templates/output.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 豆瓣影评情感分析平台
6 |
7 |
8 | 豆瓣影评情感分析平台
9 |
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 基于BERT的豆瓣影评情感分析
2 | ## 简介
3 |
4 | 本项目基于Huggingface开源的transformers库,实现对豆瓣电影短评的情感分类。
5 |
6 | ## 使用说明
7 |
8 | data_process.py——数据预处理
9 |
10 | model.py——模型训练、评估,其中使用了bert-base-chinese等预训练模型,可以从huggingface下载,也可以直接运行代码自动下载。ubuntu系统下模型自动下载路径:用户文件夹/.cache/huggingface/transformers
11 |
12 | predict.py——对模型进行封装,实现输入一个句子,输出一个标签
13 |
14 | app.py——使用flask框架将模型部署到网页
15 |
16 | ## 具体细节
17 |
18 | 待更新
19 |
--------------------------------------------------------------------------------
/templates/input.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 豆瓣影评情感分析平台
6 |
7 |
8 | 豆瓣影评情感分析平台
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author : Ezreal
3 | # @File : app.py
4 | # @Project: Douban_Bert
5 | # @CreateTime : 2022/3/13 下午6:51:12
6 | # @Version:V 0.1
7 | from flask import Flask, render_template, request
8 | import time
9 | from datetime import timedelta
10 | import predict
11 | '''
12 | 使用flask框架实现网页可视化
13 | '''
14 |
15 | app = Flask(__name__)
16 | # 设置静态文件缓存过期时间
17 | app.send_file_max_age_default = timedelta(seconds=1)
18 |
19 | # @app.route('/resnet', methods=['POST', 'GET'])
20 | @app.route('/', methods=['POST', 'GET']) # 添加路由
21 | def upload():
22 | if request.method == 'POST':
23 |
24 | user_input = request.form.get("name")#用户输入
25 | result = predict.predict(user_input)#调用predict进行预测
26 |
27 | return render_template(
28 | 'output.html',
29 | userinput=user_input,#用户输入
30 | classresult=result,
31 | val1=time.time()
32 | )
33 | return render_template('index.html')
34 |
35 | if __name__ == '__main__':
36 |
37 | app.run(host='127.0.0.1', port=5000, debug=True)
--------------------------------------------------------------------------------
/predict.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author : Ezreal
3 | # @File : predict.py
4 | # @Project: Douban_Bert
5 | # @CreateTime : 2022/3/13 上午12:08:22
6 | # @Version:V 0.1
7 |
8 | import torch
9 | from transformers import BertConfig, BertForSequenceClassification, BertTokenizer
10 | import torch.nn.functional as F
11 | '''
12 | 封装模型
13 | '''
14 | def to_input_id(sentence_input):
15 | tokenizer = BertTokenizer(vocab_file='bert-base-chinese/vocab.txt')
16 | return tokenizer.build_inputs_with_special_tokens(tokenizer.convert_tokens_to_ids(tokenizer.tokenize(sentence_input)))
17 | emotion_dict = {"很差":0, "较差":1, "一般":2, "还行":3, "力荐":4}
18 |
19 | def getDictKey(myDict, value):
20 | return [k for k, v in myDict.items() if v == value]
21 |
22 | def predict(text):
23 | # tokenizer = BertTokenizer(vocab_file='bert-base-chinese/vocab.txt')
24 | # config = BertConfig.from_pretrained('cache/config.json')
25 | model = BertForSequenceClassification.from_pretrained('cache')
26 | model.eval()
27 |
28 |
29 | sentence = text
30 |
31 | input_id = to_input_id(sentence)
32 | assert len(input_id) <= 512
33 | input_ids = torch.LongTensor(input_id).unsqueeze(0)
34 |
35 | # predict时,沒有label所以沒有loss
36 | outputs = model(input_ids)
37 |
38 | prediction = torch.max(F.softmax(outputs[0], dim=-1), dim=1)[1] # 返回索引值
39 | predict_label = prediction.data.cpu().numpy().squeeze() # 降维
40 |
41 | result = getDictKey(emotion_dict, predict_label)
42 |
43 | return result
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | if __name__ == "__main__":
52 |
53 | result = predict("燃爆")
54 | print(result)
--------------------------------------------------------------------------------
/data_process.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author : Ezreal
3 | # @File : predict.py
4 | # @Project: Douban_Bert
5 | # @CreateTime : 2022/3/13 上午12:08:22
6 | # @Version:V 0.1
7 | '''
8 | 数据预处理
9 | '''
10 | import pandas as pd
11 | import torch
12 | from transformers import Trainer,TrainingArguments, BertTokenizer, BertModel, BertPreTrainedModel,BertConfig
13 | from torch.utils.data import Dataset, DataLoader
14 | import warnings
15 | warnings.filterwarnings('ignore')
16 | import sys
17 | sys.setrecursionlimit(3000)
18 | import re
19 |
20 | def tokenize(content):
21 | filters = ['\t','\n','\x97','\x96','#','$','%','&',':',',','。','\.','“','”','"','《','》'," ","@","、","-","(",")","0","1","2","3","4","5","6","7","8","9"]
22 | content = re.sub("|".join(filters),"",content)
23 | return content
24 |
25 |
26 | def read_data(data_dir):
27 | data = pd.read_csv(data_dir)
28 | data['comments'] = data['comments'].fillna('')
29 | return data
30 |
31 | def fill_paddings(data, maxlen):
32 | '''补全句长'''
33 | if len(data) < maxlen:
34 | pad_len = maxlen-len(data)
35 | paddings = [0 for _ in range(pad_len)]
36 | data = torch.tensor(data + paddings)
37 | else:
38 | data = torch.tensor(data[:maxlen])
39 | return data
40 |
41 | class InputDataSet():
42 |
43 | def __init__(self,data,tokenizer,max_len):
44 | self.data = data
45 | self.tokenizer = tokenizer
46 | self.max_len = max_len#最大句长
47 |
48 | def __len__(self,):
49 | return len(self.data)
50 |
51 | def __getitem__(self, item):
52 | text = str(self.data['comments'][item])
53 | labels = self.data['rating'][item]
54 | labels = torch.tensor(labels, dtype=torch.long)
55 |
56 | ## 手动构建
57 | tokens = self.tokenizer.tokenize(text)
58 | tokens_ids = self.tokenizer.convert_tokens_to_ids(tokens)
59 | tokens_ids = [101] + tokens_ids + [102]
60 | input_ids = fill_paddings(tokens_ids,self.max_len)
61 |
62 | attention_mask = [1 for _ in range(len(tokens_ids))]#这里注意传入的是tokens_ids
63 | attention_mask = fill_paddings(attention_mask,self.max_len)
64 |
65 | token_type_ids = [0 for _ in range(len(tokens_ids))]
66 | token_type_ids = fill_paddings(token_type_ids,self.max_len)
67 |
68 | return {
69 | 'text':text,
70 | 'input_ids':input_ids,
71 | 'attention_mask':attention_mask,
72 | 'token_type_ids':token_type_ids,
73 | 'labels':labels-1
74 |
75 | }
76 |
77 |
78 | if __name__ == '__main__':
79 | train_dir = 'data/train.csv'
80 | dev_dir = 'data/test.csv'
81 | model_dir = 'bert-base-chinese'
82 | train = read_data(train_dir)
83 | test = read_data(dev_dir)
84 | tokenizer = BertTokenizer.from_pretrained(model_dir)
85 | train_dataset = InputDataSet(train,tokenizer=tokenizer, max_len=128)
86 | train_dataloader = DataLoader(train_dataset,batch_size=4)
87 | batch = next(iter(train_dataloader))
88 |
89 | print(batch)
90 | print(batch['input_ids'].shape)
91 | print(batch['attention_mask'].shape)
92 | print(batch['token_type_ids'].shape)
93 | print(batch['labels'].shape)
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/cache/logs/2022-04-09-20-42.log:
--------------------------------------------------------------------------------
1 | [2022-04-09 20:42:17,019][line: 219] ==> creating ./cache/logs/2022-04-09-20-42.log
2 | [2022-04-09 20:42:17,019][line: 52] ==> Train batch size = 64
3 | [2022-04-09 20:42:17,019][line: 53] ==> Total steps = 7500
4 | [2022-04-09 20:42:17,019][line: 54] ==> Training Start!
5 | [2022-04-09 20:44:43,498][line: 86] ==> ====Epoch:[1/10] avg_train_loss=0.89097====
6 | [2022-04-09 20:44:43,498][line: 87] ==> ====Training epoch took: 02:26====
7 | [2022-04-09 20:44:43,498][line: 88] ==> Running Validation...
8 | [2022-04-09 20:44:58,290][line: 93] ==> ====Epoch:[1/10] avg_val_loss=0.93396 avg_val_acc=0.71551====
9 | [2022-04-09 20:44:58,291][line: 94] ==> ====Validation epoch took: 02:41====
10 | [2022-04-09 20:44:58,291][line: 95] ==>
11 | [2022-04-09 20:47:23,092][line: 86] ==> ====Epoch:[2/10] avg_train_loss=0.43712====
12 | [2022-04-09 20:47:23,092][line: 87] ==> ====Training epoch took: 02:24====
13 | [2022-04-09 20:47:23,092][line: 88] ==> Running Validation...
14 | [2022-04-09 20:47:37,913][line: 93] ==> ====Epoch:[2/10] avg_val_loss=0.55599 avg_val_acc=0.86835====
15 | [2022-04-09 20:47:37,913][line: 94] ==> ====Validation epoch took: 02:39====
16 | [2022-04-09 20:47:37,913][line: 95] ==>
17 | [2022-04-09 20:50:04,162][line: 86] ==> ====Epoch:[3/10] avg_train_loss=0.27576====
18 | [2022-04-09 20:50:04,162][line: 87] ==> ====Training epoch took: 02:26====
19 | [2022-04-09 20:50:04,162][line: 88] ==> Running Validation...
20 | [2022-04-09 20:50:18,979][line: 93] ==> ====Epoch:[3/10] avg_val_loss=0.50120 avg_val_acc=0.89412====
21 | [2022-04-09 20:50:18,979][line: 94] ==> ====Validation epoch took: 02:41====
22 | [2022-04-09 20:50:18,979][line: 95] ==>
23 | [2022-04-09 20:52:43,696][line: 86] ==> ====Epoch:[4/10] avg_train_loss=0.22478====
24 | [2022-04-09 20:52:43,697][line: 87] ==> ====Training epoch took: 02:24====
25 | [2022-04-09 20:52:43,697][line: 88] ==> Running Validation...
26 | [2022-04-09 20:52:58,597][line: 93] ==> ====Epoch:[4/10] avg_val_loss=0.45129 avg_val_acc=0.91597====
27 | [2022-04-09 20:52:58,597][line: 94] ==> ====Validation epoch took: 02:39====
28 | [2022-04-09 20:52:58,597][line: 95] ==>
29 | [2022-04-09 20:55:23,741][line: 86] ==> ====Epoch:[5/10] avg_train_loss=0.18825====
30 | [2022-04-09 20:55:23,741][line: 87] ==> ====Training epoch took: 02:25====
31 | [2022-04-09 20:55:23,755][line: 88] ==> Running Validation...
32 | [2022-04-09 20:55:38,623][line: 93] ==> ====Epoch:[5/10] avg_val_loss=0.42481 avg_val_acc=0.92470====
33 | [2022-04-09 20:55:38,623][line: 94] ==> ====Validation epoch took: 02:40====
34 | [2022-04-09 20:55:38,623][line: 95] ==>
35 | [2022-04-09 20:58:03,976][line: 86] ==> ====Epoch:[6/10] avg_train_loss=0.16516====
36 | [2022-04-09 20:58:03,977][line: 87] ==> ====Training epoch took: 02:25====
37 | [2022-04-09 20:58:03,977][line: 88] ==> Running Validation...
38 | [2022-04-09 20:58:19,368][line: 93] ==> ====Epoch:[6/10] avg_val_loss=0.41008 avg_val_acc=0.92711====
39 | [2022-04-09 20:58:19,369][line: 94] ==> ====Validation epoch took: 02:40====
40 | [2022-04-09 20:58:19,369][line: 95] ==>
41 | [2022-04-09 21:00:43,387][line: 86] ==> ====Epoch:[7/10] avg_train_loss=0.14631====
42 | [2022-04-09 21:00:43,387][line: 87] ==> ====Training epoch took: 02:24====
43 | [2022-04-09 21:00:43,387][line: 88] ==> Running Validation...
44 | [2022-04-09 21:00:57,862][line: 93] ==> ====Epoch:[7/10] avg_val_loss=0.37470 avg_val_acc=0.93609====
45 | [2022-04-09 21:00:57,862][line: 94] ==> ====Validation epoch took: 02:38====
46 | [2022-04-09 21:00:57,862][line: 95] ==>
47 | [2022-04-09 21:03:20,793][line: 86] ==> ====Epoch:[8/10] avg_train_loss=0.12686====
48 | [2022-04-09 21:03:20,793][line: 87] ==> ====Training epoch took: 02:22====
49 | [2022-04-09 21:03:20,793][line: 88] ==> Running Validation...
50 | [2022-04-09 21:03:35,310][line: 93] ==> ====Epoch:[8/10] avg_val_loss=0.37030 avg_val_acc=0.93551====
51 | [2022-04-09 21:03:35,310][line: 94] ==> ====Validation epoch took: 02:37====
52 | [2022-04-09 21:03:35,310][line: 95] ==>
53 | [2022-04-09 21:06:03,032][line: 86] ==> ====Epoch:[9/10] avg_train_loss=0.12283====
54 | [2022-04-09 21:06:03,032][line: 87] ==> ====Training epoch took: 02:27====
55 | [2022-04-09 21:06:03,032][line: 88] ==> Running Validation...
56 | [2022-04-09 21:06:17,720][line: 93] ==> ====Epoch:[9/10] avg_val_loss=0.35997 avg_val_acc=0.93725====
57 | [2022-04-09 21:06:17,720][line: 94] ==> ====Validation epoch took: 02:42====
58 | [2022-04-09 21:06:17,720][line: 95] ==>
59 | [2022-04-09 21:08:43,587][line: 86] ==> ====Epoch:[10/10] avg_train_loss=0.12423====
60 | [2022-04-09 21:08:43,588][line: 87] ==> ====Training epoch took: 02:25====
61 | [2022-04-09 21:08:43,588][line: 88] ==> Running Validation...
62 | [2022-04-09 21:08:58,257][line: 93] ==> ====Epoch:[10/10] avg_val_loss=0.36056 avg_val_acc=0.94033====
63 | [2022-04-09 21:08:58,257][line: 94] ==> ====Validation epoch took: 02:40====
64 | [2022-04-09 21:08:58,257][line: 95] ==>
65 | [2022-04-09 21:08:58,634][line: 127] ==>
66 | [2022-04-09 21:08:58,634][line: 128] ==> Training Completed!
67 |
--------------------------------------------------------------------------------
/cache/logs/2022-04-09-23-54.log:
--------------------------------------------------------------------------------
1 | [2022-04-09 23:54:22,802][line: 225] ==> creating ./cache/logs/2022-04-09-23-54.log
2 | [2022-04-09 23:54:22,802][line: 54] ==> Train batch size = 64
3 | [2022-04-09 23:54:22,802][line: 55] ==> Total steps = 7500
4 | [2022-04-09 23:54:22,802][line: 56] ==> Training Start!
5 | [2022-04-09 23:56:49,171][line: 88] ==> ====Epoch:[1/10] avg_train_loss=0.79052====
6 | [2022-04-09 23:56:49,171][line: 89] ==> ====Training epoch took: 02:26====
7 | [2022-04-09 23:56:49,171][line: 90] ==> Running Validation...
8 | [2022-04-09 23:57:04,788][line: 95] ==> ====Epoch:[1/10] avg_val_loss=0.98110 avg_val_acc=0.70512====
9 | [2022-04-09 23:57:04,788][line: 96] ==> ====Validation epoch took: 02:41====
10 | [2022-04-09 23:57:04,788][line: 97] ==>
11 | [2022-04-09 23:59:29,837][line: 88] ==> ====Epoch:[2/10] avg_train_loss=0.37617====
12 | [2022-04-09 23:59:29,837][line: 89] ==> ====Training epoch took: 02:25====
13 | [2022-04-09 23:59:29,837][line: 90] ==> Running Validation...
14 | [2022-04-09 23:59:45,039][line: 95] ==> ====Epoch:[2/10] avg_val_loss=0.68817 avg_val_acc=0.83162====
15 | [2022-04-09 23:59:45,039][line: 96] ==> ====Validation epoch took: 02:40====
16 | [2022-04-09 23:59:45,039][line: 97] ==>
17 | [2022-04-10 00:02:08,939][line: 88] ==> ====Epoch:[3/10] avg_train_loss=0.26341====
18 | [2022-04-10 00:02:08,939][line: 89] ==> ====Training epoch took: 02:23====
19 | [2022-04-10 00:02:08,940][line: 90] ==> Running Validation...
20 | [2022-04-10 00:02:24,183][line: 95] ==> ====Epoch:[3/10] avg_val_loss=0.60514 avg_val_acc=0.87126====
21 | [2022-04-10 00:02:24,183][line: 96] ==> ====Validation epoch took: 02:39====
22 | [2022-04-10 00:02:24,183][line: 97] ==>
23 | [2022-04-10 00:04:48,402][line: 88] ==> ====Epoch:[4/10] avg_train_loss=0.21501====
24 | [2022-04-10 00:04:48,402][line: 89] ==> ====Training epoch took: 02:24====
25 | [2022-04-10 00:04:48,402][line: 90] ==> Running Validation...
26 | [2022-04-10 00:05:03,613][line: 95] ==> ====Epoch:[4/10] avg_val_loss=0.48300 avg_val_acc=0.90010====
27 | [2022-04-10 00:05:03,614][line: 96] ==> ====Validation epoch took: 02:39====
28 | [2022-04-10 00:05:03,614][line: 97] ==>
29 | [2022-04-10 00:07:27,687][line: 88] ==> ====Epoch:[5/10] avg_train_loss=0.17764====
30 | [2022-04-10 00:07:27,687][line: 89] ==> ====Training epoch took: 02:24====
31 | [2022-04-10 00:07:27,687][line: 90] ==> Running Validation...
32 | [2022-04-10 00:07:42,916][line: 95] ==> ====Epoch:[5/10] avg_val_loss=0.44431 avg_val_acc=0.91182====
33 | [2022-04-10 00:07:42,916][line: 96] ==> ====Validation epoch took: 02:39====
34 | [2022-04-10 00:07:42,916][line: 97] ==>
35 | [2022-04-10 00:10:09,527][line: 88] ==> ====Epoch:[6/10] avg_train_loss=0.16060====
36 | [2022-04-10 00:10:09,527][line: 89] ==> ====Training epoch took: 02:26====
37 | [2022-04-10 00:10:09,527][line: 90] ==> Running Validation...
38 | [2022-04-10 00:10:24,916][line: 95] ==> ====Epoch:[6/10] avg_val_loss=0.40690 avg_val_acc=0.92429====
39 | [2022-04-10 00:10:24,916][line: 96] ==> ====Validation epoch took: 02:42====
40 | [2022-04-10 00:10:24,916][line: 97] ==>
41 | [2022-04-10 00:12:50,498][line: 88] ==> ====Epoch:[7/10] avg_train_loss=0.13307====
42 | [2022-04-10 00:12:50,498][line: 89] ==> ====Training epoch took: 02:25====
43 | [2022-04-10 00:12:50,498][line: 90] ==> Running Validation...
44 | [2022-04-10 00:13:05,770][line: 95] ==> ====Epoch:[7/10] avg_val_loss=0.36382 avg_val_acc=0.93775====
45 | [2022-04-10 00:13:05,770][line: 96] ==> ====Validation epoch took: 02:40====
46 | [2022-04-10 00:13:05,770][line: 97] ==>
47 | [2022-04-10 00:15:29,989][line: 88] ==> ====Epoch:[8/10] avg_train_loss=0.11915====
48 | [2022-04-10 00:15:29,989][line: 89] ==> ====Training epoch took: 02:24====
49 | [2022-04-10 00:15:29,989][line: 90] ==> Running Validation...
50 | [2022-04-10 00:15:45,234][line: 95] ==> ====Epoch:[8/10] avg_val_loss=0.34609 avg_val_acc=0.94141====
51 | [2022-04-10 00:15:45,234][line: 96] ==> ====Validation epoch took: 02:39====
52 | [2022-04-10 00:15:45,234][line: 97] ==>
53 | [2022-04-10 00:18:10,119][line: 88] ==> ====Epoch:[9/10] avg_train_loss=0.10920====
54 | [2022-04-10 00:18:10,119][line: 89] ==> ====Training epoch took: 02:24====
55 | [2022-04-10 00:18:10,119][line: 90] ==> Running Validation...
56 | [2022-04-10 00:18:25,673][line: 95] ==> ====Epoch:[9/10] avg_val_loss=0.34493 avg_val_acc=0.94440====
57 | [2022-04-10 00:18:25,673][line: 96] ==> ====Validation epoch took: 02:40====
58 | [2022-04-10 00:18:25,673][line: 97] ==>
59 | [2022-04-10 00:21:08,030][line: 88] ==> ====Epoch:[10/10] avg_train_loss=0.10598====
60 | [2022-04-10 00:21:08,030][line: 89] ==> ====Training epoch took: 02:42====
61 | [2022-04-10 00:21:08,030][line: 90] ==> Running Validation...
62 | [2022-04-10 00:21:25,618][line: 95] ==> ====Epoch:[10/10] avg_val_loss=0.34799 avg_val_acc=0.94423====
63 | [2022-04-10 00:21:25,619][line: 96] ==> ====Validation epoch took: 02:59====
64 | [2022-04-10 00:21:25,619][line: 97] ==>
65 | [2022-04-10 00:21:25,876][line: 127] ==>
66 | [2022-04-10 00:21:25,876][line: 128] ==> Training Completed!
67 |
--------------------------------------------------------------------------------
/model.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # @Author : Ezreal
3 | # @File : predict.py
4 | # @Project: Douban_Bert
5 | # @CreateTime : 2022/3/13 上午12:08:22
6 | # @Version:V 0.1
7 | '''
8 | 模型训练和评估
9 | '''
10 | import numpy as np
11 | from torch import nn
12 | import time
13 | import os
14 | import torch
15 | import logging
16 | from torch.optim import AdamW
17 | from transformers import BertTokenizer,BertForSequenceClassification, get_linear_schedule_with_warmup
18 | from torch.utils.data import DataLoader
19 | from transformers.utils.notebook import format_time
20 | from data_process import InputDataSet,read_data
21 | import matplotlib.pyplot as plt
22 |
23 |
24 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
25 |
26 | def train(batch_size,EPOCHS):
27 | # model = BertForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=5)使用bert-base-chinese预训练模型
28 |
29 | model = BertForSequenceClassification.from_pretrained("hfl/chinese-bert-wwm", num_labels=5)#使用chinese-bert-wwm预训练模型
30 |
31 | # model = BertForSequenceClassification.from_pretrained("hfl/chinese-roberta-wwm-ext", num_labels=5)#使用hfl/chinese-roberta-wwm-ext预训练模型
32 |
33 | train = read_data('data/train.csv')
34 | val = read_data('data/test.csv')
35 | # tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
36 | tokenizer = BertTokenizer.from_pretrained('chinese-bert-wwm')
37 |
38 | train_dataset = InputDataSet(train, tokenizer, 64)
39 | val_dataset = InputDataSet(val, tokenizer, 64)
40 |
41 | train_dataloader = DataLoader(train_dataset,batch_size)
42 | val_dataloader = DataLoader(val_dataset,batch_size)
43 |
44 | optimizer = AdamW(model.parameters(), lr=2e-5)
45 |
46 | total_steps = len(train_dataloader) * EPOCHS # len(dataset)*epochs / batchsize
47 | scheduler = get_linear_schedule_with_warmup(optimizer,
48 | num_warmup_steps=0,
49 | num_training_steps=total_steps)
50 | total_t0 = time.time()
51 |
52 | log = log_creater(output_dir='./cache/logs/')
53 |
54 | log.info(" Train batch size = {}".format(batch_size))
55 | log.info(" Total steps = {}".format(total_steps))
56 | log.info(" Training Start!")
57 |
58 | train_loss = []
59 | test_loss = []
60 | test_acc = []
61 |
62 |
63 | for epoch in range(EPOCHS):
64 | total_train_loss = 0
65 | t0 = time.time()
66 | model.to(device)
67 | model.train()
68 | for step, batch in enumerate(train_dataloader):
69 |
70 | input_ids = batch['input_ids'].to(device)
71 | attention_mask = batch['attention_mask'].to(device)
72 | token_type_ids = batch['token_type_ids'].to(device)
73 | labels = batch['labels'].to(device)
74 | model.zero_grad()
75 |
76 | outputs = model(input_ids,attention_mask=attention_mask,token_type_ids=token_type_ids,labels=labels)
77 |
78 | loss = outputs.loss
79 | total_train_loss += loss.item()
80 |
81 | loss.backward()
82 | nn.utils.clip_grad_norm_(model.parameters(), 1.0)
83 | optimizer.step()
84 | scheduler.step()
85 | avg_train_loss = total_train_loss / len(train_dataloader)
86 | train_time = format_time(time.time() - t0)
87 |
88 | log.info('====Epoch:[{}/{}] avg_train_loss={:.5f}===='.format(epoch+1,EPOCHS,avg_train_loss))
89 | log.info('====Training epoch took: {:}===='.format(train_time))
90 | log.info('Running Validation...')
91 |
92 | model.eval()#这里调用了eval方法
93 | avg_val_loss, avg_val_acc = evaluate(model, val_dataloader)
94 | val_time = format_time(time.time() - t0)
95 | log.info('====Epoch:[{}/{}] avg_val_loss={:.5f} avg_val_acc={:.5f}===='.format(epoch+1,EPOCHS,avg_val_loss,avg_val_acc))
96 | log.info('====Validation epoch took: {:}===='.format(val_time))
97 | log.info('')
98 |
99 | if epoch == EPOCHS-1:#保存模型
100 |
101 | output_dir = "./cache/"#定义保存路径
102 | '''
103 | 第一种保存方法,不推荐这样写
104 | '''
105 | # model_to_save = model.module if hasattr(model, 'module') else model
106 | # # 如果使用预定义的名称保存,则可以使用`from_pretrained`加载
107 | # output_model_file = os.path.join(output_dir, WEIGHTS_NAME)
108 | # output_config_file = os.path.join(output_dir, CONFIG_NAME)
109 | #
110 | # torch.save(model_to_save.state_dict(), output_model_file)
111 | # model_to_save.config.to_json_file(output_config_file)
112 | # tokenizer.save_vocabulary(output_dir)
113 |
114 |
115 | model_to_save = model.module if hasattr(model, 'module') else model
116 | model_to_save.save_pretrained('cache')
117 | print('Model Saved!')
118 |
119 |
120 | #将数据保存到列表
121 | train_loss.append(avg_train_loss)
122 | test_loss.append(avg_val_loss)
123 | test_acc.append(avg_val_acc)
124 |
125 |
126 |
127 | log.info('')
128 | log.info(' Training Completed!')
129 | print('Total training took {:} (h:mm:ss)'.format(format_time(time.time() - total_t0)))
130 | #简单可视化
131 | x1 = range(0,EPOCHS)
132 | y1 = train_loss
133 | plt.plot(x1, y1)
134 | plt.title("train loss of chinese-bert-wwm")
135 | plt.xlabel("epoches")
136 | plt.ylabel("train loss")
137 | plt.savefig('./cache/wwm_1.png')
138 | plt.close()
139 | # plt.show()
140 |
141 | x2 = range(0,EPOCHS)
142 | y2 = test_loss
143 | plt.plot(x2, y2)
144 | plt.title("test loss of chinese-bert-wwm")
145 | plt.xlabel("epoches")
146 | plt.ylabel("test loss")
147 | plt.savefig('./cache/wwm_2.png')
148 | plt.close()
149 | # plt.show()
150 |
151 | x3 = range(0,EPOCHS)
152 | y3 = test_acc
153 | plt.plot(x3, y3)
154 | plt.title("test acc of chinese-bert-wwm")
155 | plt.xlabel("epoches")
156 | plt.ylabel("test acc")
157 | plt.savefig('./cache/wwm_3.png')
158 | plt.close()
159 | # plt.show()
160 |
161 |
162 |
163 |
164 |
165 |
166 | def evaluate(model,val_dataloader):
167 | total_val_loss = 0
168 | corrects = []
169 | for batch in val_dataloader:
170 | input_ids = batch['input_ids'].to(device)
171 | attention_mask = batch['attention_mask'].to(device)
172 | token_type_ids = batch['token_type_ids'].to(device)
173 | labels = batch['labels'].to(device)
174 |
175 | with torch.no_grad():
176 | outputs = model(input_ids,attention_mask=attention_mask,token_type_ids=token_type_ids,labels=labels)
177 |
178 | logits = torch.argmax(outputs.logits,dim=1)
179 | ## 把每个batch预测的准确率加入到一个list中
180 | ## 在加入之前,preds和labels变成cpu的格式
181 | preds = logits.detach().cpu().numpy()
182 | labels_ids = labels.to('cpu').numpy()
183 | corrects.append((preds == labels_ids).mean()) ## [0.8,0.7,0.9]
184 | ## 返回loss
185 | loss = outputs.loss
186 | ## 把每个batch的loss加入 total_val_loss
187 | ## 总共有len(val_dataloader)个batch
188 | total_val_loss += loss.item()
189 |
190 | avg_val_loss = total_val_loss / len(val_dataloader)
191 | avg_val_acc = np.mean(corrects)
192 |
193 | return avg_val_loss, avg_val_acc
194 |
195 | #训练日志,复用性很高的代码
196 | def log_creater(output_dir):
197 | if not os.path.exists(output_dir):
198 | os.makedirs(output_dir)
199 | log_name = '{}.log'.format(time.strftime('%Y-%m-%d-%H-%M'))
200 | final_log_file = os.path.join(output_dir, log_name)
201 | # creat a log
202 | log = logging.getLogger('train_log')
203 | log.setLevel(logging.DEBUG)
204 |
205 | # FileHandler
206 | file = logging.FileHandler(final_log_file)
207 | file.setLevel(logging.DEBUG)
208 |
209 | # StreamHandler
210 | stream = logging.StreamHandler()
211 | stream.setLevel(logging.DEBUG)
212 |
213 | # Formatter
214 | formatter = logging.Formatter(
215 | '[%(asctime)s][line: %(lineno)d] ==> %(message)s')
216 |
217 | # setFormatter
218 | file.setFormatter(formatter)
219 | stream.setFormatter(formatter)
220 |
221 | # addHandler
222 | log.addHandler(file)
223 | log.addHandler(stream)
224 |
225 | log.info('creating {}'.format(final_log_file))
226 | return log
227 |
228 |
229 | if __name__ == '__main__':
230 | train(batch_size=64,EPOCHS=10)
231 |
--------------------------------------------------------------------------------
/static/Home.css:
--------------------------------------------------------------------------------
1 | .u-section-1 {
2 | background-image: none;
3 | }
4 |
5 | .u-section-1 .u-sheet-1 {
6 | min-height: 624px;
7 | }
8 |
9 | .u-section-1 .u-text-1 {
10 | font-size: 2.25rem;
11 | margin: 60px auto 0 20px;
12 | }
13 |
14 | .u-section-1 .u-layout-wrap-1 {
15 | margin-top: 25px;
16 | margin-bottom: 0;
17 | }
18 |
19 | .u-section-1 .u-layout-cell-1 {
20 | min-height: 99px;
21 | }
22 |
23 | .u-section-1 .u-container-layout-1 {
24 | padding: 20px 15px;
25 | }
26 |
27 | .u-section-1 .u-form-1 {
28 | height: 47px;
29 | margin: 0 25px 0 5px;
30 | }
31 |
32 | .u-section-1 .u-layout-cell-2 {
33 | min-height: 99px;
34 | background-image: none;
35 | --animation-custom_in-translate_x: 300px;
36 | --animation-custom_in-translate_y: 0px;
37 | --animation-custom_in-opacity: 0;
38 | --animation-custom_in-rotate: 0deg;
39 | --animation-custom_in-scale: 1;
40 | }
41 |
42 | .u-section-1 .u-container-layout-2 {
43 | padding: 27px 30px;
44 | }
45 |
46 | .u-section-1 .u-social-icons-1 {
47 | height: 45px;
48 | min-height: 16px;
49 | width: 210px;
50 | min-width: 94px;
51 | margin: 0 auto;
52 | }
53 |
54 | .u-section-1 .u-icon-1 {
55 | height: 100%;
56 | }
57 |
58 | .u-section-1 .u-icon-2 {
59 | height: 100%;
60 | }
61 |
62 | .u-section-1 .u-icon-3 {
63 | height: 100%;
64 | }
65 |
66 | .u-section-1 .u-icon-4 {
67 | height: 0;
68 | }
69 |
70 | .u-section-1 .u-text-2 {
71 | font-size: 0.875rem;
72 | margin: 52px 750px 0 25px;
73 | }
74 |
75 | .u-section-1 .u-image-1 {
76 | width: 100px;
77 | height: 99px;
78 | background-image: url("images/cebeb11125c6c963b6a04fc48f61182.jpg");
79 | background-position: 50% 50%;
80 | margin: 100px 979px 0 61px;
81 | }
82 |
83 | .u-section-1 .u-text-3 {
84 | font-weight: 700;
85 | margin: -70px auto 60px 199px;
86 | }
87 |
88 | @media (max-width: 1199px) {
89 | .u-section-1 .u-sheet-1 {
90 | min-height: 607px;
91 | }
92 |
93 | .u-section-1 .u-text-1 {
94 | font-weight: normal;
95 | }
96 |
97 | .u-section-1 .u-layout-cell-1 {
98 | min-height: 82px;
99 | }
100 |
101 | .u-section-1 .u-form-1 {
102 | margin-right: 0;
103 | margin-left: 0;
104 | }
105 |
106 | .u-section-1 .u-layout-cell-2 {
107 | min-height: 82px;
108 | }
109 |
110 | .u-section-1 .u-text-2 {
111 | margin-right: 575px;
112 | margin-left: 0;
113 | }
114 |
115 | .u-section-1 .u-image-1 {
116 | width: 99px;
117 | margin-right: 840px;
118 | margin-left: 0;
119 | }
120 | }
121 |
122 | @media (max-width: 991px) {
123 | .u-section-1 .u-sheet-1 {
124 | min-height: 625px;
125 | }
126 |
127 | .u-section-1 .u-layout-cell-1 {
128 | min-height: 100px;
129 | }
130 |
131 | .u-section-1 .u-layout-cell-2 {
132 | min-height: 63px;
133 | }
134 |
135 | .u-section-1 .u-text-2 {
136 | margin-right: 355px;
137 | }
138 |
139 | .u-section-1 .u-image-1 {
140 | margin-right: 620px;
141 | }
142 | }
143 |
144 | @media (max-width: 767px) {
145 | .u-section-1 .u-sheet-1 {
146 | min-height: 748px;
147 | }
148 |
149 | .u-section-1 .u-container-layout-1 {
150 | padding-left: 10px;
151 | padding-right: 10px;
152 | }
153 |
154 | .u-section-1 .u-layout-cell-2 {
155 | min-height: 123px;
156 | }
157 |
158 | .u-section-1 .u-container-layout-2 {
159 | padding-left: 10px;
160 | padding-right: 10px;
161 | }
162 |
163 | .u-section-1 .u-text-2 {
164 | margin-right: 175px;
165 | }
166 |
167 | .u-section-1 .u-image-1 {
168 | margin-right: 440px;
169 | }
170 |
171 | .u-section-1 .u-text-3 {
172 | margin-left: 149px;
173 | }
174 | }
175 |
176 | @media (max-width: 575px) {
177 | .u-section-1 .u-sheet-1 {
178 | min-height: 702px;
179 | }
180 |
181 | .u-section-1 .u-layout-cell-2 {
182 | min-height: 77px;
183 | }
184 |
185 | .u-section-1 .u-text-2 {
186 | margin-right: 0;
187 | }
188 |
189 | .u-section-1 .u-image-1 {
190 | margin-right: 240px;
191 | }
192 |
193 | .u-section-1 .u-text-3 {
194 | margin-left: 94px;
195 | }
196 | } .u-section-2 {
197 | min-height: 708px;
198 | }
199 |
200 | .u-section-2 .u-layout-wrap-1 {
201 | margin-top: 0;
202 | margin-bottom: 0;
203 | }
204 |
205 | .u-section-2 .u-layout-cell-1 {
206 | min-height: 708px;
207 | background-image: none;
208 | }
209 |
210 | .u-section-2 .u-container-layout-1 {
211 | padding: 30px 0;
212 | }
213 |
214 | .u-section-2 .u-layout-cell-2 {
215 | min-height: 708px;
216 | background-image: none;
217 | }
218 |
219 | .u-section-2 .u-container-layout-2 {
220 | padding: 30px 0;
221 | }
222 |
223 | .u-section-2 .u-group-1 {
224 | width: 472px;
225 | min-height: 613px;
226 | margin: 22px auto 0 -236px;
227 | }
228 |
229 | .u-section-2 .u-container-layout-3 {
230 | padding-bottom: 30px;
231 | }
232 |
233 | .u-section-2 .u-text-1 {
234 | text-transform: uppercase;
235 | font-size: 6rem;
236 | font-weight: 700;
237 | letter-spacing: 2px;
238 | margin: 106px 0 0;
239 | }
240 |
241 | .u-section-2 .u-image-1 {
242 | min-height: 708px;
243 | background-image: url("images/7c62f9fc1b977eee788f421e5145fa7.jpg");
244 | background-position: 50% 50%;
245 | --animation-custom_in-translate_x: 300px;
246 | --animation-custom_in-translate_y: 0px;
247 | --animation-custom_in-opacity: 0;
248 | --animation-custom_in-rotate: 0deg;
249 | --animation-custom_in-scale: 1;
250 | }
251 |
252 | .u-section-2 .u-container-layout-4 {
253 | padding: 30px;
254 | }
255 |
256 | @media (max-width: 1199px) {
257 | .u-section-2 {
258 | min-height: 705px;
259 | }
260 |
261 | .u-section-2 .u-layout-cell-1 {
262 | min-height: 705px;
263 | }
264 |
265 | .u-section-2 .u-layout-cell-2 {
266 | min-height: 705px;
267 | }
268 |
269 | .u-section-2 .u-group-1 {
270 | width: 469px;
271 | min-height: 623px;
272 | margin-left: -265px;
273 | }
274 |
275 | .u-section-2 .u-image-1 {
276 | min-height: 705px;
277 | }
278 | }
279 |
280 | @media (max-width: 991px) {
281 | .u-section-2 {
282 | min-height: 644px;
283 | }
284 |
285 | .u-section-2 .u-layout-cell-1 {
286 | min-height: 644px;
287 | }
288 |
289 | .u-section-2 .u-layout-cell-2 {
290 | min-height: 644px;
291 | }
292 |
293 | .u-section-2 .u-group-1 {
294 | width: 381px;
295 | min-height: 560px;
296 | margin-left: -225px;
297 | }
298 |
299 | .u-section-2 .u-container-layout-3 {
300 | padding-bottom: 20px;
301 | }
302 |
303 | .u-section-2 .u-text-1 {
304 | font-size: 4.5rem;
305 | width: auto;
306 | }
307 |
308 | .u-section-2 .u-image-1 {
309 | min-height: 644px;
310 | }
311 | }
312 |
313 | @media (max-width: 767px) {
314 | .u-section-2 {
315 | min-height: 1872px;
316 | }
317 |
318 | .u-section-2 .u-layout-cell-1 {
319 | min-height: 180px;
320 | }
321 |
322 | .u-section-2 .u-layout-cell-2 {
323 | min-height: 478px;
324 | }
325 |
326 | .u-section-2 .u-container-layout-2 {
327 | padding-top: 0;
328 | padding-bottom: 0;
329 | }
330 |
331 | .u-section-2 .u-group-1 {
332 | width: 554px;
333 | margin-top: -60px;
334 | margin-left: auto;
335 | }
336 |
337 | .u-section-2 .u-image-1 {
338 | min-height: 1073px;
339 | }
340 |
341 | .u-section-2 .u-container-layout-4 {
342 | padding-left: 10px;
343 | padding-right: 10px;
344 | }
345 | }
346 |
347 | @media (max-width: 575px) {
348 | .u-section-2 {
349 | min-height: 1223px;
350 | }
351 |
352 | .u-section-2 .u-layout-cell-1 {
353 | min-height: 113px;
354 | }
355 |
356 | .u-section-2 .u-layout-cell-2 {
357 | min-height: 500px;
358 | }
359 |
360 | .u-section-2 .u-group-1 {
361 | width: 340px;
362 | }
363 |
364 | .u-section-2 .u-image-1 {
365 | min-height: 676px;
366 | }
367 | }.u-section-3 .u-sheet-1 {
368 | min-height: 667px;
369 | }
370 |
371 | .u-section-3 .u-layout-wrap-1 {
372 | margin-top: 60px;
373 | margin-bottom: -20px;
374 | }
375 |
376 | .u-section-3 .u-layout-cell-1 {
377 | min-height: 467px;
378 | background-image: none;
379 | }
380 |
381 | .u-section-3 .u-container-layout-1 {
382 | padding: 0 27px 30px;
383 | }
384 |
385 | .u-section-3 .u-image-1 {
386 | width: 213px;
387 | height: 213px;
388 | background-image: url("images/cebeb11125c6c963b6a04fc48f61182-4.jpg");
389 | background-position: 50% 50%;
390 | margin: -95px auto 0;
391 | }
392 |
393 | .u-section-3 .u-text-1 {
394 | font-size: 1.875rem;
395 | text-transform: uppercase;
396 | font-weight: 700;
397 | font-family: Georgia, serif;
398 | margin: 24px auto 0;
399 | }
400 |
401 | .u-section-3 .u-social-icons-1 {
402 | height: 46px;
403 | min-height: 16px;
404 | width: 220px;
405 | min-width: 100px;
406 | margin: 58px auto 0;
407 | }
408 |
409 | .u-section-3 .u-icon-3 {
410 | height: 100%;
411 | }
412 |
413 | .u-section-3 .u-icon-4 {
414 | height: 0;
415 | }
416 |
417 | .u-section-3 .u-layout-cell-2 {
418 | min-height: 467px;
419 | --animation-custom_in-translate_x: 300px;
420 | --animation-custom_in-translate_y: 0px;
421 | --animation-custom_in-opacity: 0;
422 | --animation-custom_in-rotate: 0deg;
423 | --animation-custom_in-scale: 1;
424 | }
425 |
426 | .u-section-3 .u-container-layout-2 {
427 | padding: 30px 60px;
428 | }
429 |
430 | .u-section-3 .u-text-2 {
431 | font-size: 6rem;
432 | font-weight: 700;
433 | text-transform: uppercase;
434 | margin: 1px auto 0 0;
435 | }
436 |
437 | .u-section-3 .u-text-3 {
438 | margin-top: 19px;
439 | font-size: 1rem;
440 | margin-bottom: 0;
441 | }
442 |
443 | .u-section-3 .u-btn-1 {
444 | border-style: solid;
445 | font-weight: 700;
446 | text-transform: uppercase;
447 | font-size: 1rem;
448 | letter-spacing: 1px;
449 | margin: 58px auto 0 0;
450 | padding: 18px 46px 20px 45px;
451 | }
452 |
453 | @media (max-width: 1199px) {
454 | .u-section-3 .u-sheet-1 {
455 | min-height: 744px;
456 | }
457 |
458 | .u-section-3 .u-layout-wrap-1 {
459 | margin-top: 152px;
460 | margin-bottom: 0;
461 | }
462 |
463 | .u-section-3 .u-layout-cell-1 {
464 | min-height: 385px;
465 | }
466 |
467 | .u-section-3 .u-layout-cell-2 {
468 | min-height: 385px;
469 | }
470 | }
471 |
472 | @media (max-width: 991px) {
473 | .u-section-3 .u-sheet-1 {
474 | min-height: 352px;
475 | }
476 |
477 | .u-section-3 .u-layout-cell-1 {
478 | min-height: 100px;
479 | }
480 |
481 | .u-section-3 .u-layout-cell-2 {
482 | min-height: 100px;
483 | }
484 |
485 | .u-section-3 .u-container-layout-2 {
486 | padding-left: 30px;
487 | padding-right: 30px;
488 | }
489 |
490 | .u-section-3 .u-text-2 {
491 | font-size: 4.5rem;
492 | }
493 | }
494 |
495 | @media (max-width: 767px) {
496 | .u-section-3 .u-sheet-1 {
497 | min-height: 452px;
498 | }
499 |
500 | .u-section-3 .u-container-layout-1 {
501 | padding-left: 10px;
502 | padding-right: 10px;
503 | }
504 |
505 | .u-section-3 .u-container-layout-2 {
506 | padding-left: 10px;
507 | padding-right: 10px;
508 | }
509 | }
510 |
511 | @media (max-width: 575px) {
512 | .u-section-3 .u-text-1 {
513 | font-size: 1.5rem;
514 | }
515 | } .u-section-4 {
516 | background-image: none;
517 | }
518 |
519 | .u-section-4 .u-sheet-1 {
520 | min-height: 812px;
521 | }
522 |
523 | .u-section-4 .u-layout-wrap-1 {
524 | margin-top: 60px;
525 | margin-bottom: 60px;
526 | }
527 |
528 | .u-section-4 .u-image-1 {
529 | min-height: 355px;
530 | background-image: url("images/c2054c88b61683933031860d6838197.jpg");
531 | background-position: 50% 0%;
532 | }
533 |
534 | .u-section-4 .u-container-layout-1 {
535 | padding: 30px;
536 | }
537 |
538 | .u-section-4 .u-image-2 {
539 | min-height: 355px;
540 | background-image: url("images/231156ce864cdf68ce8ec4da608f6c5.jpg");
541 | background-position: 50% 50%;
542 | }
543 |
544 | .u-section-4 .u-container-layout-2 {
545 | padding: 0;
546 | }
547 |
548 | .u-section-4 .u-image-3 {
549 | min-height: 329px;
550 | background-image: url("images/595d7f60e388652232aeda9a3f4f096.jpg");
551 | background-position: 50% 21.47%;
552 | }
553 |
554 | .u-section-4 .u-container-layout-3 {
555 | padding: 0;
556 | }
557 |
558 | .u-section-4 .u-image-4 {
559 | min-height: 241px;
560 | background-image: url("images/57cd2966e2199a959f6b956d2741ce4.jpg");
561 | background-position: 50% 0%;
562 | }
563 |
564 | .u-section-4 .u-container-layout-4 {
565 | padding: 30px;
566 | }
567 |
568 | .u-section-4 .u-layout-cell-5 {
569 | min-height: 241px;
570 | }
571 |
572 | .u-section-4 .u-container-layout-5 {
573 | padding: 30px;
574 | }
575 |
576 | .u-section-4 .u-text-1 {
577 | font-size: 2.25rem;
578 | margin: 0 auto 0 0;
579 | }
580 |
581 | .u-section-4 .u-image-5 {
582 | min-height: 481px;
583 | background-image: url("images/e8be7a6fb5c361ddba9dfcf8bbb8116.jpg");
584 | background-position: 50% 50%;
585 | --animation-custom_in-translate_x: 300px;
586 | --animation-custom_in-translate_y: 0px;
587 | --animation-custom_in-opacity: 0;
588 | --animation-custom_in-rotate: 0deg;
589 | --animation-custom_in-scale: 1;
590 | }
591 |
592 | .u-section-4 .u-container-layout-6 {
593 | padding: 30px;
594 | }
595 |
596 | @media (max-width: 1199px) {
597 | .u-section-4 .u-sheet-1 {
598 | min-height: 691px;
599 | }
600 |
601 | .u-section-4 .u-image-1 {
602 | min-height: 293px;
603 | }
604 |
605 | .u-section-4 .u-image-2 {
606 | min-height: 325px;
607 | }
608 |
609 | .u-section-4 .u-image-3 {
610 | min-height: 271px;
611 | }
612 |
613 | .u-section-4 .u-image-4 {
614 | min-height: 199px;
615 | }
616 |
617 | .u-section-4 .u-layout-cell-5 {
618 | min-height: 199px;
619 | }
620 |
621 | .u-section-4 .u-text-1 {
622 | font-weight: normal;
623 | text-transform: none;
624 | }
625 |
626 | .u-section-4 .u-image-5 {
627 | min-height: 397px;
628 | }
629 | }
630 |
631 | @media (max-width: 991px) {
632 | .u-section-4 .u-sheet-1 {
633 | min-height: 1578px;
634 | }
635 |
636 | .u-section-4 .u-image-1 {
637 | min-height: 224px;
638 | }
639 |
640 | .u-section-4 .u-image-2 {
641 | min-height: 249px;
642 | }
643 |
644 | .u-section-4 .u-image-3 {
645 | min-height: 311px;
646 | }
647 |
648 | .u-section-4 .u-image-4 {
649 | min-height: 229px;
650 | }
651 |
652 | .u-section-4 .u-layout-cell-5 {
653 | min-height: 100px;
654 | }
655 |
656 | .u-section-4 .u-image-5 {
657 | min-height: 912px;
658 | }
659 | }
660 |
661 | @media (max-width: 767px) {
662 | .u-section-4 .u-sheet-1 {
663 | min-height: 2090px;
664 | }
665 |
666 | .u-section-4 .u-image-1 {
667 | min-height: 504px;
668 | }
669 |
670 | .u-section-4 .u-container-layout-1 {
671 | padding-left: 10px;
672 | padding-right: 10px;
673 | }
674 |
675 | .u-section-4 .u-image-2 {
676 | min-height: 280px;
677 | }
678 |
679 | .u-section-4 .u-image-3 {
680 | min-height: 467px;
681 | }
682 |
683 | .u-section-4 .u-image-4 {
684 | min-height: 344px;
685 | }
686 |
687 | .u-section-4 .u-container-layout-4 {
688 | padding-left: 10px;
689 | padding-right: 10px;
690 | }
691 |
692 | .u-section-4 .u-container-layout-5 {
693 | padding-left: 10px;
694 | padding-right: 10px;
695 | }
696 |
697 | .u-section-4 .u-image-5 {
698 | min-height: 684px;
699 | }
700 |
701 | .u-section-4 .u-container-layout-6 {
702 | padding-left: 10px;
703 | padding-right: 10px;
704 | }
705 | }
706 |
707 | @media (max-width: 575px) {
708 | .u-section-4 .u-sheet-1 {
709 | min-height: 1359px;
710 | }
711 |
712 | .u-section-4 .u-image-1 {
713 | min-height: 317px;
714 | }
715 |
716 | .u-section-4 .u-image-2 {
717 | min-height: 190px;
718 | }
719 |
720 | .u-section-4 .u-image-3 {
721 | min-height: 294px;
722 | }
723 |
724 | .u-section-4 .u-image-4 {
725 | min-height: 217px;
726 | }
727 |
728 | .u-section-4 .u-image-5 {
729 | min-height: 431px;
730 | }
731 | }
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Home
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
60 |
61 |
62 |
豆瓣影评情感分析系统
63 |
109 |
本系统基于pytorch框架和bert-base-Chinese预训练模型。
数据集来自于“豆瓣2021年度热门电影”。
输入您的影评,然后可以得到一个预测的情感标签。
110 |
111 |
112 |
Designed by Ezreal Jing
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
Ezreal Jing
127 |
128 |
129 |
130 |
131 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Hello, I'm Ezreal
147 |
164 |
165 |
166 |
167 |
168 |
About Me
169 |
本人是数字媒体技术专业毕业生,热爱探索、钻研新技术,热衷于技术分享。对待岗位踏实认真,善于与他人沟通充满激情、勇于挑战自我,具有创新精神,善于总结经验,团队荣誉感强。
170 | 两年的军旅生涯中在磨砺中成长,培育了较强的与他人协作能力,锻炼了良好的身体素质,塑造了吃苦耐劳、坚持不懈、不畏困难的良好品格以及追求卓越、勇攀高峰的坚定理想。
171 |
Contact Me
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
194 |
195 |
196 |
197 |
198 |
208 |
209 |
210 |
211 |
212 |
数据集来自“豆瓣2021年度热门电影”
213 |
214 |
215 |
216 |
217 |
218 |
219 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/static/Home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Home
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
60 |
61 |
62 |
豆瓣影评情感分析系统
63 |
109 |
本系统基于pytorch框架和bert-base-Chinese预训练模型。
数据集来自于“豆瓣2021年度热门电影”。
输入您的影评,然后可以得到一个预测的情感标签。
110 |
111 |
112 |
Designed by Ezreal Jing
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
Ezreal Jing
127 |
128 |
129 |
130 |
131 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Hello, I'm Ezreal
147 |
164 |
165 |
166 |
167 |
168 |
About Me
169 |
本人是数字媒体技术专业毕业生,热爱探索、钻研新技术,热衷于技术分享。对待岗位踏实认真,善于与他人沟通充满激情、勇于挑战自我,具有创新精神,善于总结经验,团队荣誉感强。
170 | 两年的军旅生涯中在磨砺中成长,培育了较强的与他人协作能力,锻炼了良好的身体素质,塑造了吃苦耐劳、坚持不懈、不畏困难的良好品格以及追求卓越、勇攀高峰的坚定理想。
171 |
Contact Me
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
194 |
195 |
196 |
197 |
198 |
208 |
209 |
210 |
211 |
212 |
数据集来自“豆瓣2021年度热门电影”
213 |
214 |
215 |
216 |
217 |
218 |
219 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
238 |
249 |
250 |
--------------------------------------------------------------------------------
/templates/Home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Home
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
60 |
61 |
62 |
豆瓣影评情感分析系统
63 |
109 |
本系统基于pytorch框架和bert-base-Chinese预训练模型。
数据集来自于“豆瓣2021年度热门电影”。
输入您的影评,然后可以得到一个预测的情感标签。
110 |
111 |
112 |
Designed by Ezreal Jing
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
Ezreal Jing
127 |
128 |
129 |
130 |
131 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Hello, I'm Ezreal
147 |
164 |
165 |
166 |
167 |
168 |
About Me
169 |
本人是数字媒体技术专业毕业生,热爱探索、钻研新技术,热衷于技术分享。对待岗位踏实认真,善于与他人沟通充满激情、勇于挑战自我,具有创新精神,善于总结经验,团队荣誉感强。
170 | 两年的军旅生涯中在磨砺中成长,培育了较强的与他人协作能力,锻炼了良好的身体素质,塑造了吃苦耐劳、坚持不懈、不畏困难的良好品格以及追求卓越、勇攀高峰的坚定理想。
171 |
Contact Me
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
194 |
195 |
196 |
197 |
198 |
208 |
209 |
210 |
211 |
212 |
数据集来自“豆瓣2021年度热门电影”
213 |
214 |
215 |
216 |
217 |
218 |
219 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
238 |
249 |
250 |
--------------------------------------------------------------------------------
/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Home
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
60 |
61 |
62 |
豆瓣影评情感分析系统
63 |
109 |
本系统基于pytorch框架和bert-base-Chinese预训练模型。
数据集来自于“豆瓣2021年度热门电影”。
输入您的影评,然后可以得到一个预测的情感标签。
110 |
111 |
112 |
Designed by Ezreal Jing
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
Ezreal Jing
127 |
128 |
129 |
130 |
131 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
Hello, I'm Ezreal
147 |
164 |
165 |
166 |
167 |
168 |
About Me
169 |
本人是数字媒体技术专业毕业生,热爱探索、钻研新技术,热衷于技术分享。对待岗位踏实认真,善于与他人沟通充满激情、勇于挑战自我,具有创新精神,善于总结经验,团队荣誉感强。
170 | 两年的军旅生涯中在磨砺中成长,培育了较强的与他人协作能力,锻炼了良好的身体素质,塑造了吃苦耐劳、坚持不懈、不畏困难的良好品格以及追求卓越、勇攀高峰的坚定理想。
171 |
Contact Me
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
194 |
195 |
196 |
197 |
198 |
208 |
209 |
210 |
211 |
212 |
数据集来自“豆瓣2021年度热门电影”
213 |
214 |
215 |
216 |
217 |
218 |
219 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
238 |
249 |
250 |
--------------------------------------------------------------------------------
/static/jquery.js:
--------------------------------------------------------------------------------
1 | /*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
2 | !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0