最近用笔记本跑Keras和TensorFlow深度学习代码,一个模型跑十几个小时还奔溃,真的头大!这篇文章简单讲解易学智能GPU搭建Keras环境的过程,并实现了LSTM文本分类的实验,本来想写Google Colab免费云,但看知乎评价也不太好(梯子常断网、时间限制、数据量小)。因此,选择一个评价较好的平台供大家学习(6块一小时),也希望大家推荐更好的平台,百度飞浆后续准备也学习下,希望这篇文章能解决自身电脑配置不足,需要GPU运行模型且服务器价格又不是太高的同学,加油!
- 如果个人电脑足够使用的同学,则可以看看这篇文章的LSTM文本分类代码,下一篇文章我将详细对比。基础性文章,希望对您有所帮助。
本专栏主要结合作者之前的博客、AI经验和相关视频及论文介绍,后面随着深入会讲解更多的Python人工智能案例及应用。基础性文章,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作者作为人工智能的菜鸟,希望大家能与我在这一笔一划的博客中成长起来。写了这么多年博客,尝试第一个付费专栏,但更多博客尤其基础性文章,还是会继续免费分享,但该专栏也会用心撰写,望对得起读者,共勉!
- Keras下载地址:https://github.com/eastmountyxz/AI-for-Keras
- TensorFlow下载地址:https://github.com/eastmountyxz/AI-for-TensorFlow
文章目录
同时推荐前面作者另外五个Python系列文章。从2014年开始,作者主要写了三个Python系列文章,分别是基础知识、网络爬虫和数据分析。2018年陆续增加了Python图像识别和Python人工智能专栏。
- Python基础知识系列:Python基础知识学习与提升
- Python网络爬虫系列:Python爬虫之Selenium+BeautifulSoup+Requests
- Python数据分析系列:知识图谱、web数据挖掘及NLP
- Python图像识别系列:Python图像处理及图像识别
- Python人工智能系列:Python人工智能及知识图谱实战
前文:
[Python人工智能] 一.TensorFlow2.0环境搭建及神经网络入门
[Python人工智能] 二.TensorFlow基础及一元直线预测案例
[Python人工智能] 三.TensorFlow基础之Session、变量、传入值和激励函数
[Python人工智能] 四.TensorFlow创建回归神经网络及Optimizer优化器
[Python人工智能] 五.Tensorboard可视化基本用法及绘制整个神经网络
[Python人工智能] 六.TensorFlow实现分类学习及MNIST手写体识别案例
[Python人工智能] 七.什么是过拟合及dropout解决神经网络中的过拟合问题
[Python人工智能] 八.卷积神经网络CNN原理详解及TensorFlow编写CNN
[Python人工智能] 九.gensim词向量Word2Vec安装及《庆余年》中文短文本相似度计算
[Python人工智能] 十.Tensorflow+Opencv实现CNN自定义图像分类案例及与机器学习KNN图像分类算法对比
[Python人工智能] 十一.Tensorflow如何保存神经网络参数
[Python人工智能] 十二.循环神经网络RNN和LSTM原理详解及TensorFlow编写RNN分类案例
[Python人工智能] 十三.如何评价神经网络、loss曲线图绘制、图像分类案例的F值计算
[Python人工智能] 十四.循环神经网络LSTM RNN回归案例之sin曲线预测
[Python人工智能] 十五.无监督学习Autoencoder原理及聚类可视化案例详解
[Python人工智能] 十六.Keras环境搭建、入门基础及回归神经网络案例
[Python人工智能] 十七.Keras搭建分类神经网络及MNIST数字图像案例分析
[Python人工智能] 十八.Keras搭建卷积神经网络及CNN原理详解
[Python人工智能] 十九.Keras搭建循环神经网络分类案例及RNN原理详解
[Python人工智能] 二十.基于Keras+RNN的文本分类vs基于传统机器学习的文本分类
[Python人工智能] 二十一.Word2Vec+CNN中文文本分类详解及与机器学习(RF\DTC\SVM\KNN\NB\LR)分类对比
[Python人工智能] 二十二.基于大连理工情感词典的情感分析和情绪计算
[Python人工智能] 二十三.基于机器学习和TFIDF的情感分类(含详细的NLP数据清洗)
《人工智能狂潮》读后感——什么是人工智能?(一)
一.搭建易学智能GPU平台
第一步,注册登录后,选择“控制台”->“新建主机”。
第二步,选择主机环境。
读者可以根据代码编写习惯选择,作者习惯Windows操作系统、选择gtx 1080tiGPU、开发环境为Python3.6、pytorch1.0和tf1.12。由于作者代码TensorFlow版本较低,读者可以选择TensorFlow2.0。
点击“结算开机”会提示相关内容,如下图所示。
点击“确认开机”后支付金额并初始化。
第三步,下载远程连接配置文件:控制台->我的主机->远程连接信息,点击下载。
接着点击“下载Windows远程桌面配置文件”按钮,下图是官方提供的,大家写文章时也需要避免个人服务器账号泄露喔!
- 账号
- 密码
- IP地址
- 端口
第四步,远程连接。双击windows_connect.rdp,输入密码。
输入密码登录即可。
登录成功后进入Windows远程界面。
桌面如下图所示,运行代码的主要方式有命令行、Jupyter、PyCharm、Spyder等。
- 命令行,运行代码前请激活conda环境
- Windows使用Jupyter
- 使用PyCharm:在PyCharm中配置python解释器
- 使用Spyder:在Spyder中配置与使用python解释器
第五步,点击关机后停止计费,一定要点击“关机”按钮,切记。同时下次开机我们可以选择新的服务器型号和系统。
关机注意事项如下:
至此这个易学智能的服务云环境就介绍结束,下面我们开始讲解Python和深度学习的配置过程。
二.易学智能运行Python代码
第一步,激活Conda环境。
打开conda prompt(桌面有快捷方式),激活Conda环境。以使用py36h为例,打开anaconda prompt命令行,输入:
- activate py36h或conda activate py36h
第二步,直接打开Python3.7 IDLE编写代码即可。
pip list可以查看已经配置的扩展包,注意TensorFlow安装的是GPU版本。
TensorFlow框架如下图所示:
第三步,输入jupyter notebook打开Jupyter Notebook,如下图所示。
输入pip install pkg或conda install pkg可以安装扩展包。
第四步,利用Spyder编写代码。
首次打开需要初始化一段时间,接着运行结果如下图所示。
选择安装的环境“py36h”,然后安装Spyder,利用这个编写Python代码。
或者在终端中输入“spyer”打开。
同样读者可以直接使用PyCharm编写Python代码,它的常用扩展包也被成功安装了。
下列代码可以查看软件版本信息:
import tensorflow as tf
print(tf.__version__)
import torch as th
print(th.__version__)
import keras
print(keras.__version__)
输出结果如下图所示:
第五步,查看环境是否为GPU版本。
以tensorflow为例,运行下面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())
输出结果如下图所示,我们可以使用 “/device:CPU:0”,"/device:GPU:0"。
当作者在命令行中运行时,看到日志是GPU运行代码。
同样补充另一种设置设备的方式,核心代码如下所示:
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))
第六步,下面简单运行Pyhton机器学习代码,这里作者选择之前的博客鸢尾花线性回归代码。
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()
运行结果如下图所示:
第八步,代码文件上传。
你可能会想远程代码是不是需要发送到百度网盘或github,再下载运行,其实易学智能提供了一个上传文件的功能。界面如下图所示:
上传代码如下图所示,保存至“M盘/MyFiles”路径。
参考文献:
- http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/using_gpu.html
- https://blog.csdn.net/qq_34022601/article/details/90449789
三.LSTM基础知识
在介绍LSTM模型之前,先分享循环神经网络知识。
1.RNN原理
循环神经网络英文是Recurrent Neural Networks,简称RNN。假设有一组数据data0、data1、data2、data3,使用同一个神经网络预测它们,得到对应的结果。如果数据之间是有关系的,比如做菜下料的前后步骤,英文单词的顺序,如何让数据之间的关联也被神经网络学习呢?这就要用到——RNN。
假设存在ABCD数字,需要预测下一个数字E,会根据前面ABCD顺序进行预测,这就称为记忆。预测之前,需要回顾以前的记忆有哪些,再加上这一步新的记忆点,最终输出output,循环神经网络(RNN)就利用了这样的原理。
首先,让我们想想人类是怎么分析事物之间的关联或顺序的。人类通常记住之前发生的事情,从而帮助我们后续的行为判断,那么是否能让计算机也记住之前发生的事情呢?
在分析data0时,我们把分析结果存入记忆Memory中,然后当分析data1时,神经网络(NN)会产生新的记忆,但此时新的记忆和老的记忆没有关联,如上图所示。在RNN中,我们会简单的把老记忆调用过来分析新记忆,如果继续分析更多的数据时,NN就会把之前的记忆全部累积起来。
RNN结构如下图所示,按照时间点t-1、t、t+1,每个时刻有不同的x,每次计算会考虑上一步的state和这一步的x(t),再输出y值。在该数学形式中,每次RNN运行完之后都会产生s(t),当RNN要分析x(t+1)时,此刻的y(t+1)是由s(t)和s(t+1)共同创造的,s(t)可看作上一步的记忆。多个神经网络NN的累积就转换成了循环神经网络,其简化图如下图的左边所示。
总之,只要你的数据是有顺序的,就可以使用RNN,比如人类说话的顺序,电话号码的顺序,图像像素排列的顺序,ABC字母的顺序等。在前面讲解CNN原理时,它可以看做是一个滤波器滑动扫描整幅图像,通过卷积加深神经网络对图像的理解。
而RNN也有同样的扫描效果,只不过是增加了时间顺序和记忆功能。RNN通过隐藏层周期性的连接,从而捕获序列化数据中的动态信息,提升预测结果。
2.RNN应用
RNN常用于自然语言处理、机器翻译、语音识别、图像识别等领域,下面简单分享RNN相关应用所对应的结构。
RNN情感分析: 当分析一个人说话情感是积极的还是消极的,就用如下图所示的RNN结构,它有N个输入,1个输出,最后时间点的Y值代表最终的输出结果。
RNN图像识别: 此时有一张图片输入X,N张对应的输出。
RNN机器翻译: 输入和输出分别两个,对应的是中文和英文,如下图所示。
3.为什么引入LSTM
RNN是在有序的数据上进行学习的,RNN会像人一样对先前的数据发生记忆,但有时候也会像老爷爷一样忘记先前所说。为了解决RNN的这个弊端,提出了LTSM技术,它的英文全称是Long short-term memory,长短期记忆,也是当下最流行的RNN之一。
假设现在有一句话,如下图所示,RNN判断这句话是红烧排骨,这时需要学习,而“红烧排骨“在句子开头。
"红烧排骨"这个词需要经过长途跋涉才能抵达,要经过一系列得到误差,然后经过反向传递,它在每一步都会乘以一个权重w参数。如果乘以的权重是小于1的数,比如0.9,0.9会不断地乘以误差,最终这个值传递到初始值时,误差就消失了,这称为梯度消失或梯度离散。
反之,如果误差是一个很大的数,比如1.1,则这个RNN得到的值会很大,这称为梯度爆炸。
梯度消失或梯度爆炸:
在RNN中,如果你的State是一个很长的序列,假设反向传递的误差值是一个小于1的数,每次反向传递都会乘以这个数,0.9的n次方趋向于0,1.1的n次方趋向于无穷大,这就会造成梯度消失或梯度爆炸。
这也是RNN没有恢复记忆的原因,为了解决RNN梯度下降时遇到的梯度消失或梯度爆炸问题,引入了LSTM。
4.LSTM
LSTM是在普通的RNN上面做了一些改进,LSTM RNN多了三个控制器,即输入、输出、忘记控制器。左边多了个条主线,例如电影的主线剧情,而原本的RNN体系变成了分线剧情,并且三个控制器都在分线上。
- 输入控制器(write gate): 在输入input时设置一个gate,gate的作用是判断要不要写入这个input到我们的内存Memory中,它相当于一个参数,也是可以被训练的,这个参数就是用来控制要不要记住当下这个点。
- 输出控制器(read gate): 在输出位置的gate,判断要不要读取现在的Memory。
- 忘记控制器(forget gate): 处理位置的忘记控制器,判断要不要忘记之前的Memory。
LSTM工作原理为:如果分线剧情对于最终结果十分重要,输入控制器会将这个分线剧情按重要程度写入主线剧情,再进行分析;如果分线剧情改变了我们之前的想法,那么忘记控制器会将某些主线剧情忘记,然后按比例替换新剧情,所以主线剧情的更新就取决于输入和忘记控制;最后的输出会基于主线剧情和分线剧情。
通过这三个gate能够很好地控制我们的RNN,基于这些控制机制,LSTM是延缓记忆的良药,从而带来更好的结果。
四.编写LSTM神经网络实现文本分类
这里使用的数据集为恶意请求URL和正常请求URL,它的分词效果不像传统的英文空格或中文Jieba分词,因为恶意请求如SQL注入、XSS攻击通常包括特殊的标点符号,因此使用N-gram分词的效果更好。更好的数据集应该是包含信息的流量请求信息,这里仅提供一个简单的案例分享。
恶意请求URL检测
目前大多数网站检测方式是通过建立URL黑白名单的数据库匹配进行排查,虽然具有一定的检测效果,但有一定滞后性,不能够对没有记录在案的URL进行识别。而基于机器学习,从 URL特征、域名特征、Web特征的关联分析,使恶意URL识别具有高准确率,并具有学习推断的能力。一些开源工具如Phinn提供了另一个角度的检测方法,如果一个页面看起来非常像Google的登录页面,那么这个页面就应该托管在Google域名。Phinn使用了机器学习领域中的卷积神经网络算法来生成和训练一个自定义的Chrome扩展,这个 Chrome扩展可以将用户浏览器中呈现的页面与真正的登录页面进行视觉相似度分析,以此来识别出恶意URL(钓鱼网站)。
1.N-gram分词
该部分代码基本步骤为:
- 读取随机URL请求数据集
- 利用get_ngrams自定义函数实现n-gram分词处理,比如 www.foo.com/1 会转换为 [‘www’,‘ww.’,‘w.f’,’.fo’,‘foo’,‘oo.’,‘o.c’,’.co’,‘com’,‘om/’,‘m/1’] 的向量
- 分词结果分别存入3个数据集,由于原始数据集的恶意样本和正常样本以及随机顺序,这里前10000行数据集为训练集,中间5000行为测试集,最后5000行为验证集
fenci_data.py
# coding: utf-8
import pandas as pd
import jieba
import time
import csv
from sklearn.feature_extraction.text import TfidfVectorizer
#----------------------------------自定义函数 N-Gram处理--------------------------------
# tokenizer function, this will make 3 grams of each query
# www.foo.com/1 转换为 ['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
#----------------------------------主函数 读取文件及预处理-------------------------------
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:
# 数据元素获取
labels.append(row['label'])
contents.append(row['content'])
print(labels[:10])
print(contents[:10])
#文件写入
#数据划分 前10000-训练集 中间5000-测试集 后5000-验证集
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) #训练集
elif n>=10000 and n<15000:
writer2.writerow(tlist) #测试集
elif n>=15000:
writer3.writerow(tlist) #验证集
n = n + 1
#文件关闭
ctrain.close()
ctest.close()
cval.close()
输出结果如下图所示,包括训练集、测试集和验证集。
2.LSTM构建
该部分包括两个Python文件,具体如下:
- LSTM_data.py:构建LSTM模型,实现恶意请求分类功能
- load_pj.py:算法评价模型,自定义计算分类的Precision、Recall和F-measure
LSTM_data.py
具体任务包括六个步骤,代码中包括详细的注释,如下:
- 第一步,读取数据
- 第二步,进行OneHotEncoder()编码,可以采用TF-IDF、Word2Vec等方法
- 第三步,使用Tokenizer对词组进行编码,将数据转换为固定长度的词序列
- 第四步,建立LSTM模型,模型如下图所示
- 第五步,设置flag开关进行模型训练和模型预测,模型评估调用 load_pj.py 实现,通弄湿绘制热力图
- 第六步,验证算法进行验证集的测试
# 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()
#---------------------------------------第一步 数据读取------------------------------------
#读取测数据集
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'] # 指定默认字体 SimHei黑体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'
#---------------------------------第二步 OneHotEncoder()编码---------------------------------
#对数据集的标签数据进行编码
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)
## 对数据集的标签数据进行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对词组进行编码-------------------------------
#使用Tokenizer对词组进行编码
#当我们创建了一个Tokenizer对象后,使用该对象的fit_on_texts()函数,以空格去识别每个词
#可以将输入的文本中的每个词编号,编号是根据词频的,词频越大,编号越小
max_words = 5000
max_len = 600
tok = Tokenizer(num_words=max_words) #使用的最大词语数为5000
tok.fit_on_texts(train_df.fenci)
print(tok)
#保存训练好的Tokenizer和导入
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属性可以看到每次词对应的编码
#使用word_counts属性可以看到每个词对应的频数
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()将数据转化为序列
#使用sequence.pad_sequences()将每个序列调整为相同的长度
#对每个词编码之后,每句语料中的每个词就可以用对应的编码表示,即每条语料可以转变成一个向量了
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)
#将每个序列调整为相同的长度
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模型并训练-------------------------------
## 定义LSTM模型
inputs = Input(name='inputs',shape=[max_len])
## Embedding(词汇表大小,batch大小,每个新闻的词长)
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"])
# 增加判断 防止再次训练
flag = "train"
if flag == "train":
print("模型训练")
#模型训练
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)] #当val-loss不再提升时停止训练
)
#保存模型
model.save('my_model.h5')
del model # deletes the existing model
#计算时间
elapsed = (time.clock() - start)
print("Time used:", elapsed)
else:
print("模型预测")
# 导入已经训练好的模型
model = load_model('my_model.h5')
#--------------------------------------第五步 预测及评估--------------------------------
#对测试集进行预测
test_pre = model.predict(test_seq_mat)
#评价预测效果,计算混淆矩阵
confm = metrics.confusion_matrix(np.argmax(test_pre,axis=1),np.argmax(test_y,axis=1))
print(confm)
#混淆矩阵可视化
Labname = ['正常', '异常']
print(metrics.classification_report(np.argmax(test_pre,axis=1),np.argmax(test_y,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()
#--------------------------------------第六步 验证算法--------------------------------
#使用tok对验证数据集重新预处理,并使用训练好的模型进行预测
val_seq = tok.texts_to_sequences(val_df.fenci)
#将每个序列调整为相同的长度
val_seq_mat = sequence.pad_sequences(val_seq,maxlen=max_len)
#对验证集进行预测
val_pre = model.predict(val_seq_mat)
print(metrics.classification_report(np.argmax(val_pre,axis=1),np.argmax(val_y,axis=1)))
classification_pj(np.argmax(val_pre,axis=1),np.argmax(val_y,axis=1))
#计算时间
elapsed = (time.clock() - start)
print("Time used:", elapsed)
输出的部分结果如下图所示:
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.]]
<keras_preprocessing.text.Tokenizer object at 0x00000208C5644C50>
('s', 7660)
('sl', 362)
('sln', 1)
('fc', 53)
('fc9', 4)
('c9t', 2)
('9t5', 2)
('t54', 3)
('54l', 2)
('4l7', 8)
(10000, 600)
(5000, 600)
(5000, 600)
[[ 0 0 0 ... 0 4 199]
[ 0 0 0 ... 17 19 24]]
训练过程如下所示:
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.实验评估
当实验训练结束后,将flag变量设置为“test”进行测试,评估代码如下:
# -*- coding: utf-8 -*-
"""
author: Eastmount CSDN 2020-11-15
"""
import os
#评价指标
def classification_pj(y_test, pre):
# 正确率 Precision = 正确识别的个体总数 /识别出的个体总数
# 召回率 Recall = 正确识别的个体总数 / 测试集中存在的个体总数
# F值 F-measure = 正确率 * 召回率 * 2 / (正确率 + 召回率)
YC_A, YC_B = 0,0 #预测 bad good
ZQ_A, ZQ_B = 0,0 #正确
CZ_A, CZ_B = 0,0 #存在
#0-good 1-bad 同时计算防止类标变化
i = 0
while i<len(pre):
z = int(y_test[i]) #真实
y = int(pre[i]) #预测
if z==0:
CZ_A += 1
elif z==1:
CZ_B += 1
if y==0:
YC_A += 1
elif y==1:
YC_B += 1
if z==y and z==0 and y==0:
ZQ_A += 1
elif z==y and z==1 and y==1:
ZQ_B += 1
i = i + 1
# 结果输出
print(YC_A, YC_B, ZQ_A, ZQ_B,CZ_A, CZ_B)
P_A = ZQ_A * 1.0 / (YC_A + 0.1)
P_B = ZQ_B * 1.0 / (YC_B + 0.1)
print("Precision 0:{:.4f}".format(P_A))
print("Precision 1:{:.4f}".format(P_B))
print("Avg_precision:{:.4f}".format((P_A + P_B)/2))
R_A = ZQ_A * 1.0 / (CZ_A + 0.1)
R_B = ZQ_B * 1.0 / (CZ_B + 0.1)
print("Recall 0:{:.4f}".format(R_A))
print("Recall 1:{:.4f}".format(R_B))
print("Avg_recall:{:.4f}".format((R_A + R_B)/2))
F_A = 2 * P_A * R_A / (P_A + R_A)
F_B = 2 * P_B * R_B / (P_B + R_B)
print("F-measure 0:{:.4f}".format(F_A))
print("F-measure 1:{:.4f}".format(F_B))
print("Avg_fmeasure:{:.4f}".format((F_A + F_B)/2))
print("")
输出结果如下图所示:
- F值为0.9488
- P值为0.9533
- R值为0.9450
模型预测
[[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
注意:大家可以直接在易学智能平台的PyCharm运行代码,也可以在自己搭建的环境运行。
如果是GPU环境需要增加一些核心代码:
- 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"
#指定了每个GPU进程中使用显存的上限,0.9表示可以使用GPU 90%的资源进行训练
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)
"""
五.总结
写到这里,这篇文章就结束了,下一篇文章比较硬核,直接撰写代码详细对比CNN、LSTM、BiLSTM和BiLSTM+Attention文本分类实验。希望对您有所帮助,同时文章中不足或错误的地方,欢迎读者提出。这些实验都是我在做论文研究或项目评价常见的一些问题,希望读者带着这些问题,结合自己的需求进行深入的思考,更希望大家能学以致用。最后如果文章对您有帮助,请点赞、评论、收藏,这将是我分享最大的动力。github下载代码,记得关注点赞喔!
最后,作为人工智能的菜鸟,我希望自己能不断进步并深入,后续将它应用于图像识别、网络安全、对抗样本等领域,指导大家撰写简单的学术论文,一起加油!感谢这些年遇到很多以前进步的博友,共勉~
2020年8月18新开的“娜璋AI安全之家”,主要围绕Python大数据分析、网络空间安全、人工智能、Web渗透及攻防技术进行讲解,同时分享CCF、SCI、南核北核论文的算法实现。娜璋之家会更加系统,并重构作者的所有文章,从零讲解Python和安全,写了近十年文章,真心想把自己所学所感所做分享出来,还请各位多多指教,真诚邀请您的关注!谢谢。
(By:Eastmount 2020-11-15 周日夜于武汉 http://blog.csdn.net/eastmount/ )
来源:oschina
链接:https://my.oschina.net/u/4356413/blog/4720878