基于項目選擇了PaddlePaddle 作為文本分類的基礎,經過一周多的使用終于有所進展,把文本分類的相關工作做了一個簡單模型。
首先說說PaddlePaddle , 現在做深度學習,更多使用者使用的是TensorFlow / PyTorch ,但其實還有很多類似的架構,PaddlePaddle就是其中之一。有人會說TensorFlow / PyTorch 已經這麼優秀了,為何還用 PaddlePaddle 呢 ?我這裡也想結合一周多的使用說說 。當初使用 Paddle Paddle架構我看中的是他在自然語言中文領域有很多現成的模型,舉個例子如情感分類,如閱讀了解,還有自動問答等,而且在使用上也是非常簡單。我就是奔着這個去的,至于其他像記憶體占用小啊,API易用這些用過就知道其實是一個場景相對的工作。如果我們使用自然語言相關,我是建議使用,但在計算機視覺或者其他的都差不多。PaddlePaddle 在設計初期就兼顧了動态圖和靜态圖,是以還是不錯的。
PaddlePaddle 有不少預訓練的模型,基于預訓練組建了一個PaddleHub , 可以讓你快速調用并完成模型的管理,你還可以基于自有的模型做遷移學習,更好地服務應用場景。這裡做文本分類,我就直接用了PaddleHub 自有的 ERNIE 進行遷移學習。就這樣我就開始了一段神奇之旅。
一.ERNIE
在中文領域,這是一個非常非常棒的自然語言模型,和BERT 比,采用了先知Mask機制,和随機Mask 的BERT比,能更有效對中文常用詞進行判斷。更多可以參考 https://github.com/PaddlePaddle/ERNIE
二. 具體使用遇到的一些問題,PaddlePaddle 在網上搜尋的例子都是有問題的,因為基于原來的例子基本是按照1.x 版本(https://aistudio.baidu.com/aistudio/projectdetail/186443)改的,隻能自己碰
1. 環境問題,我現在的Cuda 環境是11.1 , 但是無論最新的2.1 還是2.0.2 其實都沒有支援的,開始我自己也慌了第一步就放棄麼?但我認真看了下,其實2.0.2 是支援11.0 也是可以在11.1的CUDA上跑,是以安裝環境就變成了
pip install paddlepaddle-gpu==2.0.2.post110 -f https://paddlepaddle.org.cn/whl/stable.html
是以對應的PaddleHub 就是2.1.0 (這裡還是得修正下,PaddleHub 用2.1,原來是2.0.2)
注:如果你是CPU就不需要考慮這個,但我覺得沒有GPU訓練也是太扯了如果做這個
2. ERNIE 版本選擇,其實我本來想要ERNIE,但最後選擇ERNIE-TINY是因為他更小巧,更适應我的場景, 如果你想應用其他也是可以的,他支援多種語義模型
import paddlehub as hub
model = hub.Module(name='ernie_tiny', version='2.0.1', task='seq-cls', num_classes=5)
3. 因為我是做遷移學習的文本分類是以這裡就需要去繼承原有的TextClassificationDataset,我一直覺得是一個簡單活,結果花了我一堆時間,因為這裡對資料格式有要求,第一列必須是Label , 而且token是一個Bert+Custom , 并且一定要做好測試集和訓練集,這裡我真的花了5天去找,但最後還是追看TextClassificationDataset 找到答案,主要是文檔太少
from typing import Dict, List, Optional, Union, Tuple
from paddlehub.datasets.base_nlp_dataset import TextClassificationDataset
import paddlenlp.data.tokenizer as tk
from paddlenlp.data import JiebaTokenizer
from paddlenlp.transformers import BertTokenizer
from paddlehub.text.tokenizer import CustomTokenizer
DATA_HOME = "./datasets/data/"
class TagDatasets(TextClassificationDataset):
def __init__(self , tokenizer: Union[BertTokenizer, CustomTokenizer],max_seq_len: int = 128, mode: str = 'train'):
if mode == 'train':
data_file = 'data_train_list.tsv'
elif mode == 'test':
data_file = 'data_test_list.tsv'
else:
data_file = 'data_all_list.tsv'
super().__init__(
base_path=DATA_HOME,
max_seq_len=max_seq_len,
tokenizer= tokenizer,
data_file=data_file,
label_list = ['0', '1', '2', '3', '4'], #改動2
is_file_with_header=True)
train_dataset = TagDatasets(tokenizer=model.get_tokenizer(), max_seq_len=128, mode='train')
test_dataset = TagDatasets(tokenizer=model.get_tokenizer(), max_seq_len=128, mode='test')
4. 訓練這裡細節也挺多的,特别最基本的一個traindata 這裡要說,我發現是要補充上learning_rate ,否則有些東西奇奇怪怪
import paddle
optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters())
trainer = hub.Trainer(model, optimizer,use_gpu=True, checkpoint_dir='./model/2021052501/ernie_text_cls')
trainer.train(train_dataset, epochs=10, batch_size=32, eval_dataset=train_dataset,save_interval=5)
trainer.evaluate(test_dataset, batch_size=32)
這是我訓練的一些結果,還是不錯,這個過程我花了5個工作日,真是痛哭流涕
三. 一些工作還是要繼續的
1. 部署,其實PaddleHub建議用PaddleServing 來部署的,但由于現在模型還在調整,資料在增加,是以臨時方案還是直接用PaddleHub去解釋模型,這裡記憶體在伺服器占用大,要改進
2. 調優,還有很多方法,還在學習中,希望日後可以填上
3. onnx , 還是想轉換為onnx ,但文檔很少,還是得花時間
4. 壓縮,模型壓縮就是技術活了,怎麼樣能做到一個精度高,容量小的模型,又是我要考慮的了
四. 小結
學習是一步步的,經過1周多,終于有成果, PaddlePaddle是好東西,但文檔,例子欠缺,我希望利用自己項目的經驗分享給大家。