目錄
- 大綱概述
- 數據集合
- 數據處理
- 預訓練word2vec模型
一、大綱概述
文本分類這個系列將會有8篇左右文章,從github直接下載代碼,從百度雲下載訓練數據,在pycharm上導入即可使用,包括基於word2vec預訓練的文本分類,與及基於近幾年的預訓練模型(ELMo,BERT等)的文本分類。總共有以下系列:
二、數據集合
數據集為IMDB 電影影評,總共有三個數據文件,在/data/rawData目錄下,包括unlabeledTrainData.tsv,labeledTrainData.tsv,testData.tsv。在進行文本分類時需要有標簽的數據(labeledTrainData),但是在訓練word2vec詞向量模型(無監督學習)時可以將無標簽的數據一起用上。
訓練數據地址:鏈接:https://pan.baidu.com/s/1-XEwx1ai8kkGsMagIFKX_g 提取碼:rtz8
三、bert模型
BERT 模型來源於論文BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding。BERT模型是Google提出的基於雙向Transformer構建的語言模型。BERT模型和ELMo有大不同,在之前的預訓練模型(包括word2vec,ELMo等)都會生成詞向量,這種類別的預訓練模型屬於domain transfer。BERT 模型是將預訓練模型和下游任務模型結合在一起的,也就是說在做下游任務時仍然是用BERT模型,詳細介紹請看這篇博文。Google提供了下面七種預訓練好的模型文件。
BERT模型在英文數據集上提供了兩種大小的模型,Base和Large。Uncased是意味着輸入的詞都會轉變成小寫,cased是意味着輸入的詞會保存其大寫(在命名實體識別等項目上需要)。Multilingual是支持多語言的,最后一個是中文預訓練模型。
在這里我們選擇BERT-Base,Uncased。下載下來之后是一個zip文件,解壓后有ckpt文件,一個模型參數的json文件,一個詞匯表txt文件。
在應用BERT模型之前,我們需要去github上下載開源代碼,我們可以直接clone下來,在這里有一個run_classifier.py文件,在做文本分類項目時,我們需要修改這個文件,主要是添加我們的數據預處理類。clone下來的項目結構如下:
修改部分如下:
3.1 新增IMDBProcessor
在run_classifier.py文件中有一個基類DataProcessor類,在這個基類中定義了一個讀取文件的靜態方法_read_tsv,四個分別獲取訓練集,驗證集,測試集和標簽的方法。接下來我們要定義自己的數據處理的類,我們將我們的類命名為
class IMDBProcessor(DataProcessor): """ IMDB data processor """ def _read_csv(self, data_dir, file_name): with tf.gfile.Open(data_dir + file_name, "r") as f: reader = csv.reader(f, delimiter=",", quotechar=None) lines = [] for line in reader: lines.append(line) return lines def get_train_examples(self, data_dir): lines = self._read_csv(data_dir, "trainData.csv") examples = [] for (i, line) in enumerate(lines): if i == 0: continue guid = "train-%d" % (i) text_a = tokenization.convert_to_unicode(line[0]) label = tokenization.convert_to_unicode(line[1]) examples.append( InputExample(guid=guid, text_a=text_a, label=label)) return examples def get_dev_examples(self, data_dir): lines = self._read_csv(data_dir, "devData.csv") examples = [] for (i, line) in enumerate(lines): if i == 0: continue guid = "dev-%d" % (i) text_a = tokenization.convert_to_unicode(line[0]) label = tokenization.convert_to_unicode(line[1]) examples.append( InputExample(guid=guid, text_a=text_a, label=label)) return examples def get_test_examples(self, data_dir): lines = self._read_csv(data_dir, "testData.csv") examples = [] for (i, line) in enumerate(lines): if i == 0: continue guid = "test-%d" % (i) text_a = tokenization.convert_to_unicode(line[0]) label = tokenization.convert_to_unicode(line[1]) examples.append( InputExample(guid=guid, text_a=text_a, label=label)) return examples def get_labels(self): return ["0", "1"]
3.2 main函數下面的processors
在這里我們沒有直接用基類中的靜態方法_read_tsv,因為我們的csv文件是用逗號分隔的,因此就自己定義了一個_read_csv的方法,其余的方法就是讀取訓練集,驗證集,測試集和標簽。在這里標簽就是一個列表,將我們的類別標簽放入就行。訓練集,驗證集和測試集都是返回一個InputExample對象的列表。InputExample是run_classifier.py中定義的一個類。在這個類中定義了text_a和text_b,說明是支持句子對的輸入的,不過我們這里做文本分類只有一個句子的輸入,因此text_b可以不傳參。
另外從上面我們自定義的數據處理類中可以看出,訓練集和驗證集是保存在不同文件中的,因此我們需要將我們之前預處理好的數據提前分割成訓練集和驗證集,並存放在同一個文件夾下面,文件的名稱要和類中方法里的名稱相同。
到這里之后我們已經准備好了我們的數據集,並定義好了數據處理類,此時我們需要將我們的數據處理類加入到run_classifier.py文件中的main函數下面的processors字典中,結果如下:
1 def main(_): 2 tf.logging.set_verbosity(tf.logging.INFO) 3 4 processors = { 5 "cola": ColaProcessor, 6 "mnli": MnliProcessor, 7 "mrpc": MrpcProcessor, 8 "xnli": XnliProcessor, 9 "imdb": IMDBProcessor #這一句是新增的,用於調用完成本次任務 10 }
3.3 配置腳本
--data_dir=../MY_DATASET/
--task_name=imdb
--vocab_file=../BERT_BASE_DIR/uncased_L-12_H-768_A-12/vocab.txt
--bert_config_file=../BERT_BASE_DIR/uncased_L-12_H-768_A-12/bert_config.json
--do_train=true
--do_eval=true
--init_checkpoint=../BERT_BASE_DIR/uncased_L-12_H-768_A-12/bert_model.ckpt
--max_seq_length=128
--train_batch_size=16
--learning_rate=5e-5
--num_train_epochs=2.0
--output_dir=../output/
具體在pycharm這種IDE運行的辦法可見這篇博文。
相關代碼可見:https://github.com/yifanhunter/NLP_textClassifier