Tensorflow学习一:初探用 tf 的对象们对某X叶草分类的研究

Tensorflow之:安装与验证

Tensorflow的安装非常简单,只要读者装有python和和相应版本的pip,输入:

pip install --upgrade tensorflow

即可。如果需要为python3的环境添加tensorflow(强烈推荐,毕竟到2020年python 2就退休了),则pip可能在有的环境下为pip3。如果读者计算设备安装有显卡加速(GPU),则输入如下指令能更快捷地安装tensorflow:

pip install --upgrade tensorflow-gpu

安装完毕之后,则可以用如下程序验证安装:

import tensorflow as tf

hello = tf.constant('Hello Tensorflow!')
sess = tf.Session()
print(sess.run(hello))

如果输出为类似下图效果,则证明tensorflow已经安装完毕。

输入图片说明

输入图片说明

机器学习是什么?它与AI的关系如何?机器学习DNN方法的大致步骤是哪些?

根据汤姆 米歇尔(Tom Mitchell)教授在1999年给出的定义,机器学习指的是“能够参考经验(E)得知完成任务(T)的方法并在任务中表现(P)不断提高的一种计算机程序”。然而我们事实上无法鉴定计算设备是否真正拥有人类所定义的“学习”的经历。现今来看,墨尔本大学知识技能科学(COMP90049 Knowledge Technology,slide machine learning)著名美女教授Dr.Sarah Erfani认为,机器学习是一种基于统计学、线性代数等数学学科以及计算机科学中的计算科学、算法等学科对于事物模式(pattern)的认知并指导实践中事件预测(prediction)的一门学科。机器学习又分为“监督式学习”(Supervised ML,即在训练过程中给出反馈结果,DNN是此类中一种比较高级的手段)和“非监督式学习”(Unsupervised ML,即只训练模型,不给出反馈)。它是人工智能的一种具体体现和实现手段。所以说实现了一个好的机器学习模型(“好”指按照用户预期的方式给出高精确度的执行,以满足用户对于潜在未知模式、规律或知识的认知),就迈出了人工智能的第一步。

而建成一个能实际使用的DNN机器学习模型,大致步骤如下:

  1. 获取数据集合:并将数据集合大致按照4:1的比例分为训练数据集合(Training data,简称“训练集”)和测试数据集合(Testing data,简称“测试集”)。这里4:1为理论上训练与结果评估的平衡值。低于这个值由于训练集合数据数量太少,训练效果不佳。高于这个值则评估的精确度就可能有问题。
  2. 训练预测模型:根据训练数据,对计算设备进行“训练”,其本质上是执行一段发现模式(pattern)的程序,并从模式中发现一个数据集可能拥有的规律,从而为进一步预测做好准备。在这一步的过程中,DNN会以训练集中的特征数据列(下简称“特征”,英文为feature)作为输入,以标签数据列(下简称“标签”,英文为label)作为输出,经历若干隐形中间层。通过这些中间层的运算发现从输入刀输出的精确度较好的映射(mapping,精确度较好指的是两个叫做loss和gradient较低,而精确度较高),从而得到一个预测模型(model)完成训练。
  3. 评估训练效果:根据得到的模型以及测试集中的特征对于测试集中的标签作出预测,并与测试集中真实的标签进行对比从而得出精确度。若精确度符合要求则结束训练,否则修改训练模型后重复步骤2。
  4. 预测未知输入:使用结束训练后的模型对于真实事件作出预测,给出在保证一定预测精确度条件下的结果。

本文所用数据集合

本文以对于鸢尾草种类的识别并实现自动分类为例,展示tensorflow DNN的工作原理。

输入图片说明输入图片说明

鸢尾草大致分为三种,即setosa,versicolor和virginica。本数据集用csv文件存储,第一列为数据集总数以及这三个分类,作为数据集的标题栏(title)。第二列开始,每列前四个数据为对于每株鸢尾草测量的四个指标,最后第五个数据为它是哪一类的草。(0-setosa, 1-versicolor以及2-virginica)。本模型的任务就是训练相应的模型,对于给定未知鸢尾草的四个指标,使用上述四个步骤,预测种类并达到大于95%的精确度。

---------------------------------------------------------------正文开始---------------------------------------------------------------

搭建环境准备:

为了搭建此模型,首先需要一个运行模型的环境。这里需要导入一些python的模块,具体代码如下:

from __future__ import absolute_import, division, print_function

import os
import matplotlib.pyplot as plt

import tensorflow as tf
import tensorflow.contrib.eager as tfe

try:
    tf.enable_eager_execution()
except ValueError:
    pass

print("TensorFlow version: {}".format(tf.VERSION))
print("Eager execution: {}".format(tf.executing_eagerly()))
print()

其中,eager_execution()是一个减少图运算的内置模块,它能加速机器学习的过程并且很多模块依赖其才得以执行。然而,在一个环境中enable_eager_execution()这一语句只能运行一次,否则会报ValueError,因此环境准备程序应写成如上所示。

获取数据集:

下载数据集

此处鸢尾草数据集(包括训练集和测试集)都会从不同链接下载。因此本模块输入为一个URL,输出为数据集所在文件对象(包括路径和文件)以便获得数据集时调用。代码如下:

def get_iris_dataset_fp(datasetURL):
    #Get the dataset:    
    dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(datasetURL),
        origin=datasetURL, cache_dir="F:\\Py_TF_wp", cache_subdir='mydataset')
    
    #print("Local copy of the dataset file: {}".format(dataset_fp))
    return dataset_fp

处理数据集中的每行数据

获得.csv数据集之后,需要将这些数据集处理为tensorflow能够使用的tensor对象(本质是一种numpy数组),并将数据集中的数据分为特征和标签。其处理方式如下:

"""
    Input: Eachline of the Iris data file.
    Output: Feature vector and label of eachline as tensors.
"""
def parse_csv(line):
	example_defaults = [[0.], [0.], [0.], [0.], [0]]  # sets field types
	parsed_line = tf.decode_csv(line, example_defaults)
  
	#print("Parsed line:", parsed_line)
  
  	# First 4 fields are features, combine into single tensor
  	features = tf.reshape(parsed_line[:-1], shape=(4,))
  	# Last field is the label
  	label = tf.reshape(parsed_line[-1], shape=())
  	return features, label

通过如下代码,读者可以自行查看对于这些数据处理的结果:

def parse_dataset(filefp):
    dataFile = open(filefp)
    # 注意第一行是方法头,这在后面的训练和评估过程中
    # 也要记得略去
    file_header = dataFile.readline()
    for eachLine in dataFile:
        features, label = parse_csv(eachLine.rstrip())
        print("Parsing result for the line:")
        print("Features:", features)
        print("Label", label)
        print()

parse_dataset("mydataset/iris_training.csv")

获得处理完成的数据集
"""
    Model: get training / testing dataset.
"""
def get_dataset(sample_size, datasetURL):
    # 根据URL获得文件对象的信息
    dataset_fp = get_iris_dataset_fp(datasetURL)
    dataset = tf.data.TextLineDataset(dataset_fp)
    dataset = dataset.skip(1)             # skip the first header row
    #parse_csv is the method used to parse each_line of the csv file.
    dataset = dataset.map(parse_csv)      # parse each row
    dataset = dataset.shuffle(buffer_size=1000)  # randomize
    dataset = dataset.batch(sample_size)
    
    # View a single example entry from a batch
    # features, label = tfe.Iterator(train_dataset).next()
    #print("example features:", features[0])
    #print("example label:", label[0])
    return dataset 

获取训练集和测试集的调用代码分别如下:

train_dataset = get_dataset(96, "http://download.tensorflow.org/data/iris_training.csv")
test_dataset = get_dataset(24, "http://download.tensorflow.org/data/iris_test.csv")

训练模型

搭建DNN架构:

在训练开始之前,首先需要搭建一个DNN架构。DNN架构是由许多层次训练步骤组成的(本文从输入到输出搭建了4层),一般来说,层次越多结果越准确,但速度也越慢。其中,搭建输入层模型时需要输入特征数据的维度。最后一层需要交代可能的标签种类的数量。

"""
    # Build the DNN:
    # First row of line input layer, in which shape is required.
    # Middle row(s) hidden layer
    # Last row output layer.
"""
def build_model():
    model = tf.keras.Sequential([
      tf.keras.layers.Dense(10, activation="relu", input_shape=(4,)),  # input shape required
      tf.keras.layers.Dense(10, activation="relu"),
      tf.keras.layers.Dense(10, activation="relu"),
      tf.keras.layers.Dense(3)
    ])
        
    #print("Built model:", model)
    return model

model = build_model()
定制“止损”策略

DNN会通过loss和gradient两个指标的计算,并结合精确度来训练模型。如前文所说,训练过程中loss和gradient应当尽量小,而精确度应当尽量大。

"""
    Calculate loss of a model. 
    Input: model, independent variables, predictions.
    Output: Loss value as calculated.
"""
def loss(model, x, y):
    #y_ is the desired label.
    y_ = model(x)
    return tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_)

def gradient(model, inputs, targets):
    with tfe.GradientTape() as tape:
        loss_value = loss(model, inputs, targets)
    return tape.gradient(loss_value, model.variables)

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
开始训练模型:

这是本例最关键的一个环节。这个环节中根据用户设置的迭代次数(num_epochs),DNN会不断迭代寻找模型的最佳匹配规律。一般来说,迭代次数设置越大则预测越准确,但是耗时也长。经过多次尝试,发现迭代次数设置在200 - 250之间较为合适。

def train_model():
    # keep results for plotting
    train_loss_results = []
    train_accuracy_results = []
    #model = build_model()
    num_epochs = 201
    #num_epochs = 251
    
    for epoch in range(num_epochs):
      epoch_loss_avg = tfe.metrics.Mean()
      epoch_accuracy = tfe.metrics.Accuracy()
    
      # Training loop - using batches of 32
      for x, y in tfe.Iterator(train_dataset):
        # Optimize the model
        grads = gradient(model, x, y)
        optimizer.apply_gradients(zip(grads, model.variables),
                                  global_step=tf.train.get_or_create_global_step())
    
        # Track progress
        epoch_loss_avg(loss(model, x, y))  # add current batch loss
        # compare predicted label to actual label
        epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)
    
      # end epoch
      train_loss_results.append(epoch_loss_avg.result())
      train_accuracy_results.append(epoch_accuracy.result())
      
      """# Check training accuracies:
      if epoch % 50 == 0:
        print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
              epoch_loss_avg.result(), epoch_accuracy.result()))
    """
    return (train_loss_results, train_accuracy_results)
train_model()
描绘训练过程:

本过程虽然不是DNN的一个必须步骤,但是对于初学者来说,可以通过观察训练过程中“损失”的降低和精确度的提高,直观感受DNN神经网络的神奇之处。

def plot_training():
    train_loss_results, train_accuracy_results = train_model()
    fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
    fig.suptitle('Training Metrics')
    
    axes[0].set_ylabel("Loss", fontsize=14)
    axes[0].plot(train_loss_results)
    
    axes[1].set_ylabel("Accuracy", fontsize=14)
    axes[1].set_xlabel("Epoch", fontsize=14)
    axes[1].plot(train_accuracy_results)
    
    plt.show()
    
plot_training()

某次测试所得图形如下:

输入图片说明

基本可以观察到,一开始随着迭代次数增加“损失”波动减少,精确度波动上升;而后面二者波动渐渐趋于稳定。因此为了节省训练时间,迭代次数也不必过多,达到预期精确度之后即可。

评估模型

评估模型时根据训练过的模型对结果进行预测,以test_accuracy.result()的方式呈现。


def evaluate():
    test_dataset = get_dataset(96, "http://download.tensorflow.org/data/iris_test.csv")
    test_accuracy = tfe.metrics.Accuracy()
    
    for (x, y) in tfe.Iterator(test_dataset):
      prediction = tf.argmax(model(x), axis=1, output_type=tf.int32)
      test_accuracy(prediction, y)
    
    print("Test set accuracy: {:.3%}".format(test_accuracy.result()))

evaluate()

对于本模型来说,预测准确度大约在数次尝试后稳定在96.67%左右。

输入图片说明

预测未知数据

最后,经过训练后的模型满足要求后便可以投入实际使用。使用时,将特征指标转化为tensor对象,然后即可由标签中的“name”变量获取预测结果。


def classify_unkowns():
    class_ids = ["Iris setosa", "Iris versicolor", "Iris virginica"]
    
    predict_dataset = tf.convert_to_tensor([
        [5.1, 3.3, 1.7, 0.5,],
        [5.9, 3.0, 4.2, 1.5,],
        [6.9, 3.1, 5.4, 2.1]
    ])
    
    predictions = model(predict_dataset)
    
    for i, logits in enumerate(predictions):
      class_idx = tf.argmax(logits).numpy()
      name = class_ids[class_idx]
      print("Example {} prediction: {}".format(i, name))

classify_unkowns()

输入图片说明

参考资料:

  1. Get Started, Tensorflow doc, URL: https://www.tensorflow.org/get_started/eager?hl=zh-cn
  2. 谷歌Tensorflow学习顺序参考页面:https://www.tensorflow.org/get_started/
  3. Installing Tensorflow, URL: https://www.tensorflow.org/install/?hl=zh-cn
  4. Slides machine learning, deep neuron network, COMP90049 Knowledge Technology, 2017 semester 2, University of Melbourne

转载于:https://my.oschina.net/Samyan/blog/1795341

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值