這期總算琢磨了點乾貨出來,主要涉及Pytorch-transformer給出的Bert ,XLM ,以及XLNet(三個NLP目前的大哥大)的參數調整和實際應用。
現在普遍的現象是要麼有現成的輪子但是封裝程度太高了,很難改裡面的參數,要麼允許調參數,但是代碼太多了,或者有些版本過低拿來根本不能用,這篇主要解決了:
Bert 、XLM、XLNet的參數由json導入並建立新類進行調整
XLM、XLNet的vocab_file的取出
XLM、XLNet與face.ai的結合(基於以上兩點)
我把自己詳細探索的步驟寫了下來,供大家參考和分享。文章有點長。
只要你對NLP有一丟丟了解,一定聽過Bert的大名,現在大量的技術類公眾號和CSDN博客上鋪天蓋地都是Bert 原理講解,其實最好的方式就是配合論文擼一遍源碼。但是對於像我這樣的平凡人,擼過代碼後也只能感嘆一聲谷歌牛X,但是實際改起來用到自己的研究中去工作量還是很大的。這些Algorithm是給天才們去做的,我們平凡的人類更需要的是實現和應用,即生產力。就像我們不會去關注信號發射用的是什麼算法,我們關心的是網速快不快。
雖然谷歌已經把bert開源了可是面對繁雜的代碼我等凡人還是望而卻步。一個叫Hugging face的天才創業團隊下凡普渡眾生了,在他們的網站上給出了六種NLP模型,均為現在自然語言處理(NLP)領域最常用的六種模型:BERT,GPT,GPT-2,Transformer-XL,XLNet,XLM
Github地址:
https://github.com/huggingface/pytorch-transformers
教程文檔:
https://huggingface.co/pytorch-transformers/quickstart.html#documentation
所以我覺得現在的環境對於平凡人真的太好了,大神和天才們已經把框架寫好了還很貼心的寫了教程文檔,我們需要做的只是閱讀這些教程和源碼、follow一下、然後修改,甚至可以和其他的輪子粘在一起。
我們先pip install pytorch-transformers, 就可以把六個模型收入囊中。
然後我們試一下教程example裡面的代碼。
因為Bert的結構就是每個句子的開頭結尾要加上[cls]和[sep]
print一下token_tensors
後面就是把henson挖掉,給訓練好的bert 餵一第一個句子,第二個句子把henson挖掉(masked),看看bert能不能準確的預測到。
print(predicted_index)
print(predict_token)
發現
確實預測對了,後面還給了OpenAI的例子,大家可以操作一下。
這就很激動人心了,可以從繁雜的代碼中解脫出來,僅僅調用幾個函數就可以用到最先進的武器!
但是例子歸例子,並且只是兩句話,如果是一個excel 文檔呢?這是平時我們最常見的形式,我們一般是從一些網站裡爬取數據然後寫入excel或者是資料庫,然後從中讀取評論並判定情感正負。
我試著改寫了一下,以做到只需要改動數據集就可以跑起來。
但是還是太複雜前後加起來一共700多行,於是我跑去github上逛了一圈看看有沒有人在造輪子做簡化,然後撿到寶了,這裡貼出地址:
作者用的數據集是Kaggle中的惡意評論分類,目標是把評論分為6類,大家可以上kaggle搜一下並下載這個數據集。
要知道faceai是最簡單的了,因為調用learn的話只需要databunch,pretrained_model,loss_func,metrics就能用了,簡直是伸手黨的福音!
我把他的代碼運行了一下,發現...
這啥..為什麼輸出是tuple?不應該啊
這個問題困擾了我一個禮拜,於是暫時不幹了,看了一個禮拜注會
稅法看吐了後決定好好研讀一下pytorch-transformer的教程文檔,有了驚喜的發現。
它們是叫pytorch-pretrained但是現在改了一個酷炫的名字transformer,同時輸出格式變成了tuple,output的元組的格式,並且作者很貼心的說,把元組中第一個元素取出來就可以達到和原來pytorch-pretrained的output一樣的結果,所以現在的問題是——這些函數都是封裝好的,怎麼取出第一個元素?我首先第一個愚蠢的想法是把github裡面的源碼下下來,然後在output後面加個[0]就好了呀
但是Google 後,發現了大神的建議
呵呵 完蛋
這裡出錯說明我需要一個GPU了..果然窮人不適合玩深度學習
本著絕不花錢的原則,能改則改,我都改寫成函數的形式,加多線程,最後用main 調用(其實這個錯誤我在前一周爬SEC的網站時候出現過,後來改成函數用多線程就爬的很麻溜了)。
勉為其難的跑了起來,風扇轉的震天響,但是幸好沒有掛掉。
25分鐘才跑完一個epoch啊.這跑十多個不得好半天...
至暗時刻,谷歌爸爸來拯救蒼生了強烈推薦老師用這個進行教學,初學者用這個入門,因為實在是太方便了! 很多常用的包都裝好了(不僅僅是anaconda裡面那一套,更有kera等深度學習庫)還不用配置環境,記得去年被安裝各種包和配置環境折磨了很久的我幾乎要摔電腦,colab還是交互式的,還能修改後再運行..這就是相見恨晚吧(其實去年就可以用了)
最最最重要的是 谷歌爸爸提供免費GPU!Free! Free! Free!
這個GPU貌似也不便宜啊Tesla K80 GPU
前提是大家得有一個穩定的梯子(很多免費的梯子都不太穩定)...由於之前混跡於ins 和youtube,我有梯子和谷歌帳號。
登陸Google Drive,開始建立colab notebook
然後我把代碼從eclipse裡面複製過來在runtime裡面改成GPU模式運行了一下
訓練集上的準確度太低了,其實這是很正常的,大家看看bert的複雜程度
用它來訓練一個只有2000行的評論數據是不是大炮打螞蟻?
我決定改一下bert的參數,怎麼改,還是剛才的做法,定義一個新類,這個新類繼承了之前的類,在新類中把config設為自己想調整的。
我們不妨先看看谷歌的參數
我把新的參數做成json文件,導入新class中去,下面就是新的類,包括了參數調整和tuple的取出。
開始訓練
真的超快的啊...太強悍了
並且參數調整後訓練集上的準確度是有顯著提高的,我們再看看測試集的表現如何
還不賴吧
好了,Bert算是搞定了,別忘了pytorch-transformer還有XLM 和XLNet啊,用哪個好呢?
emm 我全要
其中要解決的最大的問題是語言模型,Bert我們可以用vocab.keys(),但是XLM和XLNet呢?
在閱讀源碼後我找到了
XLM的是bpe_ranks
但是只支持英文
剩下的只需要對原來bert的代碼做一點改動就行
之後的改動還是和之前的一樣,不過繼承的對象是XLMForSequenceClassification
改動這倆就Ok了
其中XLM的參數建議參考Bert的,不然根本跑不起來因為實在是太大了。
這裡可能有人發現了,我用到的都是SequenceClassification,但是如果沒有呢?像pytorch-transformer裡的其他三個模型是沒有的
那只能自己寫句子分類了,利用pytorch進行onehot編碼,思路和給出的教程是一樣的,再循環epoch。
我反正不想寫了,畢竟有這三個大哥何必再招小弟
我會找個時間把今天的代碼規整一下傳到github上去,大家去下載拿來用就好了
其實Huggingface上還有幾個庫很好玩,大家可以去嘗試一下多分類、猜詞等但是對於我來說暫時沒有那麼實用,就沒有做了
得抓緊看注會了,已經看不完了
參考文獻:
【1】 https://github.com/abhikjha/Fastai-integration-with-BERT
【2】https://github.com/huggingface/pytorch-transformers
httphttps://huggingface.co/pytorchtransformers/quickstart.html#documentation