也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大
少走了弯路,也就错过了风景,无论如何,感谢经历
更多关于Android安全的知识,可前往:https://blog.csdn.net/ananasorangey/category11955914.html
本篇文章转载自公众号[娜璋AI安全之家]
前一篇文章详细讲解了循环神经网络RNN和长短期记忆网络LSTM的原理知识,并采用TensorFlow实现手写数字识别的RNN分类案例。本文将分享如何评价神经网络,绘制训练过程中的loss曲线,并结合图像分类案例讲解精确率、召回率和F值的计算过程。本文可以指导您撰写简单的深度学习论文,希望对您有所帮助。
本专栏主要结合作者之前的博客、AI经验、莫烦老师的视频学习心得和相关文章及论文介绍,后面随着深入会讲解更多的Python人工智能案例及应用。基础性文章,希望对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作者作为人工智能的菜鸟,希望大家能与我在这一笔一划的博客中成长起来,该专栏作者会用心撰写,望对得起读者,共勉!
文章目录:
一. 神经网络评价指标二.图像分类loss曲线绘制1.数据集介绍2.训练过程3.绘制loss和accuracy曲线三.图像分类准确率、召回率、F值计算1.预测2.计算四.总结代码下载地址(欢迎大家关注点赞):
https://github.com/eastmountyxz/AI-for-TensorFlowhttps://github.com/eastmountyxz/AI-for-Keras学Python近八年,认识了很多大佬和朋友,感恩。作者的本意是帮助更多初学者入门,因此在github开源了所有代码,也在公众号同步更新。深知自己很菜,得拼命努力前行,编程也没有什么捷径,干就对了。希望未来能更透彻学习和撰写文章,也能在读博几年里学会真正的独立科研。同时非常感谢参考文献中的大佬们的文章和分享。
- https://blog.csdn.net/eastmount
一. 神经网络评价指标
由于各种问题影响,会导致神经网络的学习效率不高,或者干扰因素太多导致分析结果不理想。这些因素可能是数据问题、学习参数问题、算法效率问题等。
那么,如何评价(Evaluate)神经网络呢?我们可以通过一些指标对神经网络进行评价,通过评价来改进神经网络。评价神经网络的方法和评价机器学习的方法大同小异,常见的包括误差、准确率、R2 score、F值等。
1.误差(Error)
先用误差评价神经网络,如下图所示,随着训练时间增长,预测误差会不断减小,得到更为准确的答案,最后误差会趋近于水平。
2.正确率(Accuracy)
正确率(精准度)是指预测正确结果与真实结果的比例,接近100%是最好的结果。例如,分类神经网络100个样本中有90个分类正确,则其预测正确率为90%。
正确率对应的是误检率(false positve),假设100个样本中误捡个数为10,则误检率10%(10/100)。
3.准确率、召回率和F值在机器学习和深度学习中,经常会用到准确率、召回率和F值评价算法。
上图为一个二分类的混淆矩阵(多分类同理,只需要把不属于当前类的其他类都考虑为负例),表格中的四个参数说明:
True Positive(TP):正确预测出的正样本个数(预测为正例,实际为正例)False Positive(FP):错误预测出的正样本个数(本来是负样本,被预测成正样本)True Negative(TN):正确预测出的负样本个数(预测为负例,实际为负例)False Negative(FN):错误预测出的负样本个数(本来是正样本,被预测成负样本)其中,TP和TN都是预测正确,FP和FN都是预测错误。
正确率(accuracy):它是最常见的评价指标,正确预测的样本数占总预测样本数的比值,它不考虑预测的样本是正例还是负例。
错误率(error rate):又称为误检率,错误率则与正确率相反,描述被分类器错分的比例。对某一个实例来说,分对与分错是互斥事件,所以 accuracy = 1 - error rate。
准确率(precision):准确率是精确性的度量,表示正确预测的正样本数占所有预测为正样本的数量的比值,也就是说所有预测为正样本的样本中有多少是真正的正样本。注意,precision只关注预测为正样本的部分,而accuracy考虑全部样本。
召回率(recall):又称为查全率,是覆盖面的度量,表示正确预测的正样本数占真实正样本总数的比值,也就是能从这些样本中能够正确找出多少个正样本。
F值(F-score):有时候precision和recall指标会存在矛盾的现象,此时就需要调用F-score或F-measure指标,它是precision和recall的调和平均值,能够均衡的评价算法。在公式中,precision和recall任何一个数值减小,F-score都会减小;反之亦然。
灵敏度(sensitive):表示所有正例中被分对的比例,衡量了分类器对正例的识别能力。
特效度(specificity):表示所有负例中被分对的比例,衡量了分类器对负例的识别能力。
ROC和AUC是评价分类器的指标,这部分后续文章作深入分享。
4.R2 Score
前面讲解了分类和聚类问题的评价,那如果是回归问题呢?又如何评价连续值的精准度呢?这里我们使用MSE、MAE、R2 Score等值来衡量。其基本思想是:测试数据集中的点,距离模型的平均距离越小,该模型越精确。
在评价回归模型时,sklearn中提供了四种评价尺度,分别为mean_squared_error、mean_absolute_error、explained_variance_score 和 r2_score。
(1) 均方差(mean_squared_error):
(2) 平均绝对值误差(mean_absolute_error):
(3) 可释方差得分(explained_variance_score):
(4) 中值绝对误差(Median absolute error)
(5) R2决定系数(拟合优度)
模型越好:r2→1,模型越差:r2→0。
Sklearn代码调用如下:
fromsklearn.metrics import r2_scorey_true=[1,2,4]y_pred=[1.3,2.5,3.7]r2_score(y_true,y_pred)5.交叉验证
神经网络中有很多参数,我们怎么确定哪些参数能更有效解决现有问题呢?这时候交叉验证是最好的途径。交叉验证不仅可以用于神经网络调参,还可以用于其他机器学习的调参。例如:X轴为学习率(Learning rate)、神经网络层数(N-layers),Y轴为Error或精确度,不同神经层数对应的误差值或精准度也不同。
由于神经层数目越多,计算机消耗的时间也会增加,所以只需要找到满足误差要求又能节约时间的层结构即可。例如,当误差在0.005以下时都能接收时,则采用30层(N-layers=30)的结构即可。
二.图像分类loss曲线绘制
我们在阅读论文或实践项目中,可能会看到很多评价神经网络训练的曲线,当神经网络训练好了,我们才用它来进行预测及分析。前面第五篇文章Tensorboard也讲解了可视化曲线的绘制方法,而这部分将采用最原始的方法告诉大家loss曲线和accuracy曲线如何跟随神经网络迭代次数变化的,所生成的图是可以直接应用到我们论文中的。希望对您有所帮助~
1.数据集介绍
首先,实验所采用的数据集为Sort_1000pics数据集,该数据集包含了1000张图片,总共分为10大类,分别是人(第0类)、沙滩(第1类)、建筑(第2类)、大卡车(第3类)、恐龙(第4类)、大象(第5类)、花朵(第6类)、马(第7类)、山峰(第8类)和食品(第9类),每类100张。如图所示。
接着将所有各类图像按照对应的类标划分至0至9命名的文件夹中,如图所示,每个文件夹中均包含了100张图像,对应同一类别。
比如,文件夹名称为6中包含了100张花的图像,如下图所示。
2.训练过程
接着是图像分类的CNN代码,这里就不再介绍了,请参考前面的文章和详细注释。
完整代码:
-*- coding: utf-8 -*-""" Created on Tue Jan 7 13:39:19 2020 @author: xiuzhang Eastmount CSDN """importosimportglobimportcv2importnumpyasnpimporttensorflowastf定义图片路径path =photo/---------------------------------第一步 读取图像-----------------------------------defread_img(path):cate = [path + xforxinos.listdir(path)ifos.path.isdir(path + x)] imgs = [] labels = [] fpath = []foridx, folderinenumerate(cate):遍历整个目录判断每个文件是不是符合foriminglob.glob(folder +/*.jpg):print(reading the images:%s % (im))img = cv2.imread(im)调用opencv库读取像素点img = cv2.resize(img, (32,32))图像像素大小一致imgs.append(img)图像数据labels.append(idx)图像类标fpath.append(path+im)图像路径名print(path+im, idx)returnnp.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)读取图像fpaths, data, label = read_img(path) print(data.shape)(1000, 256, 256, 3)计算有多少类图片num_classes = len(set(label)) print(num_classes)生成等差数列随机调整图像顺序num_example = data.shape[0] arr = np.arange(num_example) np.random.shuffle(arr) data = data[arr] label = label[arr] fpaths = fpaths[arr]拆分训练集和测试集 80%训练集 20%测试集ratio =0.8s = np.int(num_example * ratio) x_train = data[:s] y_train = label[:s] fpaths_train = fpaths[:s] x_val = data[s:] y_val = label[s:] fpaths_test = fpaths[s:] print(len(x_train),len(y_train),len(x_val),len(y_val))800 800 200 200print(y_val)---------------------------------第二步 建立神经网络-----------------------------------定义Placeholderxs = tf.placeholder(tf.float32, [None,32,32,3])每张图片32*32*3个点ys = tf.placeholder(tf.int32, [None])每个样本有1个输出存放DropOut参数的容器drop = tf.placeholder(tf.float32)训练时为0.25 测试时为0定义卷积层 conv0conv0 = tf.layers.conv2d(xs,20,5, activation=tf.nn.relu)20个卷积核 卷积核大小为5 Relu激活定义max-pooling层 pool0pool0 = tf.layers.max_pooling2d(conv0, [2,2], [2,2])pooling窗口为2x2 步长为2x2print("Layer0:n", conv0, pool0)定义卷积层 conv1conv1 = tf.layers.conv2d(pool0,40,4, activation=tf.nn.relu)40个卷积核 卷积核大小为4 Relu激活定义max-pooling层 pool1pool1 = tf.layers.max_pooling2d(conv1, [2,2], [2,2])pooling窗口为2x2 步长为2x2print("Layer1:n", conv1, pool1)将3维特征转换为1维向量flatten = tf.layers.flatten(pool1)全连接层 转换为长度为400的特征向量fc = tf.layers.dense(flatten,400, activation=tf.nn.relu) print("Layer2:n", fc)加上DropOut防止过拟合dropout_fc = tf.layers.dropout(fc, drop)未激活的输出层logits = tf.layers.dense(dropout_fc, num_classes) print("Output:n", logits)定义输出结果predicted_labels = tf.arg_max(logits,1)---------------------------------第三步 定义损失函数和优化器---------------------------------利用交叉熵定义损失losses = tf.nn.softmax_cross_entropy_with_logits( labels = tf.one_hot(ys, num_classes),将input转化为one-hot类型数据输出logits = logits)平均损失mean_loss = tf.reduce_mean(losses)定义优化器 学习效率设置为0.0001optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)------------------------------------第四步 模型训练和预测-----------------------------------用于保存和载入模型saver = tf.train.Saver()训练或预测train =True模型文件路径model_path ="model/image_model"withtf.Session()assess:iftrain: print("训练模式")训练初始化参数sess.run(tf.global_variables_initializer())定义输入和Label以填充容器 训练时dropout为0.25train_feed_dict = { xs: x_train, ys: y_train, drop:0.25}训练学习1000次forstepinrange(1000): _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)ifstep %20==0:每隔20次输出一次结果训练准确率pre = sess.run(predicted_labels, feed_dict=train_feed_dict) accuracy =1.0*sum(y_train==pre) / len(pre) print("{},{},{}".format(step, mean_loss_val,accuracy))保存模型saver.save(sess, model_path) print("训练结束,保存模型到{}".format(model_path))else: print("测试模式")测试载入参数saver.restore(sess, model_path) print("从{}载入模型".format(model_path))label和名称的对照关系label_name_dict = {0:"人类",1:"沙滩",2:"建筑",3:"公交",4:"恐龙",5:"大象",6:"花朵",7:"野马",8:"雪山",9:"美食"}定义输入和Label以填充容器 测试时dropout为0test_feed_dict = { xs: x_val, ys: y_val, drop:0}真实label与模型预测labelpredicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)forfpath, real_label, predicted_labelinzip(fpaths_test, y_val, predicted_labels_val):将label id转换为label名real_label_name = label_name_dict[real_label] predicted_label_name = label_name_dict[predicted_label] print("{}t{} => {}".format(fpath, real_label_name, predicted_label_name))评价结果print("正确预测个数:", sum(y_val==predicted_labels_val)) print("准确度为:",1.0*sum(y_val==predicted_labels_val) / len(y_val)) k =0whilek < len(y_val): print(y_val[k], predicted_labels_val[k]) k = k +1当train=True时,训练过程会输出误差和accuracy值,核心代码如下:
输出结果如下所示,分别代表训练次数、整体误差和正确率。我们将其复制到TXT文件中,再重新写一个py代码绘图。
(1000,32,32,3)10800800200200[44300083867177904706077095435122828517871772640906112743962212334160530481816593698427292033086504427244359680904699350981418532651902199308578834440562815589720861589928260780219043190043333188159809]训练模式0,62.20244216918945,0.1220,8.619616508483887,0.362540,3.896609306335449,0.545...940,0.0003522337938193232,1.0960,0.00033640244510024786,1.0980,0.00032152896164916456,1.0训练结束,保存模型到model/image_model3.绘制loss和accuracy曲线
首先读取train_data.txt数据集,采用逗号连接,再绘制折线图即可。
importmatplotlib.pyplotaspltfrommpl_toolkits.axes_grid1importhost_subplot读取文件数据fp = open(train_data.txt,r)迭代次数 整体误差 正确率train_iterations = [] train_loss = [] test_accuracy = []解析数据forlineinfp.readlines(): con = line.strip(n).split(,)print(con) train_iterations.append(int(con[0])) train_loss.append(float(con[1])) test_accuracy.append(float(con[2]))绘制曲线图host = host_subplot(111) plt.subplots_adjust(right=0.8)ajust the right boundary of the plot windowpar1 = host.twinx()设置类标host.set_xlabel("iterations") host.set_ylabel("loss") par1.set_ylabel("validation accuracy")绘制曲线p1, = host.plot(train_iterations, train_loss,"b-", label="training loss") p2, = host.plot(train_iterations, train_loss,".")曲线点p3, = par1.plot(train_iterations, test_accuracy, label="validation accuracy") p4, = par1.plot(train_iterations, test_accuracy,"1")设置图标1->rightup corner, 2->leftup corner, 3->leftdown corner4->rightdown corner, 5->rightmid ...host.legend(loc=5)设置颜色host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p3.get_color())设置范围host.set_xlim([-10,1000]) plt.draw() plt.show()输出结果如下图所示,可以看到整体误差趋近于0.0003拟合,正确率朝着100%接近,整个神经网络的学习效率不错。
三.准确率、召回率、F值计算
1.预测
接下来将CNN神经网络中的train标记变量设置为False,使用上一步训练好的神经网络进行预测。核心代码如下:
输出结果如下所示,其中在200测试样本中,正确预测个数181,正确度为0.905。
(1000,32,32,3)10800800200200[94870757149305800258747889416784849961679863187804698526001996815911601721718797751060155075867750978973092479170225651095970625442686257150045793554613997569233241482734391576426400451724662417506837]测试模式INFO:tensorflow:Restoringparametersfrommodel/image_model从model/image_model载入模型bphoto/photo/9960.jpg美食=>美食bphoto/photo/4414.jpg恐龙=>恐龙bphoto/photo/8809.jpg雪山=>雪山bphoto/photo/7745.jpg野马=>大象bphoto/photo/012.jpg人类=>人类...bphoto/photo/053.jpg人类=>人类bphoto/photo/6658.jpg花朵=>花朵bphoto/photo/8850.jpg雪山=>雪山bphoto/photo/3318.jpg公交=>美食bphoto/photo/7796.jpg野马=>野马正确预测个数:181准确度为:0.905994488...668839772.计算
同样,我们将预测的结果和正确的类标复制到TXT文件中,然后计算其准确率、召回率、F值。基本步骤:
读取数据集分别计算0-9类(共10类)不同类标正确识别的个数和总识别的个数按照第一部分的公式计算准确率、召回率和F值调用matplotlib库绘制对比柱状图比如,测试集实际有20张人类图片,预测出18张人类图片,正确的类标14,则准确率为14/18,召回率为14/20。
最终绘制图形如下:
完整代码如下:
-*- coding: utf-8 -*-""" Created on Tue Jan 7 13:39:19 2020 @author: xiuzhang Eastmount CSDN """import numpy as np import matplotlib.pyplot as plt--------------------------------------------------------------------------第一部分 计算准确率 召回率 F值--------------------------------------------------------------------------读取文件数据fp =open(test_data.txt,r)迭代次数 整体误差 正确率real = [] pre = []解析数据forline in fp.readlines(): con = line.strip(n).split()print(con)real.append(int(con[0]))真实类标pre.append(int(con[1]))预测类标计算各类结果 共10类图片real_10= list(range(0,10))真实10个类标数量的统计pre_10= list(range(0,10))预测10个类标数量的统计right_10= list(range(0,10))预测正确的10个类标数量k =0whilek < len(real): v1 =int(real[k]) v2 =int(pre[k])print(v1, v2) real_10[v1] = real_10[v1] +1计数pre_10[v2] = pre_10[v2] +1计数ifv1==v2: right_10[v1] = right_10[v1] +1k = k +1print("统计各类数量")print(real_10, pre_10, right_10)准确率 = 正确数 / 预测数precision = list(range(0,10)) k =0whilek < len(real_10): value = right_10[k] *1.0/ pre_10[k] precision[k] = value k = k +1print(precision)召回率 = 正确数 / 真实数recall = list(range(0,10)) k =0whilek < len(real_10): value = right_10[k] *1.0/ real_10[k] recall[k] = value k = k +1print(recall)F值 = 2*准确率*召回率/(准确率+召回率)f_measure = list(range(0,10)) k =0whilek < len(real_10): value = (2* precision[k] * recall[k] *1.0) / (precision[k] + recall[k]) f_measure[k] = value k = k +1print(f_measure)--------------------------------------------------------------------------第二部分 绘制曲线--------------------------------------------------------------------------设置类别n_groups =10fig, ax = plt.subplots()index= np.arange(n_groups) bar_width =0.2opacity =0.4error_config = {ecolor:0.3}用来正常显示中文标签plt.rcParams[font.sans-serif]=[SimHei]绘制rects1 = ax.bar(index, precision, bar_width, alpha=opacity, color=b, error_kw=error_config, label=precision) rects2 = ax.bar(index+ bar_width, recall, bar_width, alpha=opacity, color=m, error_kw=error_config, label=recall) rects3 = ax.bar(index+ bar_width + bar_width, f_measure, bar_width, alpha=opacity, color=r, error_kw=error_config, label=f_measure)设置标签ax.set_xticks(index+3* bar_width /3) ax.set_xticklabels((0-人类,1-沙滩,2-建筑,3-公交,4-恐龙,5-大象,6-花朵,7-野马,8-雪山,9-美食))设置类标ax.legend() plt.xlabel("类标") plt.ylabel("评价") fig.tight_layout() plt.savefig(result.png, dpi=200) plt.show()输出结果如下所示,读者也可以尝试直接复制下面的precision、recall、f-measure绘制图形。
统计各类数量[21,22,17,13,24,28,27,36,26,31][19,23,18,12,24,30,29,34,25,31][17,19,15,11,24,26,27,34,24,29][0.8947368421052632,0.8260869565217391,0.8333333333333334,0.9166666666666666,1.0,0.8666666666666667,0.9310344827586207,1.0,0.96,0.9354838709677419][0.8095238095238095,0.8636363636363636,0.8823529411764706,0.8461538461538461,1.0,0.9285714285714286,1.0,0.9444444444444444,0.9230769230769231,0.9354838709677419][0.8500000000000001,0.8444444444444444,0.8571428571428571,0.8799999999999999,1.0,0.896551724137931,0.9642857142857143,0.9714285714285714,0.9411764705882353,0.9354838709677419]四.总结
写到这里,这篇文章就讲解完毕,更多TensorFlow深度学习文章会继续分享,接下来我们会分享RNN回归、文本识别、图像识别、语音识别等内容。如果读者有什么想学习的,也可以私聊我,我去学习并应用到你的领域。
最后,希望这篇基础性文章对您有所帮助,如果文章中存在错误或不足之处,还请海涵~作为人工智能的菜鸟,我希望自己能不断进步并深入,后续将它应用于图像识别、网络安全、对抗样本等领域,指导大家撰写简单的学术论文,一起加油!
读博不易,但深夜总喜欢挤时间写上一篇文章,算是对自己这么多年分享的鼓励,也希望自己能坚持,感谢家人的支持,小珞珞太可爱了。如果您也是从事Python数据分析、图像处理、人工智能、网络安全的朋友,我们可以深入探讨,尤其是做研究的同学,共同进步~
前文分享(可以点击喔):
一.白话神经网络和AI概念入门普及二.TensorFlow环境搭建、学习路线及入门案例三.TensorFlow基础及一元直线预测案例四.TensorFlow基础之Session、变量、传入值和激励函数五.TensorFlow创建回归神经网络及Optimizer优化器六.Tensorboard可视化基本用法及神经网络绘制七.TensorFlow实现分类学习及MNIST手写体识别案例八.什么是过拟合及dropout解决神经网络中的过拟合问题九.卷积神经网络CNN原理详解及TensorFlow编写CNN十.Tensorflow+Opencv实现CNN自定义图像分类案例及与机器学习KNN对比十一.Tensorflow如何保存神经网络参数十二.循环神经网络RNN和LSTM原理详解及TensorFlow分类案例十三.如何评价神经网络、loss曲线图绘制、图像分类案例的F值计算天行健,君子以自强不息。地势坤,君子以厚德载物。
真诚地感谢您关注娜璋之家公众号,也希望我的文章能陪伴你成长,希望在技术路上不断前行。文章如果对你有帮助、有感悟,就是对我最好的回报,且看且珍惜!再次感谢您的关注,也请帮忙宣传下娜璋之家,初来乍到,还请多指教。
(By:Eastmount 2022-01-19 夜于贵阳)
参考文献:
[1] 冈萨雷斯著. 数字图像处理(第3版)[M]. 北京:电子工业出版社,2013.[2] 杨秀璋, 颜娜. Python网络数据爬取及分析从入门到精通(分析篇)[M]. 北京:北京航天航空大学出版社, 2018.[3] 罗子江等. Python中的图像处理[M]. 科学出版社, 2020.[4]莫烦大神 网易云视频地址[5] https://study.163.com/course/courseLearn.htm?courseId=1003209007[6] TensorFlow【极简】CNN - Yellow_python大神[7] https://github.com/siucaan/CNN_MNIST[8] https://github.com/eastmountyxz/AI-for-TensorFlow[9]《机器学习》周志华[10] 神经网络模型的评价指标 - ZHANG ALIN[11] [深度学习] 分类指标accuracy,recall,precision等的区别 - z小白[12] 分类指标准确率(Precision)和正确率(Accuracy)的区别 - mxp_neu[13] 学习笔记2:scikit-learn中使用r2_score评价回归模型 - Softdiamonds[14] 方差、协方差、标准差、均方差、均方根值、均方误差、均方根误差对比分析 - cqfdcw[15] 机器学习:衡量线性回归法的指标(MSE、RMSE、MAE、R Squared)- volcao你以为你有很多路可以选择,其实你只有一条路可以走