利用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阶段。
网友评论