Tensorflow-iris-案例教程-零基础-机器学习

作者:jcmp      发布时间:2021-05-13      浏览量:0
这篇文章将和大家一起完成Tenso

这篇文章将和大家一起完成Tensorflow的经典鸢尾花分类案例。
完整过程可能需要一些时间,但您没有必要一次性完成它。

--

准备工作

如果您还不了解鸢尾花分类问题是什么
请点这里认真完成阅读(不需要写任何代码)

如果您还没有安装Python和Tensorflow
Windows用户点这里认真阅读并完成安装
苹果MacOS用户点这里认真阅读并完成安装

从百度云下载需要用到的文件
点击这里,提取码dwdk

--

了解数据集

下载到的资料中包含两个看起来像excel格式的文件,iris_training.csv和iris_test.csv。
iris_training.csv顾名思义是训练数据集,iris_test.csv是测试数据集。

接下来,我们会先把训练数据“喂”给计算机,让它吃掉并消化好,这样它就能自己从数据中找到植物学家区分三种鸢尾花类型的规则。

然后我们再用训练出来的规则尝试去鉴定我们的测试数据,如果鉴定出来的结果和植物学家的看法一致,那么我们就可以说这个规则很有效。

我们先认真看一下数据文件内容。
请用右键选择文本编辑工具打开它,它们的内容看起来像下面这个样子:



每个文件的第一行包含两个数字,第一个数字是说这个文件中有多少行数据,每一行代表一朵花。training有120朵,test有30朵。

第二个数字都是4,表示每朵花有几个【特征futures】数据。从前面的鸢尾花案例分析文章中我们知道,测量了花萼的长度、花萼的宽度、花瓣的长度、花瓣的宽度这4个数据,所以这里都是4。(但实际上,对于计算机来说,数据的名称一点也不重要,不是吗?)

第一行还包含了三个英文单词,就是鸢尾花的三个类型山鸢尾花Setosa、变色鸢尾花Versicolor、韦尔吉尼娅鸢尾花Virginica。

下面是很多很多的数字行。每一行有5个数字,逗号分割。前面4个对应花萼花瓣4个特征futrues。

每行数字最后一个都是0、1或2,这里的意思是0代表Setosa,1代表Versicolor,2代表Virginica。012这个顺序和第一行最后三个单词是对应的。这就是植物学家鉴定之后给每朵花写上的【标签label】

--

安装软件

首先确保Python和Tensorflow已经被正确安装。具体请参考 Python-Tensorflow-最简安装教程
然后用IDLE从菜单【文件File-新文件New file】创建新文件,保存到桌面iris文件夹下命名iris.py,然后把下载的两个数据文件也拷贝到iris文件夹下。

保存后右键选择打开方式,IDLE打开,然后粘贴以下代码并保存:

import pandas as pdimport tensorflow as tf

然后在命令行工具内执行以下命令,MacOS:

python3 ~/desktop/iris/iris.py

Windows:

python3 desktop/iris/iris.py

正常情况会提示错误ImportError: No module named pandas。缺少pandas这个模块,下面我们安装它。

使用下面命令安装:

pip3 install pandas

如果遇到问题请尝试用管理员运行(Windows)或前面加sudo执行,下同。
如果进度非常缓慢卡住,请尝试添加--trusted-host国内镜像地址,多试几次,命令比如

pip3 --trusted-host http://mirrors.aliyun.com/pypi/simple/ install pandas

--

加载数据

首先把数据文件的路径处理成可以使用的train_path和test_path。
然后使用pandas模块的read_csv方法把数据读进来,又使用pop方法把4个特征数据和Species数据拆分成_x和_y。这样命名的原因是我们之前介绍过的函数表示:


iris.py的代码如下:

import osimport pandas as pdimport tensorflow as tfFUTURES = ['SepalLength', 'SepalWidth','PetalLength', 'PetalWidth', 'Species']SPECIES = ['Setosa', 'Versicolor', 'Virginica']dir_path = os.path.dirname(os.path.realpath(__file__))train_path=os.path.join(dir_path,'iris_training.csv')test_path=os.path.join(dir_path,'iris_test.csv')train = pd.read_csv(train_path, names=FUTURES, header=0)train_x, train_y = train, train.pop('Species')test = pd.read_csv(test_path, names=FUTURES, header=0)test_x, test_y = test, test.pop('Species')feature_columns = []for key in train_x.keys():    feature_columns.append(tf.feature_column.numeric_column(key=key))print(test_x)

保存到桌面文件夹iris/iris.py,和两个数据文件放在一起,我们使用python3命令运行它,MacOS终端命令

python3 ~/desktop/iris/iris.py

Windows命令提示符

python3 desktop/iris/iris.py

运行结果如下:



如果将最后一行代码改为print(test_y)则会只输出每朵花的类型0、1或2

如果将最后一行代码改为print(feature_columns)我们会看到输出类似下面的数据:



暂时我们不需要深究它的含义,只要留意到它与花朵的4个特征相对应,表示了每个特征的数据类型都是32位浮点小数tf.float32。

--

设定估算器(分类器)

我们直接使用tensorflow提供的估算器来从花朵数据推测分类规则。tf.estimator里面包含了很多估算器,这里我们使用深层神经网络分类器DNNClassifier(Deep Neural Network Classifier)。
去除最后一行,在最后添加新的内容:

classifier = tf.estimator.DNNClassifier(    feature_columns=feature_columns,    hidden_units=[10, 10],    n_classes=3)

训练模型

接下来我们就可以灌输数据给我们的估算器,让它自动训练,寻找其中的分类规律,也就是我们真正需要的分类函数,也称之为模型。

继续添加新的代码:

def train_input_fn(features, labels, batch_size):    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))    dataset = dataset.shuffle(1000).repeat().batch(batch_size)    return dataset.make_one_shot_iterator().get_next()tf.logging.set_verbosity(tf.logging.INFO)batch_size=100classifier.train(input_fn=lambda:train_input_fn(train_x, train_y,batch_size),steps=1000)

重新运行iris.py,可以看到输出了很多行类似的信息,这说明训练正常运行了:


--

评估模型

上面我们把训练数据“喂食”给分类器进行训练,当然计算机也就从数据中猜出了三种花分类的依据,也就是我们训练得到的模型。
但我们并不知道这个“训练”出来的模型是否正确,为了考验一下它,我们把test测试数据交给它,让计算机用这个模型来预测这些test花的分类,然后我们把预测得到的分类和植物学家为test花标注的分类进行对比,如果模型预测的都正确,我就说这个模型的精确度accuracy是100%。

继续添加以下代码:

def eval_input_fn(features, labels, batch_size):    features=dict(features)    inputs=(features,labels)    dataset = tf.data.Dataset.from_tensor_slices(inputs)    dataset = dataset.batch(batch_size)    return dataset.make_one_shot_iterator().get_next()eval_result = classifier.evaluate(    input_fn=lambda:eval_input_fn(test_x, test_y,batch_size))print(eval_result)

我们再次运行,最后一行得到类似下面的结果,我们看到accuracy能保持在0.9以上:


如果我们调整神经网络的层级设置hidden_units,或者训练的设置batch_size=100或steps=1000,我们就有可能得到精确度更高或更低的结果。

应用模型

回到我们最初要解决的问题,也就是当女朋友把她的鸢尾花测量数据交给我们的时候,我们可以让训练出来的人工智能模型来自动对这朵花进行分类,由于精度超过90%,所以我们有超过九成的把握可以认为这个分类就是正确的。

继续添加以下代码:

for i in range(0,100):    print('\nPlease enter features: SepalLength,SepalWidth,PetalLength,PetalWidth')    a,b,c,d = map(float, input().split(','))     predict_x = {        'SepalLength': [a],        'SepalWidth': [b],        'PetalLength': [c],        'PetalWidth': [d],    }    predictions = classifier.predict(            input_fn=lambda:eval_input_fn(predict_x,                                            labels=[0],                                            batch_size=batch_size))    for pred_dict in predictions:        class_id = pred_dict['class_ids'][0]        probability = pred_dict['probabilities'][class_id]        print(SPECIES[class_id],100 * probability)                                      

--

结语

通过这个经典案例,我们使用Tensorflow训练了第一个机器学习模型,虽然它只能根据已测量的数据做简单的分类预测,但是整个学习过程和代码流程却是完备的。

回顾一下整个流程:

下面是以上代码的完整版,带有更多注释,仅供学习者参考理解,强烈提示不要一味照抄照搬,思路才是最重要的。更多关于神经网络的信息可以参考Tensorflow官网,我后续也会发布一些自己的学习经验。

import osimport pandas as pdimport tensorflow as tfFUTURES = ['SepalLength', 'SepalWidth','PetalLength', 'PetalWidth', 'Species']SPECIES = ['Setosa', 'Versicolor', 'Virginica']#格式化数据文件的目录地址dir_path = os.path.dirname(os.path.realpath(__file__))train_path=os.path.join(dir_path,'iris_training.csv')test_path=os.path.join(dir_path,'iris_test.csv')#载入训练数据train = pd.read_csv(train_path, names=FUTURES, header=0)train_x, train_y = train, train.pop('Species')#载入测试数据test = pd.read_csv(test_path, names=FUTURES, header=0)test_x, test_y = test, test.pop('Species')#设定特征值的名称feature_columns = []for key in train_x.keys():    feature_columns.append(tf.feature_column.numeric_column(key=key))#选定估算器:深层神经网络分类器  classifier = tf.estimator.DNNClassifier(    feature_columns=feature_columns,    hidden_units=[10, 10],    n_classes=3)#针对训练的喂食函数def train_input_fn(features, labels, batch_size):    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))    dataset = dataset.shuffle(1000).repeat().batch(batch_size) #每次随机调整数据顺序    return dataset.make_one_shot_iterator().get_next()#设定仅输出警告提示,可改为INFOtf.logging.set_verbosity(tf.logging.WARN)#开始训练模型!batch_size=100classifier.train(input_fn=lambda:train_input_fn(train_x, train_y,batch_size),steps=1000)#针对测试的喂食函数def eval_input_fn(features, labels, batch_size):    features=dict(features)    inputs=(features,labels)    dataset = tf.data.Dataset.from_tensor_slices(inputs)    dataset = dataset.batch(batch_size)    return dataset.make_one_shot_iterator().get_next()#评估我们训练出来的模型质量eval_result = classifier.evaluate(    input_fn=lambda:eval_input_fn(test_x, test_y,batch_size))print(eval_result)#支持100次循环对新数据进行分类预测for i in range(0,100):    print('\nPlease enter features: SepalLength,SepalWidth,PetalLength,PetalWidth')    a,b,c,d = map(float, input().split(',')) #捕获用户输入的数字    predict_x = {        'SepalLength': [a],        'SepalWidth': [b],        'PetalLength': [c],        'PetalWidth': [d],    }        #进行预测    predictions = classifier.predict(            input_fn=lambda:eval_input_fn(predict_x,                                            labels=[0],                                            batch_size=batch_size))    #预测结果是数组,尽管实际我们只有一个    for pred_dict in predictions:        class_id = pred_dict['class_ids'][0]        probability = pred_dict['probabilities'][class_id]        print(SPECIES[class_id],100 * probability)

以上代码文件实在不成功可以从百度云盘下载
iris.py
提取密码: 8dt3

>>> import tensorflow as tf>>> print(tf.__version__)

探索人工智能的新边界

如果您发现文章错误,请不吝留言指正;
如果您觉得有用,请点喜欢;
如果您觉得很有用,感谢转发~


END