Skip to content

Commit 6dd2074

Browse files
author
zida
committed
Update README.md
1 parent 7e3c619 commit 6dd2074

File tree

1 file changed

+51
-30
lines changed

1 file changed

+51
-30
lines changed

README.md

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ Bert在生产环境的应用需要进行压缩,这就要求对Bert结构很了
1010

1111
运行之前,需要做两个事情。
1212

13-
1. 一个是预训练模型的准备,我使用的是谷歌的中文预训练模型:chinese_L-12_H-768_A-12.zip,模型有点大,我就不上传了,如果本地不存在,就点击[这里](https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip),或者直接命令行运行
13+
#### 准备预训练模型
14+
15+
一个是预训练模型的准备,我使用的是谷歌的中文预训练模型:chinese_L-12_H-768_A-12.zip,模型有点大,我就不上传了,如果本地不存在,就点击[这里](https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip)直接下载,或者直接命令行运行
1416

1517
```shell
1618
wget https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
@@ -33,27 +35,34 @@ python convert_tf_checkpoint_to_pytorch.py \
3335
Read_Bert_Code/bert_read_step_to_step/prev_trained_model/
3436
```
3537

36-
并该名称为 $bert-base-chinese$
38+
并重新命名为:
39+
40+
```shell
41+
bert-base-chinese
42+
```
43+
44+
#### 准备文本分类训练数据
3745

38-
2. 第二个事情就是准备训练数据,这里我准备做一个文本分类任务,使用的是Tnews数据集,这个数据集来源是[这里](https://github.com/ChineseGLUE/ChineseGLUE/tree/master/baselines/models_pytorch/classifier_pytorch/chineseGLUEdatasets),分为训练,测试和开发集,我已经上传到了仓库中,具体位置在
46+
第二个事情就是准备训练数据,这里我准备做一个文本分类任务,使用的是Tnews数据集,这个数据集来源是[这里](https://github.com/ChineseGLUE/ChineseGLUE/tree/master/baselines/models_pytorch/classifier_pytorch/chineseGLUEdatasets),分为训练,测试和开发集,我已经上传到了仓库中,具体位置在
3947

4048
```shell
4149
Read_Bert_Code/bert_read_step_to_step/chineseGLUEdatasets/tnews
4250
```
4351

4452
需要注意的一点是,因为我只是为了了解内部代码情况,所以准确度不是在我的考虑范围之内,所以我只是取其中的一部分数据,其中训练数据使用1k,测试数据使用1k,开发数据1k。
4553

46-
准备就绪,使用pycharm导入项目,准备调试,我的调试文件是 run_classifier.py文件,对应的参数
47-
48-
正常情况下我是需要运行run_classifier_tnews.sh 这个文件的,这个文件主要是为run_classifier.py这个文件配置一些参数,我把这些参数直接config到run_classifier.py文件中,就不适用run_classifier_tnews.sh这个文件进行运行了。
49-
50-
这里列一下run_classifier.py的配置参数如下:
54+
准备就绪,使用pycharm导入项目,准备调试,我的调试文件是 run_classifier.py文件,对应的参数为
5155

56+
```shell
5257
--model_type=bert --model_name_or_path=prev_trained_model/bert-base-chinese --task_name="tnews" --do_train --do_eval --do_lower_case --data_dir=./chineseGLUEdatasets/tnews --max_seq_length=128 --per_gpu_train_batch_size=16 --per_gpu_eval_batch_size=16 --learning_rate=2e-5 --num_train_epochs=4.0 --logging_steps=100 --save_steps=100 --output_dir=./outputs/tnews_output/ --overwrite_output_dir
58+
```
5359

54-
然后对run_classifier.py 进行调试,我会在下面总结细节
60+
然后对run_classifier.py 进行调试,我会在下面是调试的细节
5561

5662
## 1.main函数进入
63+
64+
首先是主函数位置打入断点,位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L522),然后进入看一下主函数的情况
65+
5766
```python
5867
##主函数打上断点
5968
if __name__ == "__main__":
@@ -62,10 +71,12 @@ if __name__ == "__main__":
6271

6372
## 2.解析命令行参数
6473

65-
解析命令行参数:主要是什么模型名称,模型地址,是否进行测试等等。比较简单就不罗列代码了
74+
[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L333)[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L413)就是在解析命令行参数,是常规操作,主要是什么模型名称,模型地址,是否进行测试等等。比较简单,直接过就可以了
6675

6776
## 3.判断一些情况
6877

78+
[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L414)[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L448)是一些常规的判断:
79+
6980
判断是否存在输出文件夹
7081

7182
判断是否需要远程debug
@@ -74,7 +85,10 @@ if __name__ == "__main__":
7485

7586
一个是args.local_rank == -1 or args.no_cuda 为true,如果有gpu,就进行单机dpu训练,如果没有gpu就进行单机cpu训练。 否则进行多级GPU训练。
7687

77-
简单来讲,0或者其他数字代表GPU训练,-1代表单机CPU训练
88+
简单来讲,0或者其他数字代表GPU训练,-1代表单机CPU训练,
89+
90+
具体可以看代码如下:
91+
7892
```python
7993
if args.local_rank == -1 or args.no_cuda:
8094
device = torch.device("cuda" if torch.cuda.is_available() and not args.no_cuda else "cpu")
@@ -88,44 +102,41 @@ else: # Initializes the distributed backend which will take care of sychronizin
88102

89103
## 4.获取任务对应Processor
90104

91-
获取任务对应的相应processor,这个对应的函数就是需要我们自己去定义的处理我们自己输入文件的函数
105+
获取任务对应的相应processor,这个对应的函数就是需要我们自己去定义的处理我们自己输入文件的函数,位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L449),代码如下:
92106

93107
```python
94108
processor = processors[args.task_name]()
95109
```
96110

97-
这里我们使用的是
111+
这里我们使用的是,这个结果返回的是一个类,我们使用的是如下的类:
98112

99113
```python
100114
TnewsProcessor(DataProcessor)
101115
```
102116

117+
具体代码位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/processors/glue.py#L376),
118+
103119
### 4.1 TnewsProcessor
104120

105121
仔细分析一下TnewsProcessor,首先继承自DataProcessor
122+
106123
<details>
107124
<summary>点击此处打开折叠代码</summary>
108125

109126
```python
110127
## DataProcessor在整个项目的位置:processors.utils.DataProcessor
111128
class DataProcessor(object):
112-
"""Base class for data converters for sequence classification data sets."""
113-
114129
def get_train_examples(self, data_dir):
115-
"""Gets a collection of `InputExample`s for the train set."""
116130
raise NotImplementedError()
117131

118132
def get_dev_examples(self, data_dir):
119-
"""Gets a collection of `InputExample`s for the dev set."""
120133
raise NotImplementedError()
121134

122135
def get_labels(self):
123-
"""Gets the list of labels for this data set."""
124136
raise NotImplementedError()
125137

126138
@classmethod
127139
def _read_tsv(cls, input_file, quotechar=None):
128-
"""Reads a tab separated value file."""
129140
with open(input_file, "r", encoding="utf-8-sig") as f:
130141
reader = csv.reader(f, delimiter="\t", quotechar=quotechar)
131142
lines = []
@@ -145,14 +156,15 @@ class DataProcessor(object):
145156
```
146157
</details>
147158

148-
然后它自己包含五个函数,分别是读取训练集,测试集,开发集数据,获取返回label,制作bert需要的格式的数据
159+
然后它自己包含五个函数,分别是读取训练集,开发集数据,获取返回label,制作bert需要的格式的数据
160+
161+
接下来看一下 TnewsProcessor代码格式:
149162

150163
<details>
151164
<summary>点击此处打开折叠代码</summary>
152165

153166
```python
154167
class TnewsProcessor(DataProcessor):
155-
"""Processor for the SST-2 data set (GLUE version)."""
156168

157169
def get_train_examples(self, data_dir):
158170
"""See base class."""
@@ -194,14 +206,16 @@ class TnewsProcessor(DataProcessor):
194206
```
195207
</details>
196208

209+
这里有一点需要提醒大家,如果说我们使用自己的训练数据,有两个方法,第一个就是把数据格式变化成和我们测试用例一样的数据,第二个就是我们在这里更改源代码,去读取我们自己的数据格式
210+
197211
## 5.加载预训练模型
198-
代码比较简单,就是调用预训练模型
212+
213+
代码比较简单,就是调用预训练模型,不详细介绍了
199214

200215
<details>
201216
<summary>点击此处打开折叠代码</summary>
202217

203218
```python
204-
205219
config_class, model_class, tokenizer_class = MODEL_CLASSES[args.model_type]
206220
config = config_class.from_pretrained(args.config_name if args.config_name else args.model_name_or_path, num_labels=num_labels, finetuning_task=args.task_name)
207221
tokenizer = tokenizer_class.from_pretrained(args.tokenizer_name if args.tokenizer_name else args.model_name_or_path, do_lower_case=args.do_lower_case)
@@ -212,23 +226,30 @@ model = model_class.from_pretrained(args.model_name_or_path, from_tf=bool('.ckpt
212226

213227
## 6.训练模型-也是最重要的部分
214228

215-
训练模型,从主函数这里看就是两个步骤,一个是加载需要的数据集,一个是进行训练,大概代码就是
229+
训练模型,从主函数这里看就是两个步骤,一个是加载需要的数据集,一个是进行训练,代码位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L472)。大概代码就是这样:
216230

217231
```python
218-
219232
train_dataset = load_and_cache_examples(args, args.task_name, tokenizer, data_type='train')
220233
global_step, tr_loss = train(args, train_dataset, model, tokenizer)
221234

222235
```
223236

237+
两个函数,我们一个个看:
238+
224239
### 6.1 加载训练集
225240

226-
我们先看一下第一个函数,load_and_cache_examples 就是加载训练数据集,大概看一下这个代码,核心操作有三个个,一个是利用processor读取训练集,一个是convert_examples_to_features讲数据进行转化,第三个是将转化之后的新数据tensor化,然后使用TensorDataset构造最终的数据集并返回
241+
我们先看一下第一个函数,load_and_cache_examples 就是加载训练数据集,代码位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L274)。大概看一下这个代码,核心操作有三个。
242+
243+
244+
245+
第一个核心操作,位置在这里(https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L297),代码如下:
227246

228247
```python
229248
examples = processor.get_train_examples(args.data_dir)
230249
```
231250

251+
这个代码是为了利用processor读取训练集,很简单。
252+
232253
这里得到的example大概是这样的(这个返回形式在上面看processor的时候很清楚的展示了):
233254

234255
```
@@ -238,7 +259,9 @@ text_a='今天股票形式不怎么样啊'
238259
text_b=None
239260
```
240261

241-
接下来第二个核心操作是
262+
第二个核心操作是convert_examples_to_features讲数据进行转化,也很简单。
263+
264+
代码位置在[这里](https://github.com/DA-southampton/Read_Bert_Code/blob/7e3c619aef9e462ec8865cde75c7a0ff2aefe60f/bert_read_step_to_step/run_classifier.py#L303)。代码如下:
242265

243266
```python
244267
features = convert_examples_to_features(examples,tokenizer,label_list=label_list,max_length=args.max_seq_length,output_mode=output_mode,pad_on_left=bool(args.model_type in ['xlnet']), pad_token=tokenizer.convert_tokens_to_ids([tokenizer.pad_token])[0],
@@ -267,8 +290,6 @@ processors.glue.glue_convert_examples_to_features
267290

268291
这个时候,我们的input_ids 就变成了上面的列表后面加上1280.然后我们的attention_mask就变成了上面的形式加上1180,因为补长的并不是我们的第二个句子,我们压根没第二个句子,所以token_type_ids是总共1280
269292

270-
271-
272293
每操作一个数据之后,我们需要做的是
273294

274295
```python
@@ -283,7 +304,7 @@ InputFeatures 在这里就是将转化之后的特征存储到一个新的变量
283304

284305
在将所有原始数据进行特征转化之后,我们得到了features列表,然后将其中的元素转化为tensor形式,随后
285306

286-
使用TensorDataset获取最终的数据集
307+
第三个是将转化之后的新数据tensor化,然后使用TensorDataset构造最终的数据集并返回,
287308

288309
```python
289310
dataset = TensorDataset(all_input_ids, all_attention_mask, all_token_type_ids, all_lens,all_labels)

0 commit comments

Comments
 (0)