利用keras框架实现鸢尾花的识别#
前言
本项目是朱某学习第二阶段深度学习给自己布置的一个家庭作业,在第二阶段的学习中,我学习了如何处理二元分类、多分类问题以及连续数据预测的问题。如何对送进网络的数据进行预处理。如何根据送进网络的验证数据正确处理过拟合问题。在学习过程中,我用到的数据集都是keras自带的数据集,因此我就想。能否根据自己自定义的一批数据来实现网络训练,并正确判断鸢尾花的类型,虽然艰难重重,但是最后还是成功了。
数据集介绍
本次项目采用采用的是鸢尾花数据集,Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。数据集内包含 3 类共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,可以通过这4个特征预测鸢尾花卉属于(iris-setosa, iris-versicolour, iris-virginica)中的哪一品种。在去年寒假我曾用过该数据集做个KNN算法的测试,虽然该数据集数据量较少,但因为有较大的相关性,放进神经网络训练,依然可以得到不错的结果。
i鸢尾花
数据格式
为了方便计算机的读取,我们把三种花的类型分别用:0,1,2进行替代
数据
接下来我们读入数据
import csv import random import numpy def loadDataset(filename, split, trainingSet=[], testSet=[]): with open(filename, 'rt') as csvfile: lines = csv.reader(csvfile) dataset = list(lines) # 转换成list,lines是所有的行 for x in range(len(dataset) - 2): for y in range(5): dataset[x][y] = float(dataset[x][y]) if random.random() < split: trainingSet.append(dataset[x]) else: testSet.append(dataset[x]) trainingSet=[] testSet=[] loadDataset(r'iris.data.txt', 0.67, trainingSet, testSet) #通过设定一个概率阈值对数据集分割训练集和测试集 partial_x_train = [] #训练集输入 partial_y_train = [] #训练集标签 x_val = [] y_val = [] #处理测试输入数据集,将前四个元素生成一个array,最后把array拼在一起,构建一个五维张量 for i in trainingSet: partial_x_train.append((i[:4])) partial_x_train= numpy.asfarray(partial_x_train) # #处理测试输入标签 # 初始化一个三维array,值的大小代表概率。根据数据赋值,把0,1,2对应元素赋值0.99,其他赋值0.01,最后整合成一个四维度张量 for i in trainingSet: targets = numpy.zeros(3) + 0.01 targets[int(i[4:][0])] = 0.99 partial_y_train.append(targets) partial_y_train=numpy.array(partial_y_train) #exit # #处理测试输入数据集 for i in testSet: x_val.append((i[:4])) x_val= numpy.asfarray(x_val) # # #处理测试输入标签 for i in testSet: target = numpy.zeros(3) + 0.01 target[int(i[4:][0])] = 0.99 y_val.append(target) y_val=numpy.array(y_val) #将测试集的的一部分分为校验数据 test_x=x_val[12:] test_y=y_val[12:] x_val1=x_val[:12] y_val1=y_val[:12] print(y_val1)
通过观察,我们可以看出,一份数据的前四个数据决定最后一个数据,因为输出的数据总共有三个类别,因此我们设计一个输入4个结点输出三个节点的神经网络,因为数据量较少,我们设置两层中间层,每层64个节点。前两层我们使用‘relu’作为激活函数
relu
当结果是输出多个分类的概率时,用softmax激活函数
softmax
对于输出多个分类结果,最好的损失函数是categorical_crossentropy
categorical_crossentropy性质:即受误差的影响,所以当误差大的时候,权重更新就快,当误差小的时候,权重的更新就慢。这是一个很好的性质。
性质:
a.非负性。(所以我们的目标就是最小化代价函数)
b.当真实输出a与期望输出y接近的时候,代价函数接近于0.(比如y=0,a~0;y=1,a~1时,代价函数都接近0)。
from keras import models from keras import layers model = models.Sequential() model.add(layers.Dense(64, activation='relu', input_shape=(4,))) #inputshape 4 代表输入5维度tensor model.add(layers.Dense(64, activation='relu')) #当结果是输出多个分类的概率时,用softmax激活函数,它将为3个分类提供不同的可能性概率值 model.add(layers.Dense(3, activation='softmax')) #对于输出多个分类结果,最好的损失函数是categorical_crossentropy model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) # history = model.fit(partial_x_train, partial_y_train, epochs=64, validation_data = (x_val1, y_val1)) # # history_dict = history.history print(history_dict.keys())
接下来我们根据训练数据的误差和校验数据的误差画出函数
误差曲线
接下来我们根据训练数据的误差和校验数据的精度画出函数
误差曲线
准确度曲线
可以看出第二种值是最大的,因此还是蛮准的,接下来我们对输入的数据进行一些简单的处理。统计化处理,把数值处理成期望为0,方差为1的分布。
常用的数据处理方法有:
把数值都变小,通常把数组转换到0和1之间。 统一化,把数值处理成在一个取值范围之内。 统计化处理,把数值处理成期望为0,方差为1的分布。第三种处理方式的公式如下,其中X’为均值,std为(X-X')的标准差
实现代码如下:(只对训练数据进行处理)
mean = partial_x_train.mean(axis=0) partial_x_train -= mean std = partial_x_train.std(axis = 0) partial_x_train /= std x_val -= mean x_val /= std
数据处理结果
虽然最后评价出的准确值都差不多,但是我们可以看出训练时的准度高多了
接下来开始进入CNN阶段。