[Python人工智能] 二十四.易學(xué)智能GPU搭建Keras環(huán)境實(shí)現(xiàn)LSTM惡意URL請求分類
最近用筆記本跑Keras和TensorFlow深度學(xué)習(xí)代碼,一個(gè)模型跑十幾個(gè)小時(shí)還奔潰,真的頭大!這篇文章簡單講解易學(xué)智能GPU搭建Keras環(huán)境的過程,并實(shí)現(xiàn)了LSTM文本分類的實(shí)驗(yàn),本來想寫Google Colab免費(fèi)云,但看知乎評價(jià)也不太好(梯子常斷網(wǎng)、時(shí)間限制、數(shù)據(jù)量?。?。因此,選擇一個(gè)評價(jià)較好的平臺(tái)供大家學(xué)習(xí)(6塊一小時(shí)),也希望大家推薦更好的平臺(tái),百度飛漿后續(xù)準(zhǔn)備也學(xué)習(xí)下,希望這篇文章能解決自身電腦配置不足,需要GPU運(yùn)行模型且服務(wù)器價(jià)格又不是太高的同學(xué),加油!

如果個(gè)人電腦足夠使用的同學(xué),則可以看看這篇文章的LSTM文本分類代碼,下一篇文章我將詳細(xì)對比?;A(chǔ)性文章,希望對您有所幫助。
Keras-:https://github.com/eastmountyxz/AI-for-Keras
TensorFlow-:https://github.com/eastmountyxz/AI-for-TensorFlow
文章目錄
一.搭建易學(xué)智能GPU平臺(tái)
二.易學(xué)智能運(yùn)行Python代碼
三.LSTM基礎(chǔ)知識(shí)
1.RNN原理
2.RNN應(yīng)用
3.為什么引入LSTM
4.LSTM
四.編寫LSTM神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)文本分類
1.N-gram分詞
2.LSTM構(gòu)建
3.實(shí)驗(yàn)評估
五.總結(jié)
華為云社區(qū)前文賞析:
[Python人工智能] 一.TensorFlow2.0環(huán)境搭建及神經(jīng)網(wǎng)絡(luò)入門
[Python人工智能] 二.TensorFlow基礎(chǔ)及一元直線預(yù)測案例
[Python人工智能] 三.TensorFlow基礎(chǔ)之Session、變量、傳入值和激勵(lì)函數(shù)
[Python人工智能] 四.TensorFlow創(chuàng)建回歸神經(jīng)網(wǎng)絡(luò)及Optimizer優(yōu)化器
[Python人工智能] 五.Tensorboard可視化基本用法及繪制整個(gè)神經(jīng)網(wǎng)絡(luò)
[Python人工智能] 六.TensorFlow實(shí)現(xiàn)分類學(xué)習(xí)及MNIST手寫體識(shí)別案例
[Python人工智能] 七.什么是過擬合及dropout解決神經(jīng)網(wǎng)絡(luò)中的過擬合問題
[Python人工智能] 八.卷積神經(jīng)網(wǎng)絡(luò)CNN原理詳解及TensorFlow編寫CNN
[Python人工智能] 九.gensim詞向量Word2Vec安裝及《慶余年》中文短文本相似度計(jì)算
[Python人工智能] 十.Tensorflow+Opencv實(shí)現(xiàn)CNN自定義圖像分類及與KNN圖像分類對比
[Python人工智能] 十一.Tensorflow如何保存神經(jīng)網(wǎng)絡(luò)參數(shù)
[Python人工智能] 十二.循環(huán)神經(jīng)網(wǎng)絡(luò)RNN和LSTM原理詳解及TensorFlow編寫RNN分類案例
[Python人工智能] 十三.如何評價(jià)神經(jīng)網(wǎng)絡(luò)、loss曲線圖繪制、圖像分類案例的F值計(jì)算
[Python人工智能] 十四.循環(huán)神經(jīng)網(wǎng)絡(luò)LSTM RNN回歸案例之sin曲線預(yù)測 丨【百變AI秀】
[Python人工智能] 十五.無監(jiān)督學(xué)習(xí)Autoencoder原理及聚類可視化案例詳解
[Python人工智能] 十六.Keras環(huán)境搭建、入門基礎(chǔ)及回歸神經(jīng)網(wǎng)絡(luò)案例
[Python人工智能] 十七.Keras搭建分類神經(jīng)網(wǎng)絡(luò)及MNIST數(shù)字圖像案例分析
[Python人工智能] 十八.Keras搭建卷積神經(jīng)網(wǎng)絡(luò)及CNN原理詳解
[Python人工智能] 十九.Keras搭建循環(huán)神經(jīng)網(wǎng)絡(luò)分類案例及RNN原理詳解
[Python人工智能] 二十.基于Keras+RNN的文本分類vs基于傳統(tǒng)機(jī)器學(xué)習(xí)的文本分類
[Python人工智能] 二十一.Word2Vec+CNN中文文本分類詳解及與機(jī)器學(xué)習(xí)算法對比
[Python人工智能] 二十二.基于大連理工情感詞典的情感分析和情緒計(jì)算
[Python人工智能] 二十三.基于機(jī)器學(xué)習(xí)和TFIDF的情感分類(含詳細(xì)的NLP數(shù)據(jù)清洗)
[Python人工智能] 二十四.易學(xué)智能GPU搭建Keras環(huán)境實(shí)現(xiàn)LSTM惡意URL請求分類
一.搭建易學(xué)智能GPU平臺(tái)
第一步,注冊登錄后,選擇“控制臺(tái)”->“新建主機(jī)”。
點(diǎn)擊“結(jié)算開機(jī)”會(huì)提示相關(guān)內(nèi)容,如下圖所示。
創(chuàng)建Windows主機(jī)
創(chuàng)建Ubuntu主機(jī)
點(diǎn)擊“確認(rèn)開機(jī)”后支付金額并初始化。
第三步,下載遠(yuǎn)程連接配置文件:控制臺(tái)->我的主機(jī)->遠(yuǎn)程連接信息,點(diǎn)擊下載。
接著點(diǎn)擊“下載Windows遠(yuǎn)程桌面配置文件”按鈕,下圖是官方提供的,大家寫文章時(shí)也需要避免個(gè)人服務(wù)器賬號(hào)泄露喔!
賬號(hào)
密碼
IP地址
端口
第四步,遠(yuǎn)程連接。雙擊windows_connect.rdp,輸入密碼。
輸入密碼登錄即可。
登錄成功后進(jìn)入Windows遠(yuǎn)程界面。
桌面如下圖所示,運(yùn)行代碼的主要方式有命令行、Jupyter、PyCharm、Spyder等。
命令行,運(yùn)行代碼前請激活conda環(huán)境
Windows使用Jupyter
使用PyCharm:在PyCharm中配置python解釋器
使用Spyder:在Spyder中配置與使用python解釋器
第五步,點(diǎn)擊關(guān)機(jī)后停止計(jì)費(fèi),一定要點(diǎn)擊“關(guān)機(jī)”按鈕,切記。同時(shí)下次開機(jī)我們可以選擇新的服務(wù)器型號(hào)和系統(tǒng)。
關(guān)機(jī)注意事項(xiàng)如下:
至此這個(gè)易學(xué)智能的服務(wù)云環(huán)境就介紹結(jié)束,下面我們開始講解Python和深度學(xué)習(xí)的配置過程。
二.易學(xué)智能運(yùn)行Python代碼
第一步,激活Conda環(huán)境。
打開conda prompt(桌面有快捷方式),激活Conda環(huán)境。以使用py36h為例,打開anaconda prompt命令行,輸入:
activate py36h或conda activate py36h
第二步,直接打開Python3.7 IDLE編寫代碼即可。
pip list可以查看已經(jīng)配置的擴(kuò)展包,注意TensorFlow安裝的是GPU版本。
TensorFlow框架如下圖所示:
第三步,輸入jupyter notebook打開Jupyter Notebook,如下圖所示。
輸入pip install pkg或conda install pkg可以安裝擴(kuò)展包。
第四步,利用Spyder編寫代碼。
首次打開需要初始化一段時(shí)間,接著運(yùn)行結(jié)果如下圖所示。
選擇安裝的環(huán)境“py36h”,然后安裝Spyder,利用這個(gè)編寫Python代碼。
或者在終端中輸入“spyer”打開。
同樣讀者可以直接使用PyCharm編寫Python代碼,它的常用擴(kuò)展包也被成功安裝了。
下列代碼可以查看軟件版本信息:
import tensorflow as tf print(tf.__version__) import torch as th print(th.__version__) import keras print(keras.__version__)
輸出結(jié)果如下圖所示:
第五步,查看環(huán)境是否為GPU版本。
以tensorflow為例,運(yùn)行下面python代碼。
import tensorflow as tf print(tf.__version__) import os os.environ["CUDA_DEVICES_ORDER"] = "PCI_BUS_IS" os.environ["CUDA_VISIBLE_DEVICES"] = "0" #sess = tf.Session() sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) a = tf.constant(1) b = tf.constant(2) print(sess.run(a+b)) from tensorflow.python.client import device_lib print(device_lib.list_local_devices())
輸出結(jié)果如下圖所示,我們可以使用 “/device:CPU:0”,"/device:GPU:0"。
同樣補(bǔ)充另一種設(shè)置設(shè)備的方式,核心代碼如下所示:
import tensorflow as tf with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)) as sess: sess.run(init) with tf.device('/device:GPU:0'): for _ in range(3): print(sess.run(state))
from sklearn.datasets import load_iris import numpy as np from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt #獲取花瓣的長和寬 hua = load_iris() x = [n[0] for n in hua.data] y = [n[1] for n in hua.data] x = np.array(x).reshape(len(x),1) y = np.array(y).reshape(len(y),1) #線性回歸分析 clf = LinearRegression() clf.fit(x,y) pre = clf.predict(x) #可視化畫圖 plt.scatter(x,y,s=100) plt.plot(x,pre,"r-",linewidth=4) for idx, m in enumerate(x): plt.plot([m,m],[y[idx],pre[idx]], 'g-') plt.show()
運(yùn)行結(jié)果如下圖所示:
第八步,代碼文件上傳。
你可能會(huì)想遠(yuǎn)程代碼是不是需要發(fā)送到百度網(wǎng)盤或github,再下載運(yùn)行,其實(shí)易學(xué)智能提供了一個(gè)上傳文件的功能。界面如下圖所示:
上傳代碼如下圖所示,保存至“M盤/MyFiles”路徑。
參考文獻(xiàn):
http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/using_gpu.html
https://blog.csdn.net/qq_34022601/article/details/90449789
三.LSTM基礎(chǔ)知識(shí)
在介紹LSTM模型之前,先分享循環(huán)神經(jīng)網(wǎng)絡(luò)知識(shí)。
1.RNN原理
循環(huán)神經(jīng)網(wǎng)絡(luò)英文是Recurrent Neural Networks,簡稱RNN。假設(shè)有一組數(shù)據(jù)data0、data1、data2、data3,使用同一個(gè)神經(jīng)網(wǎng)絡(luò)預(yù)測它們,得到對應(yīng)的結(jié)果。如果數(shù)據(jù)之間是有關(guān)系的,比如做菜下料的前后步驟,英文單詞的順序,如何讓數(shù)據(jù)之間的關(guān)聯(lián)也被神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)呢?這就要用到——RNN。
假設(shè)存在ABCD數(shù)字,需要預(yù)測下一個(gè)數(shù)字E,會(huì)根據(jù)前面ABCD順序進(jìn)行預(yù)測,這就稱為記憶。預(yù)測之前,需要回顧以前的記憶有哪些,再加上這一步新的記憶點(diǎn),最終輸出output,循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)就利用了這樣的原理。
首先,讓我們想想人類是怎么分析事物之間的關(guān)聯(lián)或順序的。人類通常記住之前發(fā)生的事情,從而幫助我們后續(xù)的行為判斷,那么是否能讓計(jì)算機(jī)也記住之前發(fā)生的事情呢?
在分析data0時(shí),我們把分析結(jié)果存入記憶Memory中,然后當(dāng)分析data1時(shí),神經(jīng)網(wǎng)絡(luò)(NN)會(huì)產(chǎn)生新的記憶,但此時(shí)新的記憶和老的記憶沒有關(guān)聯(lián),如上圖所示。在RNN中,我們會(huì)簡單的把老記憶調(diào)用過來分析新記憶,如果繼續(xù)分析更多的數(shù)據(jù)時(shí),NN就會(huì)把之前的記憶全部累積起來。
RNN結(jié)構(gòu)如下圖所示,按照時(shí)間點(diǎn)t-1、t、t+1,每個(gè)時(shí)刻有不同的x,每次計(jì)算會(huì)考慮上一步的state和這一步的x(t),再輸出y值。在該數(shù)學(xué)形式中,每次RNN運(yùn)行完之后都會(huì)產(chǎn)生s(t),當(dāng)RNN要分析x(t+1)時(shí),此刻的y(t+1)是由s(t)和s(t+1)共同創(chuàng)造的,s(t)可看作上一步的記憶。多個(gè)神經(jīng)網(wǎng)絡(luò)NN的累積就轉(zhuǎn)換成了循環(huán)神經(jīng)網(wǎng)絡(luò),其簡化圖如下圖的左邊所示。
總之,只要你的數(shù)據(jù)是有順序的,就可以使用RNN,比如人類說話的順序,電話號(hào)碼的順序,圖像像素排列的順序,ABC字母的順序等。在前面講解CNN原理時(shí),它可以看做是一個(gè)濾波器滑動(dòng)掃描整幅圖像,通過卷積加深神經(jīng)網(wǎng)絡(luò)對圖像的理解。
而RNN也有同樣的掃描效果,只不過是增加了時(shí)間順序和記憶功能。RNN通過隱藏層周期性的連接,從而捕獲序列化數(shù)據(jù)中的動(dòng)態(tài)信息,提升預(yù)測結(jié)果。
2.RNN應(yīng)用
RNN常用于自然語言處理、機(jī)器翻譯、語音識(shí)別、圖像識(shí)別等領(lǐng)域,下面簡單分享RNN相關(guān)應(yīng)用所對應(yīng)的結(jié)構(gòu)。
RNN情感分析:?當(dāng)分析一個(gè)人說話情感是積極的還是消極的,就用如下圖所示的RNN結(jié)構(gòu),它有N個(gè)輸入,1個(gè)輸出,最后時(shí)間點(diǎn)的Y值代表最終的輸出結(jié)果。
RNN圖像識(shí)別:?此時(shí)有一張圖片輸入X,N張對應(yīng)的輸出。
RNN機(jī)器翻譯:?輸入和輸出分別兩個(gè),對應(yīng)的是中文和英文,如下圖所示。
3.為什么引入LSTM
RNN是在有序的數(shù)據(jù)上進(jìn)行學(xué)習(xí)的,RNN會(huì)像人一樣對先前的數(shù)據(jù)發(fā)生記憶,但有時(shí)候也會(huì)像老爺爺一樣忘記先前所說。為了解決RNN的這個(gè)弊端,提出了LTSM技術(shù),它的英文全稱是Long short-term memory,長短期記憶,也是當(dāng)下最流行的RNN之一。
假設(shè)現(xiàn)在有一句話,如下圖所示,RNN判斷這句話是紅燒排骨,這時(shí)需要學(xué)習(xí),而“紅燒排骨“在句子開頭。
"紅燒排骨"這個(gè)詞需要經(jīng)過長途跋涉才能抵達(dá),要經(jīng)過一系列得到誤差,然后經(jīng)過反向傳遞,它在每一步都會(huì)乘以一個(gè)權(quán)重w參數(shù)。如果乘以的權(quán)重是小于1的數(shù),比如0.9,0.9會(huì)不斷地乘以誤差,最終這個(gè)值傳遞到初始值時(shí),誤差就消失了,這稱為梯度消失或梯度離散。
反之,如果誤差是一個(gè)很大的數(shù),比如1.1,則這個(gè)RNN得到的值會(huì)很大,這稱為梯度爆炸。
梯度消失或梯度爆炸:
在RNN中,如果你的State是一個(gè)很長的序列,假設(shè)反向傳遞的誤差值是一個(gè)小于1的數(shù),每次反向傳遞都會(huì)乘以這個(gè)數(shù),0.9的n次方趨向于0,1.1的n次方趨向于無窮大,這就會(huì)造成梯度消失或梯度爆炸。
這也是RNN沒有恢復(fù)記憶的原因,為了解決RNN梯度下降時(shí)遇到的梯度消失或梯度爆炸問題,引入了LSTM。
4.LSTM
LSTM是在普通的RNN上面做了一些改進(jìn),LSTM RNN多了三個(gè)控制器,即輸入、輸出、忘記控制器。左邊多了個(gè)條主線,例如電影的主線劇情,而原本的RNN體系變成了分線劇情,并且三個(gè)控制器都在分線上。
輸入控制器(write gate):?在輸入input時(shí)設(shè)置一個(gè)gate,gate的作用是判斷要不要寫入這個(gè)input到我們的內(nèi)存Memory中,它相當(dāng)于一個(gè)參數(shù),也是可以被訓(xùn)練的,這個(gè)參數(shù)就是用來控制要不要記住當(dāng)下這個(gè)點(diǎn)。
輸出控制器(read gate):?在輸出位置的gate,判斷要不要讀取現(xiàn)在的Memory。
忘記控制器(forget gate):?處理位置的忘記控制器,判斷要不要忘記之前的Memory。
LSTM工作原理為:如果分線劇情對于最終結(jié)果十分重要,輸入控制器會(huì)將這個(gè)分線劇情按重要程度寫入主線劇情,再進(jìn)行分析;如果分線劇情改變了我們之前的想法,那么忘記控制器會(huì)將某些主線劇情忘記,然后按比例替換新劇情,所以主線劇情的更新就取決于輸入和忘記控制;最后的輸出會(huì)基于主線劇情和分線劇情。
通過這三個(gè)gate能夠很好地控制我們的RNN,基于這些控制機(jī)制,LSTM是延緩記憶的良藥,從而帶來更好的結(jié)果。
四.編寫LSTM神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)文本分類
這里使用的數(shù)據(jù)集為惡意請求URL和正常請求URL,它的分詞效果不像傳統(tǒng)的英文空格或中文Jieba分詞,因?yàn)閻阂庹埱笕鏢QL注入、XSS攻擊通常包括特殊的標(biāo)點(diǎn)符號(hào),因此使用N-gram分詞的效果更好。更好的數(shù)據(jù)集應(yīng)該是包含信息的流量請求信息,這里僅提供一個(gè)簡單的案例分享。
惡意請求URL檢測
目前大多數(shù)網(wǎng)站檢測方式是通過建立URL黑白名單的數(shù)據(jù)庫匹配進(jìn)行排查,雖然具有一定的檢測效果,但有一定滯后性,不能夠?qū)]有記錄在案的URL進(jìn)行識(shí)別。而基于機(jī)器學(xué)習(xí),從 URL特征、域名特征、Web特征的關(guān)聯(lián)分析,使惡意URL識(shí)別具有高準(zhǔn)確率,并具有學(xué)習(xí)推斷的能力。一些開源工具如Phinn提供了另一個(gè)角度的檢測方法,如果一個(gè)頁面看起來非常像Google的登錄頁面,那么這個(gè)頁面就應(yīng)該托管在Google域名。Phinn使用了機(jī)器學(xué)習(xí)領(lǐng)域中的卷積神經(jīng)網(wǎng)絡(luò)算法來生成和訓(xùn)練一個(gè)自定義的Chrome擴(kuò)展,這個(gè) Chrome擴(kuò)展可以將用戶瀏覽器中呈現(xiàn)的頁面與真正的登錄頁面進(jìn)行視覺相似度分析,以此來識(shí)別出惡意URL(釣魚網(wǎng)站)。
1.N-gram分詞
該部分代碼基本步驟為:
讀取隨機(jī)URL請求數(shù)據(jù)集
利用get_ngrams自定義函數(shù)實(shí)現(xiàn)n-gram分詞處理,比如 www.foo.com/1 會(huì)轉(zhuǎn)換為 [‘www’,‘ww.’,‘w.f’,’.fo’,‘foo’,‘oo.’,‘o.c’,’.co’,‘com’,‘om/’,‘m/1’] 的向量
分詞結(jié)果分別存入3個(gè)數(shù)據(jù)集,由于原始數(shù)據(jù)集的惡意樣本和正常樣本以及隨機(jī)順序,這里前10000行數(shù)據(jù)集為訓(xùn)練集,中間5000行為測試集,最后5000行為驗(yàn)證集
fenci_data.py
# coding: utf-8 import pandas as pd import jieba import time import csv from sklearn.feature_extraction.text import TfidfVectorizer #----------------------------------自定義函數(shù) N-Gram處理-------------------------------- # tokenizer function, this will make 3 grams of each query # www.foo.com/1 轉(zhuǎn)換為 ['www','ww.','w.f','.fo','foo','oo.','o.c','.co','com','om/','m/1'] def get_ngrams(query): tempQuery = str(query) ngrams = [] for i in range(0, len(tempQuery)-3+1): ngrams.append(tempQuery[i:i+3]) return ngrams #----------------------------------主函數(shù) 讀取文件及預(yù)處理------------------------------- if __name__ == '__main__': # 使用csv.DictReader讀取文件中的信息 file = "all_data_url_random.csv" with open(file, "r", encoding="UTF-8") as f: reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數(shù)據(jù)元素獲取 labels.append(row['label']) contents.append(row['content']) print(labels[:10]) print(contents[:10]) #文件寫入 #數(shù)據(jù)劃分 前10000-訓(xùn)練集 中間5000-測試集 后5000-驗(yàn)證集 ctrain = open("all_data_url_random_fenci_train.csv", "a+", newline='', encoding='gb18030') writer1 = csv.writer(ctrain) writer1.writerow(["label","fenci"]) ctest = open("all_data_url_random_fenci_test.csv", "a+", newline='', encoding='gb18030') writer2 = csv.writer(ctest) writer2.writerow(["label","fenci"]) cval = open("all_data_url_random_fenci_val.csv", "a+", newline='', encoding='gb18030') writer3 = csv.writer(cval) writer3.writerow(["label","fenci"]) n = 0 while n < len(contents): res = get_ngrams(contents[n]) #print(res) final = ' '.join(res) tlist = [] tlist.append(labels[n]) tlist.append(final) if n<10000: writer1.writerow(tlist) #訓(xùn)練集 elif n>=10000 and n<15000: writer2.writerow(tlist) #測試集 elif n>=15000: writer3.writerow(tlist) #驗(yàn)證集 n = n + 1 #文件關(guān)閉 ctrain.close() ctest.close() cval.close()
輸出結(jié)果如下圖所示,包括訓(xùn)練集、測試集和驗(yàn)證集。
2.LSTM構(gòu)建
該部分包括兩個(gè)Python文件,具體如下:
LSTM_data.py:構(gòu)建LSTM模型,實(shí)現(xiàn)惡意請求分類功能
load_pj.py:算法評價(jià)模型,自定義計(jì)算分類的Precision、Recall和F-measure
LSTM_data.py
具體任務(wù)包括六個(gè)步驟,代碼中包括詳細(xì)的注釋,如下:
第一步,讀取數(shù)據(jù)
第二步,進(jìn)行OneHotEncoder()編碼,可以采用TF-IDF、Word2Vec等方法
第三步,使用Tokenizer對詞組進(jìn)行編碼,將數(shù)據(jù)轉(zhuǎn)換為固定長度的詞序列
第四步,建立LSTM模型,模型如下圖所示
第五步,設(shè)置flag開關(guān)進(jìn)行模型訓(xùn)練和模型預(yù)測,模型評估調(diào)用 load_pj.py 實(shí)現(xiàn),通弄濕繪制熱力圖
第六步,驗(yàn)證算法進(jìn)行驗(yàn)證集的測試
# coding=utf-8 # By:Eastmount CSDN 2020-11-15 import pickle import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn import metrics from sklearn.preprocessing import LabelEncoder,OneHotEncoder from keras.models import Model from keras.layers import LSTM, Activation, Dense, Dropout, Input, Embedding from keras.optimizers import RMSprop from keras.preprocessing.text import Tokenizer from keras.preprocessing import sequence from keras.callbacks import EarlyStopping from keras.models import load_model from load_pj import classification_pj import time start = time.clock() #---------------------------------------第一步 數(shù)據(jù)讀取------------------------------------ #讀取測數(shù)據(jù)集 train_df = pd.read_csv("all_data_url_random_fenci_train.csv") val_df = pd.read_csv("all_data_url_random_fenci_val.csv") test_df = pd.read_csv("all_data_url_random_fenci_test.csv") print(train_df.head()) #解決中文顯示問題 plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默認(rèn)字體 SimHei黑體 plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負(fù)號(hào)' #---------------------------------第二步 OneHotEncoder()編碼--------------------------------- #對數(shù)據(jù)集的標(biāo)簽數(shù)據(jù)進(jìn)行編碼 train_y = train_df.label print("Label:") print(train_y[:10]) val_y = val_df.label test_y = test_df.label le = LabelEncoder() train_y = le.fit_transform(train_y).reshape(-1,1) print("LabelEncoder") print(train_y[:10]) print(len(train_y)) val_y = le.transform(val_y).reshape(-1,1) test_y = le.transform(test_y).reshape(-1,1) ## 對數(shù)據(jù)集的標(biāo)簽數(shù)據(jù)進(jìn)行one-hot編碼 ohe = OneHotEncoder() train_y = ohe.fit_transform(train_y).toarray() val_y = ohe.transform(val_y).toarray() test_y = ohe.transform(test_y).toarray() print("OneHotEncoder:") print(train_y[:10]) #-------------------------------第三步 使用Tokenizer對詞組進(jìn)行編碼------------------------------- #使用Tokenizer對詞組進(jìn)行編碼 #當(dāng)我們創(chuàng)建了一個(gè)Tokenizer對象后,使用該對象的fit_on_texts()函數(shù),以空格去識(shí)別每個(gè)詞 #可以將輸入的文本中的每個(gè)詞編號(hào),編號(hào)是根據(jù)詞頻的,詞頻越大,編號(hào)越小 max_words = 5000 max_len = 600 tok = Tokenizer(num_words=max_words) #使用的最大詞語數(shù)為5000 tok.fit_on_texts(train_df.fenci) print(tok) #保存訓(xùn)練好的Tokenizer和導(dǎo)入 with open('tok.pickle', 'wb') as handle: pickle.dump(tok, handle, protocol=pickle.HIGHEST_PROTOCOL) # loading with open('tok.pickle', 'rb') as handle: tok = pickle.load(handle) #使用word_index屬性可以看到每次詞對應(yīng)的編碼 #使用word_counts屬性可以看到每個(gè)詞對應(yīng)的頻數(shù) for ii,iterm in enumerate(tok.word_index.items()): if ii < 10: print(iterm) else: break print("===================") for ii,iterm in enumerate(tok.word_counts.items()): if ii < 10: print(iterm) else: break #使用tok.texts_to_sequences()將數(shù)據(jù)轉(zhuǎn)化為序列 #使用sequence.pad_sequences()將每個(gè)序列調(diào)整為相同的長度 #對每個(gè)詞編碼之后,每句語料中的每個(gè)詞就可以用對應(yīng)的編碼表示,即每條語料可以轉(zhuǎn)變成一個(gè)向量了 train_seq = tok.texts_to_sequences(train_df.fenci) val_seq = tok.texts_to_sequences(val_df.fenci) test_seq = tok.texts_to_sequences(test_df.fenci) #將每個(gè)序列調(diào)整為相同的長度 train_seq_mat = sequence.pad_sequences(train_seq,maxlen=max_len) val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len) test_seq_mat = sequence.pad_sequences(test_seq,maxlen=max_len) print(train_seq_mat.shape) #(10000, 600) print(val_seq_mat.shape) #(5000, 600) print(test_seq_mat.shape) #(5000, 600) print(train_seq_mat[:2]) #-------------------------------第四步 建立LSTM模型并訓(xùn)練------------------------------- ## 定義LSTM模型 inputs = Input(name='inputs',shape=[max_len]) ## Embedding(詞匯表大小,batch大小,每個(gè)新聞的詞長) layer = Embedding(max_words+1, 128, input_length=max_len)(inputs) layer = LSTM(128)(layer) layer = Dense(128, activation="relu", name="FC1")(layer) layer = Dropout(0.3)(layer) layer = Dense(2, activation="softmax", name="FC2")(layer) model = Model(inputs=inputs, outputs=layer) model.summary() model.compile(loss="categorical_crossentropy", optimizer=RMSprop(), metrics=["accuracy"]) # 增加判斷 防止再次訓(xùn)練 flag = "train" if flag == "train": print("模型訓(xùn)練") #模型訓(xùn)練 model_fit = model.fit(train_seq_mat, train_y, batch_size=128, epochs=10, validation_data=(val_seq_mat,val_y), callbacks=[EarlyStopping(monitor='val_loss',min_delta=0.0001)] #當(dāng)val-loss不再提升時(shí)停止訓(xùn)練 ) #保存模型 model.save('my_model.h5') del model # deletes the existing model #計(jì)算時(shí)間 elapsed = (time.clock() - start) print("Time used:", elapsed) else: print("模型預(yù)測") # 導(dǎo)入已經(jīng)訓(xùn)練好的模型 model = load_model('my_model.h5') #--------------------------------------第五步 預(yù)測及評估-------------------------------- #對測試集進(jìn)行預(yù)測 test_pre = model.predict(test_seq_mat) #評價(jià)預(yù)測效果,計(jì)算混淆矩陣 參數(shù)順序 confm = metrics.confusion_matrix(np.argmax(test_y,axis=1),np.argmax(test_pre,axis=1)) print(confm) #混淆矩陣可視化 Labname = ['正常', '異常'] print(metrics.classification_report(np.argmax(test_y,axis=1),np.argmax(test_pre,axis=1))) classification_pj(np.argmax(test_pre,axis=1),np.argmax(test_y,axis=1)) plt.figure(figsize=(8,8)) sns.heatmap(confm.T, square=True, annot=True, fmt='d', cbar=False, linewidths=.6, cmap="YlGnBu") plt.xlabel('True label',size = 14) plt.ylabel('Predicted label', size = 14) plt.xticks(np.arange(2)+0.8, Labname, size = 12) plt.yticks(np.arange(2)+0.4, Labname, size = 12) plt.show() #--------------------------------------第六步 驗(yàn)證算法-------------------------------- #使用tok對驗(yàn)證數(shù)據(jù)集重新預(yù)處理,并使用訓(xùn)練好的模型進(jìn)行預(yù)測 val_seq = tok.texts_to_sequences(val_df.fenci) #將每個(gè)序列調(diào)整為相同的長度 val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len) #對驗(yàn)證集進(jìn)行預(yù)測 val_pre = model.predict(val_seq_mat) print(metrics.classification_report(np.argmax(val_y,axis=1),np.argmax(val_pre,axis=1))) classification_pj(np.argmax(val_pre,axis=1),np.argmax(val_y,axis=1)) #計(jì)算時(shí)間 elapsed = (time.clock() - start) print("Time used:", elapsed)
輸出的部分結(jié)果如下圖所示:
label fenci 0 異常 /.. ../ ./. /.s .sl sln 1 異常 /fc fc9 c9t 9t5 t54 54l 4l7 l7. 7.c .cf cfm fm... 2 正常 /10 108 085 856 569 69_ 9_m _mi mis iss ssi si... 3 異常 /sc scr cri rip ipt pts ts/ s/f /fo for oru ru... 4 正常 /ro row ow2 w2_ 2_j _jo joi oin int nt/ LabelEncoder [[0] [0] [1] [0] [1] [1] [1] [1] [1] [0]] 10000 OneHotEncoder: [[1. 0.] [1. 0.] [0. 1.] [1. 0.] [0. 1.] [0. 1.] [0. 1.] [0. 1.] [0. 1.] [1. 0.]]
訓(xùn)練過程如下所示:
Train on 10000 samples, validate on 5000 samples Epoch 1/10 10000/10000 [==============================] - 250s 25ms/step - loss: 0.2590 - accuracy: 0.9102 - val_loss: 0.1295 - val_accuracy: 0.9626 Epoch 2/10 10000/10000 [==============================] - 248s 25ms/step - loss: 0.1783 - accuracy: 0.9616 - val_loss: 0.1642 - val_accuracy: 0.9366 Time used: 502.5310856
3.實(shí)驗(yàn)評估
當(dāng)實(shí)驗(yàn)訓(xùn)練結(jié)束后,將flag變量設(shè)置為“test”進(jìn)行測試,評估代碼如下:
# -*- coding: utf-8 -*- """ author: Eastmount CSDN 2020-11-15 """ import os #評價(jià)指標(biāo) 參數(shù)順序 def classification_pj(pre, y_test): # 正確率 Precision = 正確識(shí)別的個(gè)體總數(shù) /識(shí)別出的個(gè)體總數(shù) # 召回率 Recall = 正確識(shí)別的個(gè)體總數(shù) / 測試集中存在的個(gè)體總數(shù) # F值 F-measure = 正確率 * 召回率 * 2 / (正確率 + 召回率) YC_A, YC_B = 0,0 #預(yù)測 bad good ZQ_A, ZQ_B = 0,0 #正確 CZ_A, CZ_B = 0,0 #存在 #0-good 1-bad 同時(shí)計(jì)算防止類標(biāo)變化 i = 0 while i 輸出結(jié)果如下圖所示: F值為0.9488 P值為0.9533 R值為0.9450 模型預(yù)測 [[1758 164] [ 76 3002]] precision recall f1-score support 0 0.96 0.91 0.94 1922 1 0.95 0.98 0.96 3078 accuracy 0.95 5000 macro avg 0.95 0.94 0.95 5000 weighted avg 0.95 0.95 0.95 5000 1834 3166 1758 3002 1922 3078 Precision 0:0.9585 Precision 1:0.9482 Avg_precision:0.9533 Recall 0:0.9146 Recall 1:0.9753 Avg_recall:0.9450 F-measure 0:0.9361 F-measure 1:0.9615 Avg_fmeasure:0.9488 F值為0.93 注意:大家可以直接在易學(xué)智能平臺(tái)的PyCharm運(yùn)行代碼,也可以在自己搭建的環(huán)境運(yùn)行。 如果是GPU環(huán)境需要增加一些核心代碼: ailed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED failed to allocate 9.90G (10630043904 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY: out of memory 增加下面代碼: import os os.environ["CUDA_DEVICES_ORDER"] = "PCI_BUS_IS" os.environ["CUDA_VISIBLE_DEVICES"] = "0" #指定了每個(gè)GPU進(jìn)程中使用顯存的上限,0.9表示可以使用GPU 90%的資源進(jìn)行訓(xùn)練 gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.9) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) """ #TensorFlow2.0 gpus = tf.config.experimental.list_physical_devices('GPU') for gpu in gpus: tf.config.experimental.set_memory_growth(gpu,True) """ 五.總結(jié) 寫到這里,這篇文章就結(jié)束了,下一篇文章比較硬核,直接撰寫代碼詳細(xì)對比CNN、LSTM、BiLSTM和BiLSTM+Attention文本分類實(shí)驗(yàn)。希望對您有所幫助,同時(shí)文章中不足或錯(cuò)誤的地方,歡迎讀者提出。這些實(shí)驗(yàn)都是我在做論文研究或項(xiàng)目評價(jià)常見的一些問題,希望讀者帶著這些問題,結(jié)合自己的需求進(jìn)行深入的思考,更希望大家能學(xué)以致用。最后如果文章對您有幫助,請、評論、,這將是我分享最大的動(dòng)力。github下載代碼,記得關(guān)注喔! https://github.com/eastmountyxz/AI-for-Keras 最后,作為人工智能的菜鳥,我希望自己能不斷進(jìn)步并深入,后續(xù)將它應(yīng)用于圖像識(shí)別、網(wǎng)絡(luò)安全、對抗樣本等領(lǐng)域,指導(dǎo)大家撰寫簡單的學(xué)術(shù)論文,一起加油!感謝這些年遇到很多以前進(jìn)步的博友,共勉~ 2022年第一篇,感恩能與大家在華為云遇見! 希望能與大家一起在華為云社區(qū)共同成長。原文地址:https://blog.csdn.net/Eastmount/article/details/109697350 (By:娜璋之家 Eastmount 2022-01-07 夜于武漢) GPU加速云服務(wù)器 Keras Python 深度學(xué)習(xí)
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。