个性化阅读
专注于IT技术分析

TensorFlow入门:机器学习权威教程

本文概述

TensorFlow是Google创建的一个开源软件库, 用于实现机器学习和深度学习系统。这两个名称包含一系列共同面临挑战的强大算法-允许计算机学习如何自动发现复杂的模式和/或做出最佳决策。

如果你对这些系统的详细信息感兴趣, 可以从srcmini关于机器学习和深度学习的博客文章中了解更多信息。

TensorFlow教程

TensorFlow的核心是用于数据流编程的库。它利用各种优化技术使数学表达式的计算更轻松, 更高效。

TensorFlow的一些关键功能包括:

  • 有效处理涉及多维数组的数学表达式
  • 深度神经网络和机器学习概念的良好支持
  • GPU / CPU计算, 可以在两种架构上执行相同的代码
  • 跨机器和庞大数据集的计算具有高度可扩展性

这些功能一起使TensorFlow成为生产规模机器智能的理想框架。

在本TensorFlow教程中, 你将学习如何在TensorFlow中使用简单但功能强大的机器学习方法, 以及如何使用其一些辅助库来调试, 可视化和调整由此创建的模型。

安装TensorFlow

我们将使用TensorFlow Python API, 该API可与Python 2.7和Python 3.3+一起使用。 GPU版本(仅Linux)需要Cuda Toolkit 7.0+和cuDNN v2 +。

我们将使用Conda软件包依赖性管理系统来安装TensorFlow。 Conda使我们可以在一台机器上分离多个环境。你可以从此处了解如何安装Conda。

安装Conda之后, 我们可以创建用于TensorFlow安装和使用的环境。以下命令将使用其他一些库(如NumPy)创建我们的环境, 一旦我们开始使用TensorFlow, 这将非常有用。

在此环境中安装的Python版本是2.7, 我们将在本文中使用此版本。

conda create --name TensorflowEnv biopython

为了使事情变得容易, 我们在这里安装了biopython而不是NumPy。这包括NumPy和我们将需要的其他一些软件包。你始终可以使用conda install或pip install命令根据需要安装软件包。

以下命令将激活创建的Conda环境。我们将能够使用安装在其中的软件包, 而无需与全局或某些其他环境中安装的软件包混合使用。

source activate TensorFlowEnv 

pip安装工具是Conda环境的标准部分。我们将使用它来安装TensorFlow库。在此之前, 一个好的第一步是使用以下命令将pip更新到最新版本:

pip install --upgrade pip

现在我们可以通过运行以下命令来安装TensorFlow:

pip install tensorflow

TensorFlow的下载和构建可能需要几分钟。在撰写本文时, 这将安装TensorFlow 1.1.0。

数据流图

在TensorFlow中, 使用数据流图描述了计算。图的每个节点代表数学运算(例如加法, 除法或乘法)的实例, 并且每个边都是对其执行操作的多维数据集(张量)。

一个简单的数据流程图

当TensorFlow与计算图一起使用时, 将对它们进行管理, 其中每个节点代表一个操作的实例, 其中每个操作具有零个或多个输入和零个或多个输出。

TensorFlow中的边缘可分为两类:正常边缘传输数据结构(张量), 其中一个操作的输出可能成为另一操作的输入, 特殊边缘用于控制两个节点之间的依赖性以设置一个节点等待另一个节点完成的操作顺序。

简单表达

在继续讨论TensorFlow的元素之前, 我们将首先进行TensorFlow的工作, 以了解TensorFlow程序的外观。

让我们从简单的表达式开始, 并假设由于某种原因, 我们想以TensorFlow方式评估函数y = 5 * x + 13。

在简单的Python代码中, 它看起来像:

x = -2.0
y = 5*x + 13
print y

在这种情况下, 我们得到的结果是3.0。

现在我们将上面的表达式转换成TensorFlow术语。

常量

在TensorFlow中, 使用函数常量创建常量, 该常量具有签名常量(value, dtype = None, shape = None, name =’Const’, verify_shape = False), 其中value是将在其中使用的实际常量值进一步计算, dtype是数据类型参数(例如float32 / 64, int8 / 16等), shape是可选尺寸, name是张量的可选名称, 最后一个参数是布尔值, 指示对价值的形状。

如果在训练模型中需要具有特定值的常量, 则可以按以下示例使用常量对象:

z = tf.constant(5.2, name="x", dtype=tf.float32)

变量

TensorFlow中的变量是包含张量的内存缓冲区, 必须对张量进行显式初始化, 并在图中使用它们来维护会话之间的状态。通过简单地调用构造函数, 变量将被添加到计算图中。

从训练模型开始, 变量特别有用, 并且变量用于保存和更新参数。作为构造函数的参数传递的初始值表示张量或对象, 可以将其转换或作为张量返回。这意味着, 如果我们想在变量中填充一些预定义或随机值, 以供以后在训练过程中使用并在迭代中进行更新, 则可以通过以下方式进行定义:

k = tf.Variable(tf.zeros([1]), name="k")

在TensorFlow中使用变量的另一种方法是在计算中, 该变量不可训练, 可以通过以下方式定义:

k = tf.Variable(tf.add(a, b), trainable=False)

届会

为了实际评估节点, 我们必须在会话中运行计算图。

会话封装了TensorFlow运行时的控件和状态。没有参数的会话将使用在当前会话中创建的默认图, 否则会话类接受一个图参数, 该参数将在要执行的会话中使用。

以下是一个简短的代码片段, 显示了如何在TensorFlow中使用以上定义的术语来计算简单的线性函数。

import tensorflow as tf

x = tf.constant(-2.0, name="x", dtype=tf.float32)
a = tf.constant(5.0, name="a", dtype=tf.float32)
b = tf.constant(13.0, name="b", dtype=tf.float32)

y = tf.Variable(tf.add(tf.multiply(a, x), b))

init = tf.global_variables_initializer()

with tf.Session() as session:
    session.run(init)
    print session.run(y)

使用TensorFlow:定义计算图

使用数据流图的好处是执行模型与执行模型是分开的(在CPU, GPU或某种组合上), 一旦实现, TensorFlow中的软件就可以在CPU或GPU上使用, 其中所有复杂性都与代码有关执行是隐藏的。

可以在使用TensorFlow库的过程中构建计算图, 而不必显式实例化Graph对象。

TensorFlow中的Graph对象可以通过简单的代码行(例如c = tf.add(a, b))创建。这将创建一个运算节点, 该运算节点采用两个张量a和b来生成其总和c作为输出。

计算图是使用该库的内置过程, 无需直接调用图对象。 TensorFlow中的图对象包含一组操作和张量作为数据单位, 用于两个操作之间, 这些对象允许相同的过程, 并且包含多个图, 每个图将分配给不同的会话。例如, 简单的代码行c = tf.add(a, b)将创建一个操作节点, 该操作节点将两个张量a和b作为输入并产生它们的和c作为输出。

TensorFlow还提供了一种供料机制, 用于将张量修补到图中的任何操作, 其中供料用张量值替换了操作的输出。提要数据在run()函数调用中作为参数传递。

占位符是TensorFlow的一种方法, 它允许开发人员通过绑定在某些表达式内的占位符将数据注入计算图中。占位符的签名是:

placeholder(dtype, shape=None, name=None)

其中dtype是张量中元素的类型, 可以提供要馈入的张量的形状和操作名称。

如果未通过形状, 则该张量可以采用任何形状。重要说明是, 必须向占位符张量馈送数据, 否则, 在执行会话时, 如果缺少该部分, 则占位符会产生以下结构的错误:

InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'y' with dtype float

占位符的优点是, 它们允许开发人员创建操作以及通常的计算图, 而无需为此事先提供数据, 并且可以在运行时从外部源添加数据。

让我们来解决一个简单的问题, 即以TensorFlow方式将两个整数x和y相乘, 在此情况下, 占位符将通过会话运行方法与供稿机制一起使用。

import tensorflow as tf

x = tf.placeholder(tf.float32, name="x")
y = tf.placeholder(tf.float32, name="y")

z = tf.multiply(x, y, name="z")

with tf.Session() as session:
    print session.run(z, feed_dict={x: 2.1, y: 3.0})

使用TensorBoard可视化计算图

TensorBoard是用于分析数据流图的可视化工具。这有助于更好地理解机器学习模型。

使用TensorBoard, 你可以深入了解有关参数的不同类型的统计信息以及有关计算图各部分的详细信息。深度神经网络具有大量节点并不罕见。 TensorBoard允许开发人员深入了解每个节点以及如何在TensorFlow运行时执行计算。

TensorBoard图形视图

现在让我们回到本TensorFlow教程开始的示例, 其中我们定义了一个线性函数, 格式为y = a * x + b。

为了记录会话中的事件(以后可以在TensorBoard中使用), TensorFlow提供了FileWriter类。它可用于创建用于存储摘要和事件的事件文件, 其中构造函数接受六个参数, 如下所示:

__init__(logdir, graph=None, max_queue=10, flush_secs=120, graph_def=None, filename_suffix=None)

其中logdir参数是必需的, 其他具有默认值。 graph参数将从训练程序中创建的会话对象中传递。完整的示例代码如下:

import tensorflow as tf


x = tf.constant(-2.0, name="x", dtype=tf.float32)
a = tf.constant(5.0, name="a", dtype=tf.float32)
b = tf.constant(13.0, name="b", dtype=tf.float32)


y = tf.Variable(tf.add(tf.multiply(a, x), b))


init = tf.global_variables_initializer()


with tf.Session() as session:
    merged = tf.summary.merge_all() // new
    writer = tf.summary.FileWriter("logs", session.graph) // new


    session.run(init)
    print session.run(y)

我们只添加了两行。我们合并默认图中收集的所有摘要, 并分别使用FileWriter将事件转储到文件中, 如上所述。

运行该程序后, 我们将文件保存在目录日志中, 最后一步是运行tensorboard:

tensorboard --logdir logs/

现在TensorBoard已启动并在默认端口6006上运行。打开http:// localhost:6006并单击Graphs菜单项(位于页面顶部)后, 你将能够看到该图, 就像一个在下面的图片中:

TensorBoard数据流程图

TensorBoard标记常量和摘要节点特定的符号, 如下所述。

图图标

TensorFlow数学

张量是TensorFlow中的基本数据结构, 它们代表数据流图中的连接边。

张量只是标识多维数组或列表。张量结构可以通过三个参数来识别:等级, 形状和类型。

  • 等级:标识张量的维数。等级被称为张量的阶数或n维数, 其中例如等级1张量是矢量或等级2张量是矩阵。
  • 形状:张量的形状是它具有的行数和列数。
  • 类型:分配给张量元素的数据类型。

要在TensorFlow中构建张量, 我们可以构建一个n维数组。这可以通过使用NumPy库或将Python n维数组转换为TensorFlow张量来轻松完成。

具有不同尺寸的张量

要构建一维张量, 我们将使用NumPy数组, 我们将通过传递内置的Python列表进行构造。

import numpy as np
tensor_1d = np.array([1.45, -1, 0.2, 102.1])

使用这种数组类似于使用内置的Python列表。主要区别在于NumPy数组还包含一些其他属性, 例如尺寸, 形状和类型。

> > print tensor1d
[   1.45   -1.      0.2   102.1 ]

> > print tensor1d[0]
1.45

> > print tensor1d[2]
0.2

> > print tensor1d.ndim
1

> > print tensor1d.shape
(4, )

> > print tensor1d.dtype
float64

使用辅助函数convert_to_tensor可以轻松地将NumPy数组转换为TensorFlow张量, 这有助于开发人员将Python对象转换为张量对象。此函数接受张量对象, NumPy数组, Python列表和Python标量。

tensor = tf.convert_to_tensor(tensor_1d, dtype=tf.float64)

现在, 如果我们将张量绑定到TensorFlow会话, 我们将能够看到转换结果。

tensor = tf.convert_to_tensor(tensor_1d, dtype=tf.float64)

with tf.Session() as session:
    print session.run(tensor)
    print session.run(tensor[0])
    print session.run(tensor[1])

输出如下:

[   1.45   -1.      0.2   102.1 ]
1.45
-1.0

我们可以通过类似的方式创建二维张量或矩阵:

tensor_2d = np.array(np.random.rand(4, 4), dtype='float32')
tensor_2d_1 = np.array(np.random.rand(4, 4), dtype='float32')
tensor_2d_2 = np.array(np.random.rand(4, 4), dtype='float32')

m1 = tf.convert_to_tensor(tensor_2d)
m2 = tf.convert_to_tensor(tensor_2d_1)
m3 = tf.convert_to_tensor(tensor_2d_2)
mat_product = tf.matmul(m1, m2)
mat_sum = tf.add(m2, m3)
mat_det = tf.matrix_determinant(m3)

with tf.Session() as session:
    print session.run(mat_product)
    print session.run(mat_sum)
    print session.run(mat_det)

张量运算

在上面的示例中, 我们介绍了一些关于向量和矩阵的TensorFlow操作。这些操作对张量执行某些计算。下表显示了哪些计算。

TensorFlow运算符 描述
tf.add x + y
减去
乘以 x * y
tf.div x / y
tf.mod x%y
tf.abs | x |
-x
tf.sign sign(x)
tf.square x * x
tf.round round(x)
tf.sqrt sqrt(x)
tf.pow X ^ÿ
tf.exp E 1 X
tf.log log(x)
最大tf max(x, y)
最小 min(x, y)
tf.cos cos(x)
tf.sin sin(x)

上表中列出的TensorFlow操作适用于张量对象, 并且是逐元素执行的。因此, 如果你想计算向量x的余弦值, TensorFlow操作将对传递的张量中的每个元素进行计算。

tensor_1d = np.array([0, 0, 0])
tensor = tf.convert_to_tensor(tensor_1d, dtype=tf.float64)
with tf.Session() as session:
    print session.run(tf.cos(tensor))

输出如下:

[ 1.  1.  1.]

矩阵运算

矩阵运算对于机器学习模型(例如线性回归)非常重要, 因为它们经常在其中使用。 TensorFlow支持所有最常见的矩阵运算, 例如乘法, 转置, 求逆, 计算行列式, 求解线性方程式等等。

接下来, 我们将解释一些矩阵运算。在涉及线性回归等机器学习模型时, 它们往往很重要。让我们写一些代码来执行基本的矩阵运算, 例如乘法, 获取转置, 获取行列式, 乘法, sol等。

下面是调用这些操作的基本示例。

import tensorflow as tf
import numpy as np

def convert(v, t=tf.float32):
    return tf.convert_to_tensor(v, dtype=t)

m1 = convert(np.array(np.random.rand(4, 4), dtype='float32'))
m2 = convert(np.array(np.random.rand(4, 4), dtype='float32'))
m3 = convert(np.array(np.random.rand(4, 4), dtype='float32'))
m4 = convert(np.array(np.random.rand(4, 4), dtype='float32'))
m5 = convert(np.array(np.random.rand(4, 4), dtype='float32'))

m_tranpose = tf.transpose(m1)
m_mul = tf.matmul(m1, m2)
m_det = tf.matrix_determinant(m3)
m_inv = tf.matrix_inverse(m4)
m_solve = tf.matrix_solve(m5, [[1], [1], [1], [1]])

with tf.Session() as session:
    print session.run(m_tranpose)
    print session.run(m_mul)
    print session.run(m_inv)
    print session.run(m_det)
    print session.run(m_solve)

转换资料

减少

TensorFlow支持各种还原。归约是通过对张量进行一个或多个操作来从张量中删除一个或多个尺寸的操作。可在此处找到当前版本的TensorFlow支持的缩减版本列表。在下面的示例中, 我们将介绍其中的一些。

import tensorflow as tf
import numpy as np

def convert(v, t=tf.float32):
    return tf.convert_to_tensor(v, dtype=t)

x = convert(
    np.array(
        [
            (1, 2, 3), (4, 5, 6), (7, 8, 9)
        ]), tf.int32)

bool_tensor = convert([(True, False, True), (False, False, True), (True, False, False)], tf.bool)

red_sum_0 = tf.reduce_sum(x)
red_sum = tf.reduce_sum(x, axis=1)

red_prod_0 = tf.reduce_prod(x)
red_prod = tf.reduce_prod(x, axis=1)

red_min_0 = tf.reduce_min(x)
red_min = tf.reduce_min(x, axis=1)

red_max_0 = tf.reduce_max(x)
red_max = tf.reduce_max(x, axis=1)

red_mean_0 = tf.reduce_mean(x)
red_mean = tf.reduce_mean(x, axis=1)

red_bool_all_0 = tf.reduce_all(bool_tensor)
red_bool_all = tf.reduce_all(bool_tensor, axis=1)

red_bool_any_0 = tf.reduce_any(bool_tensor)
red_bool_any = tf.reduce_any(bool_tensor, axis=1)


with tf.Session() as session:
    print "Reduce sum without passed axis parameter: ", session.run(red_sum_0)
    print "Reduce sum with passed axis=1: ", session.run(red_sum)

    print "Reduce product without passed axis parameter: ", session.run(red_prod_0)
    print "Reduce product with passed axis=1: ", session.run(red_prod)

    print "Reduce min without passed axis parameter: ", session.run(red_min_0)
    print "Reduce min with passed axis=1: ", session.run(red_min)

    print "Reduce max without passed axis parameter: ", session.run(red_max_0)
    print "Reduce max with passed axis=1: ", session.run(red_max)

    print "Reduce mean without passed axis parameter: ", session.run(red_mean_0)
    print "Reduce mean with passed axis=1: ", session.run(red_mean)

    print "Reduce bool all without passed axis parameter: ", session.run(red_bool_all_0)
    print "Reduce bool all with passed axis=1: ", session.run(red_bool_all)

    print "Reduce bool any without passed axis parameter: ", session.run(red_bool_any_0)
    print "Reduce bool any with passed axis=1: ", session.run(red_bool_any)

输出如下:

Reduce sum without passed axis parameter:  45
Reduce sum with passed axis=1:  [ 6 15 24]
Reduce product without passed axis parameter:  362880
Reduce product with passed axis=1:  [  6 120 504]
Reduce min without passed axis parameter:  1
Reduce min with passed axis=1:  [1 4 7]
Reduce max without passed axis parameter:  9
Reduce max with passed axis=1:  [3 6 9]
Reduce mean without passed axis parameter:  5
Reduce mean with passed axis=1:  [2 5 8]
Reduce bool all without passed axis parameter:  False
Reduce bool all with passed axis=1:  [False False False]
Reduce bool any without passed axis parameter:  True
Reduce bool any with passed axis=1:  [ True  True  True]

约简运算符的第一个参数是我们要约简的张量。第二个参数是我们要执行缩减的尺寸索引。该参数是可选的, 如果未传递, 则将在所有尺寸上执行缩小。

我们可以看一下reduce_sum操作。我们传递一个二维张量, 并希望沿尺寸1缩小它。

在我们的例子中, 结果总和为:

[1 + 2 + 3 = 6, 4 + 5 + 6 = 15, 7 + 8 + 9 = 24]

如果我们传递维度0, 则结果将是:

[1 + 4 + 7 = 12, 2 + 5 + 8 = 15, 3 + 6 + 9 = 18]

如果我们不通过任何轴, 那么结果就是以下各项的总和:

1 + 4 + 7 = 12, 2 + 5 + 8 = 15, 3 + 6 + 9 = 45

所有缩减功能均具有相似的界面, 并在TensorFlow缩减文档中列出。

分割

分段是一个过程, 其中维之一是将维映射到提供的段索引上的过程, 结果元素由索引行确定。

分段实际上是在重复索引下对元素进行分组, 因此, 例如, 在本例中, 我们对张量tens1应用了分段id [0, 0, 1, 2, 2], 这意味着在分段之后将对第一和第二个数组进行变换操作(在我们的示例中为求和), 将获得一个新数组, 其外观类似于(2, 8, 1, 0)=(2 + 0, 5 + 3, 3-2, -5 + 5)。张量tens1中的第三个元素没有被触及, 因为它没有分组在任何重复的索引中, 并且最后两个数组的累加方式与第一个元素相同。除了求和, TensorFlow还支持乘积, 均值, 最大值和最小值。

细分汇总
import tensorflow as tf
import numpy as np




def convert(v, t=tf.float32):
    return tf.convert_to_tensor(v, dtype=t)


seg_ids = tf.constant([0, 0, 1, 2, 2])
tens1 = convert(np.array([(2, 5, 3, -5), (0, 3, -2, 5), (4, 3, 5, 3), (6, 1, 4, 0), (6, 1, 4, 0)]), tf.int32)
tens2 = convert(np.array([1, 2, 3, 4, 5]), tf.int32)


seg_sum = tf.segment_sum(tens1, seg_ids)
seg_sum_1 = tf.segment_sum(tens2, seg_ids)


with tf.Session() as session:
    print "Segmentation sum tens1: ", session.run(seg_sum)
    print "Segmentation sum tens2: ", session.run(seg_sum_1)
Segmentation sum tens1:  
[[ 2  8  1  0]
 [ 4  3  5  3]
 [12  2  8  0]]
 
Segmentation sum tens2: [3 3 9]

序列工具

序列实用程序包括以下方法:

  • argmin函数, 该函数返回跨输入张量轴的最小值的索引,
  • argmax函数, 该函数返回跨输入张量轴的最大值的索引,
  • setdiff, 用于计算两个数字或字符串列表之间的差异,
  • where函数, 该函数将从两个传递的元素x或y返回元素, 这取决于传递的条件, 或者
  • 唯一函数, 它将返回一维张量中的唯一元素。

我们在下面演示一些执行示例:

import numpy as np
import tensorflow as tf

def convert(v, t=tf.float32):
    return tf.convert_to_tensor(v, dtype=t)

x = convert(np.array([
    [2, 2, 1, 3], [4, 5, 6, -1], [0, 1, 1, -2], [6, 2, 3, 0]
]))

y = convert(np.array([1, 2, 5, 3, 7]))
z = convert(np.array([1, 0, 4, 6, 2]))

arg_min = tf.argmin(x, 1)
arg_max = tf.argmax(x, 1)
unique = tf.unique(y)
diff = tf.setdiff1d(y, z)

with tf.Session() as session:
    print "Argmin = ", session.run(arg_min)
    print "Argmax = ", session.run(arg_max)

    print "Unique_values = ", session.run(unique)[0]
    print "Unique_idx = ", session.run(unique)[1]

    print "Setdiff_values = ", session.run(diff)[0]
    print "Setdiff_idx = ", session.run(diff)[1]

    print session.run(diff)[1]

输出如下:

Argmin = [2 3 3 3]
Argmax =  [3 2 1 0]
Unique_values =  [ 1.  2.  5.  3.  7.]
Unique_idx =  [0 1 2 3 4]
Setdiff_values =  [ 5.  3.  7.]
Setdiff_idx =  [2 3 4]

使用TensorFlow进行机器学习

在本节中, 我们将介绍TensorFlow的机器学习用例。第一个示例将是一种使用kNN方法对数据进行分类的算法, 第二个示例将使用线性回归算法。

k近邻

第一种算法是k最近邻(kNN)。这是一种有监督的学习算法, 它使用距离指标(例如, 欧几里得距离)对数据进行分类以进行训练。它是最简单的算法之一, 但是对于数据分类仍然非常强大。该算法的优点:

  • 训练模型足够大时可提供高精度, 并且
  • 通常对异常值不敏感, 我们不需要对数据做任何假设。

该算法的缺点:

  • 计算上昂贵, 并且
  • 需要大量内存, 需要在其中将新的分类数据添加到所有初始训练实例。
kNN概述

我们在此代码示例中将使用的距离是欧几里得, 它定义了两个点之间的距离, 如下所示:

数学方程

在此公式中, n是空间的维数, x是训练数据的向量, y是我们要分类的新数据点。

import os
import numpy as np
import tensorflow as tf

ccf_train_data = "train_dataset.csv"
ccf_test_data = "test_dataset.csv"

dataset_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../datasets'))

ccf_train_filepath = os.path.join(dataset_dir, ccf_train_data)
ccf_test_filepath = os.path.join(dataset_dir, ccf_test_data)

def load_data(filepath):
    from numpy import genfromtxt

    csv_data = genfromtxt(filepath, delimiter=", ", skip_header=1)
    data = []
    labels = []

    for d in csv_data:
        data.append(d[:-1])
        labels.append(d[-1])

    return np.array(data), np.array(labels)

train_dataset, train_labels = load_data(ccf_train_filepath)
test_dataset, test_labels = load_data(ccf_test_filepath)

train_pl = tf.placeholder("float", [None, 28])
test_pl = tf.placeholder("float", [28])

knn_prediction = tf.reduce_sum(tf.abs(tf.add(train_pl, tf.negative(test_pl))), axis=1)

pred = tf.argmin(knn_prediction, 0)

with tf.Session() as tf_session:
    missed = 0

    for i in xrange(len(test_dataset)):
        knn_index = tf_session.run(pred, feed_dict={train_pl: train_dataset, test_pl: test_dataset[i]})

        print "Predicted class {} -- True class {}".format(train_labels[knn_index], test_labels[i])

        if train_labels[knn_index] != test_labels[i]:
            missed += 1

    tf.summary.FileWriter("../samples/article/logs", tf_session.graph)

print "Missed: {} -- Total: {}".format(missed, len(test_dataset))

我们在上面的示例中使用的数据集是可以在Kaggle数据集部分中找到的数据集。我们使用了一种包含通过欧洲持卡人的信用卡进行的交易的交易。我们使用的数据没有任何清理或过滤, 并且根据Kaggle中对此数据集的描述, 它非常不平衡。数据集包含31个变量:时间, V1, …, V28, 数量和类别。在此代码示例中, 我们仅使用V1, …, V28和Class。类别将欺诈性交易标记为1, 而非欺诈性交易标记为0。

该代码示例主要包含我们在前面各节中描述的内容, 但我们引入了加载数据集的功能。函数load_data(filepath)将采用CSV文件作为参数, 并将返回一个元组, 其中包含以CSV定义的数据和标签。

在该功能的正下方, 我们为测试和训练后的数据定义了占位符。在预测模型中使用经过训练的数据来解析需要分类的输入数据的标签。在我们的案例中, kNN使用欧几里得距离来获取最近的标签。

错误分类率可以通过简单地除以分类器的数目除以样本总数得出, 该样本在本例中为该数据集的总数为0.2(即分类器为我们提供了20%的测试数据的错误数据标签)。

线性回归

线性回归算法寻找两个变量之间的线性关系。如果我们将因变量标记为y, 将自变量标记为x, 那么我们将尝试估算函数y = Wx + b的参数。

线性回归是应用科学领域中一种广泛使用的算法。该算法允许在实现中添加机器学习的两个重要概念:成本函数和用于寻找函数最小值的梯度下降方法。

使用此方法实现的机器学习算法必须将y的值预测为x的函数, 其中线性回归算法将确定值W和b, 这实际上是未知数, 并且是在整个训练过程中确定的。选择成本函数, 通常使用均方误差, 其中梯度下降是用于找到成本函数的局部最小值的优化算法。

梯度下降法只是局部函数最小值, 但可以在找到全局最小值时使用, 方法是找到一个局部最小值并随机选择一个新的起点, 然后重复多次此过程。如果函数的最小值的数量有限并且尝试的次数非常多, 则很有可能在某个时刻发现全局最小值。有关此技术的更多详细信息, 我们将在引言部分中提到的文章中保留。

import tensorflow as tf
import numpy as np

test_data_size = 2000
iterations = 10000
learn_rate = 0.005

def generate_test_values():
    train_x = []
    train_y = []

    for _ in xrange(test_data_size):
        x1 = np.random.rand()
        x2 = np.random.rand()
        x3 = np.random.rand()
        y_f = 2 * x1 + 3 * x2 + 7 * x3 + 4
        train_x.append([x1, x2, x3])
        train_y.append(y_f)

    return np.array(train_x), np.transpose([train_y])

x = tf.placeholder(tf.float32, [None, 3], name="x")
W = tf.Variable(tf.zeros([3, 1]), name="W")
b = tf.Variable(tf.zeros([1]), name="b")
y = tf.placeholder(tf.float32, [None, 1])

model = tf.add(tf.matmul(x, W), b)

cost = tf.reduce_mean(tf.square(y - model))
train = tf.train.GradientDescentOptimizer(learn_rate).minimize(cost)

train_dataset, train_values = generate_test_values()

init = tf.global_variables_initializer()

with tf.Session() as session:
    session.run(init)

    for _ in xrange(iterations):

        session.run(train, feed_dict={
            x: train_dataset, y: train_values
        })

    print "cost = {}".format(session.run(cost, feed_dict={
        x: train_dataset, y: train_values
    }))

    print "W = {}".format(session.run(W))
    print "b = {}".format(session.run(b))

输出如下:

cost = 3.1083032809e-05
W = [[ 1.99049103]
 [ 2.9887135 ]
 [ 6.98754263]]
b = [ 4.01742554]

在上面的示例中, 我们有两个新变量, 我们分别称为cost和train。通过这两个变量, 我们定义了一个优化器, 我们要在训练模型中使用该优化器, 并希望将其最小化。

最后, W和b的输出参数应与generate_test_values函数中定义的参数相同。在第17行中, 我们实际上定义了一个函数, 用于生成线性数据点以进行训练, 其中w1 = 2, w2 = 3, w3 = 7和b = 4。上例中的线性回归是多元变量, 其中使用了多个自变量。

总结

从本TensorFlow教程中可以看出, TensorFlow是一个功能强大的框架, 可以轻松地使用数学表达式和多维数组, 这是机器学习中必不可少的。它还抽象了执行数据图和缩放的复杂性。

随着时间的流逝, TensorFlow变得越来越流行, 现在被开发人员用来使用深度学习方法来解决问题, 例如图像识别, 视频检测, 诸如情感分析之类的文本处理等。与任何其他库一样, 你可能需要一些时间才能使用TensorFlow构建的概念。而且, 一旦这样做, 在文档和社区支持的帮助下, 将问题表示为数据图并用TensorFlow解决即可, 使大规模机器学习的过程不再那么繁琐。

赞(0)
未经允许不得转载:srcmini » TensorFlow入门:机器学习权威教程

评论 抢沙发

评论前必须登录!