python版本TensorFlow神经网络教程

AI 概述
TensorFlow是Google开源的机器学习库,支持CPU、GPU和TPU,可通过多种方式安装。其核心API组件包括张量、图和会话,张量有常量、变量和占位符三种类型。文章以IRIS数据集为例,使用核心API构建三层前馈神经网络,比较了三种不同隐藏层节点数的网络架构,通过2000次迭代训练模型,绘制损失函数变化图,并在测试集上评估模型,实现了较高准确率。理解TensorFlow编码理念需时间,但构建机器学习应用十分方便。
目录
文章目录隐藏
  1. 安装 TensorFlow
  2. 核心 API 组件
  3. 神经网络模型
  4. 结论

TensorFlow 神经网络教程

TensorFlow 是一个开源的机器学习库。它是 Google Brain 的第二代系统,取代了闭源的 DistBelief,并且被 Google 用于研究和生产应用。TensorFlow 应用程序可以用几种语言编写:Python、Go、Java 和 C。本文关注的是 Python 版本,并且探讨了该库的安装、基本低级组件,以及从头开始构建一个前馈神经网络,以在真实数据集上进行学习。

深度学习神经网络的训练时间在更复杂的场景中常常是一个瓶颈。由于神经网络以及其他机器学习算法大多使用矩阵乘法,因此在图形处理单元(GPUs)上运行它们比在标准中央处理单元(CPUs)上快得多。

TensorFlow 支持 CPU 和 GPU,谷歌甚至为其云计算专门制造了硬件,称为张量处理单元 (TPU),它在不同的处理单元中产生最佳性能。

安装 TensorFlow

虽然 TPU 只能在云端使用,但 TensorFlow 可以在本地计算机上安装,目标可以是 CPU 或 GPU 处理架构。要使用 GPU 版本,您的计算机必须配备 NVIDIA 显卡,并且还要满足一些更多要求。

基本上,至少有 5 种不同的安装选项,使用:virtualenv、pip、Docker、Anaconda 和从源安装。

  • 使用 virtualenv 和 Docker 可以让我们在与您的其他 Python 库隔离的环境中安装 TensorFlow。
  • Anaconda 是一个包含大量科学计算库的 Python 发行版,包括 TensorFlow。
  • pip 被认为是 Python 软件包的“原生”安装程序,无需使用任何单独的环境。
  • 最后,从源码安装需要通过 Git,并且是选择特定软件版本的最佳方式,当前 TensorFlow 的稳定版本是 r1.4。

通过 virtualenv 和 pip 来安装。以下是你在 Ubuntu 机器上获取它的方法:

# Install pip
sudo apt-get install python-pip python-dev   # Python 2.7
sudo apt-get install python3-pip python3-dev # Python 3.x

在 Ubuntu 和 Mac OSX 机器上安装 TensorFlow:

# CPU support
pip install tensorflow      # Python 2.7
pip3 install tensorflow     # Python 3.x

# GPU support
pip install tensorflow-gpu  # Python 2.7
pip3 install tensorflow-gpu # Python 3.x

上面命令在 Windows 机器上也可以使用,但仅适用于 Python 3.5.x 和 3.6.x 版本。

在单独的环境中安装 TensorFlow 可以通过 virtualenv 或 conda(是 Anaconda 的一部分)来完成。

总体过程与上述步骤相同,只是这次你需要首先创建并激活一个新的环境,方法如下:

virtualenv --system-site-packages ~/tensorflow
source ~/tensorflow/bin/activate

这将确保所有所需的包与您系统上全局安装的包分开。

核心 API 组件

有多种应用程序编程接口(API)可用于 TensorFlow 编程。最底层的一个被称为核心层,它与基本组件(张量、图和会话)一起工作。

更高级别的 API,如tf.estimator,旨在简化工作流程并自动化数据集管理、学习、评估等过程。

Core API 的全部要点是构建一个计算图,该图包含一系列操作,这些操作被组织成节点图。每个节点可能有多个张量(基本数据结构)作为输入,并对它们进行操作以计算输出,之后这个输出可能在多层网络中作为其他节点的输入。这种类型的架构适用于机器学习应用,例如神经网络。

张量

张量是 TensorFlow 中的基本数据结构,用于存储任意维度的数据,类似于 NumPy 中的多维数组。张量有三种基本类型:常量、变量和占位符。

  • 常量 是不可变的张量类型。它们可以被视为没有输入的节点,输出它们内部存储的单一值。
  • 变量是在图运行期间其值可以改变的张量的可变类型。在机器学习应用中,变量通常存储需要优化的参数(例如神经网络中节点之间的权重)。在运行图之前,必须通过显式调用特殊操作来初始化变量。
  • 占位符是存储来自外部来源的数据的张量。它们代表了一个“承诺”,即在运行图时会提供一个值。在机器学习应用中,占位符通常用于将数据输入到学习模型中。

以下几行代码展示了三种张量类型:

import tensorflow as tf

tf.reset_default_graph()

# 定义一个占位符
a = tf.placeholder("float", name='pholdA')
print("a:", a)

# 定义一个变量
b = tf.Variable(2.0, name='varB')
print("b:", b)

# 定义一个常量
c = tf.constant([1., 2., 3., 4.], name='consC')
print("c:", c)

结果:

a: Tensor("pholdA:0", dtype=float32)
b: <tf.Variable 'varB:0' shape=() dtype=float32_ref>
c: Tensor("consC:0", shape=(4,), dtype=float32)

请注意,张量在此时尚未包含值,其值只有在图在会话中运行时才可用。

图表

此时图中只包含不连接的树张量。让我们对我们的张量进行一些操作:

d = a * b + c
d
<tf.Tensor 'add:0' shape=<unknown> dtype=float32>

结果输出再次是一个名为’add’的张量,现在我们的模型看起来如下图所示。你可以使用 TensorFlow 内置的特性TensorBoard来探索你的图以及其他的参数。

TensorFlow 神经网络教程
包含乘法和加法的 TensorFlow 图

另一个有用的工具会打印出其中的所有操作。

# 调用默认图
graph = tf.get_default_graph()

# 图中的打印操作
for op in graph.get_operations():
    print(op.name)

结果:

pholdA
varB/initial_value
varB
varB/Assign
varB/read
consC
mul
add

会话

最后,我们的图应该在会话中运行。请注意,变量在之前已经被初始化,而占位符张量通过feed_dict属性接收具体的值。

# 初始化变量
init = tf.global_variables_initializer()

# 运行一个会话并计算 d
sess = tf.Session()
sess.run(init)
print(sess.run(d, feed_dict={a: [[0.5], [2], [3]]}))
sess.close()

结果:

[[  2.   3.   4.   5.]
 [  5.   6.   7.   8.]
 [  7.   8.   9.  10.]]

上面的示例是一个学习模型的简化版本。它展示了基本tf组件如何在图中组合并在会话中运行。让我们了解到了操作如何在不同形状的张量上运行。

下面,我们将使用核心 API 构建一个用于真实数据机器学习的神经网络。

神经网络模型

在接下来这一部分,我们使用 TensorFlow 的核心组件从头开始构建一个前馈神经网络。我们比较了三种神经网络架构,这些架构将在单个隐藏层中的节点数量上有所不同。

IRIS 数据集

我们使用简单的IRIS 数据集,该数据集由 150 个植物样本组成,每个样本都有 4 个维度(作为输入特征)和其类型(需要预测的输出值)。一个植物可以属于三种可能的类型中的一个(setosa, virginica 和 versicolor)。首先,我们从 TensorFlow 的网站上下载数据 – 它被分为训练集和测试集,分别包含 120 个和 30 个样本。

# 导入所需的库
import numpy as np
import pandas as pd
import tensorflow as tf
import urllib.request as request
import matplotlib.pyplot as plt

# 下载数据集
IRIS_TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv"
IRIS_TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"

names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'species']
train = pd.read_csv(IRIS_TRAIN_URL, names=names, skiprows=1)
test = pd.read_csv(IRIS_TEST_URL, names=names, skiprows=1)

# 训练和测试输入数据
Xtrain = train.drop("species", axis=1)
Xtest = test.drop("species", axis=1)

# 将目标值编码为二进制('one-hot'风格)表示
ytrain = pd.get_dummies(train.species)
ytest = pd.get_dummies(test.species)

模型与学习

我们的神经网络的输入层和输出层的形状将对应于数据的形状,即输入层将包含四个神经元,代表四个输入特征,而输出层将包含三个神经元,因为使用了三个位来以one-hot方式编码植物种类。例如,’setosa’种类可以用向量[1, 0, 0]编码,’virginica’用[0, 1, 0]编码等。

我们选择隐藏层神经元的数量为三个值:5、10 和 20,从而得到网络规模为(4-5-3)、(4-10-3)和(4-20-3)。这意味着,例如,我们的第一个网络将有 4 个输入神经元、5 个“隐藏”神经元和 3 个输出神经元。

三层前馈神经网络
三层前馈神经网络

下面的代码我定义了一个函数,在这个函数中我们创建模型,定义一个需要最小化的损失函数,并运行一个包含 2000 次迭代的会话来学习最佳权重W_1W_2。如前面所述,输入和输出矩阵被传入tf.placeholder张量,权重被表示为变量,因为它们在每次迭代中的值都会改变。损失函数被定义为我们预测y_est和实际物种类型的均方误差y,我们使用的激活函数是sigmoid。该create_train_model函数返回学习到的权重并打印出损失函数的最终值。

# 创建并训练一个基于 TensorFlow 的神经网络模型
def create_train_model(hidden_nodes, num_iters):
    
    # 重置图表
    tf.reset_default_graph()

    # 输入和输出数据的占位符
    X = tf.placeholder(shape=(120, 4), dtype=tf.float64, name='X')
    y = tf.placeholder(shape=(120, 3), dtype=tf.float64, name='y')

    # 网络三层之间两组权重的变量
    W1 = tf.Variable(np.random.rand(4, hidden_nodes), dtype=tf.float64)
    W2 = tf.Variable(np.random.rand(hidden_nodes, 3), dtype=tf.float64)

    # 创建神经网络图
    A1 = tf.sigmoid(tf.matmul(X, W1))
    y_est = tf.sigmoid(tf.matmul(A1, W2))

    # 定义一个损失函数
    deltas = tf.square(y_est - y)
    loss = tf.reduce_sum(deltas)

    # 定义一个运行方案以最大程度减少损失
    optimizer = tf.train.GradientDescentOptimizer(0.005)
    train = optimizer.minimize(loss)

    # 初始化变量并运行会话
    init = tf.global_variables_initializer()
    sess = tf.Session()
    sess.run(init)

    # Go through num_iters iterations
    for i in range(num_iters):
        sess.run(train, feed_dict={X: Xtrain, y: ytrain})
        loss_plot[hidden_nodes].append(sess.run(loss, feed_dict={X: Xtrain.as_matrix(), y: ytrain.as_matrix()}))
        weights1 = sess.run(W1)
        weights2 = sess.run(W2)
        
    print("loss (hidden nodes: %d, iterations: %d): %.2f" % (hidden_nodes, num_iters, loss_plot[hidden_nodes][-1]))
    sess.close()
    return weights1, weights2

我们来构建这三种网络架构,并绘制损失函数随迭代次数的变化图。

# 对 3 种不同的网络架构进行训练: (4-5-3) (4-10-3) (4-20-3)

# 绘制损失函数随迭代次数的变化图
num_hidden_nodes = [5, 10, 20]
loss_plot = {5: [], 10: [], 20: []}
weights1 = {5: None, 10: None, 20: None}
weights2 = {5: None, 10: None, 20: None}
num_iters = 2000

plt.figure(figsize=(12,8))
for hidden_nodes in num_hidden_nodes:
    weights1[hidden_nodes], weights2[hidden_nodes] = create_train_model(hidden_nodes, num_iters)
    plt.plot(range(num_iters), loss_plot[hidden_nodes], label="nn: 4-%d-3" % hidden_nodes)
    
plt.xlabel('Iteration', fontsize=12)
plt.ylabel('Loss', fontsize=12)
plt.legend(fontsize=12)
loss (hidden nodes: 5, iterations: 2000): 31.82
loss (hidden nodes: 10, iterations: 2000): 5.90
loss (hidden nodes: 20, iterations: 2000): 5.61

<matplotlib.legend.Legend at 0x123b157f0>
不同网络架构在 2000 次迭代中的损失函数
不同网络架构在 2000 次迭代中的损失函数。

我们可以看到,具有 20 个隐藏神经元的网络需要更长时间才能达到最小值,这归因于其更高的复杂性。具有 5 个隐藏神经元的网络卡在了一个局部最小值,不会给出好的结果。

无论如何,对于像 Iris 这样的简单数据集,即使是一个有 5 个隐藏神经元的小网络也应该能够学习到一个良好的模型。在我们的情况下,模型卡在局部极小值是一个偶然事件,如果我们反复运行代码,这种情况不会经常发生。

模型评估

最后,让我们评估我们的模型。我们使用学到的权重 W_1 和 W_2 并前向传播测试集的示例。准确率指标定义为正确预测示例的百分比。

# 在测试集上评估模型
X = tf.placeholder(shape=(30, 4), dtype=tf.float64, name='X')
y = tf.placeholder(shape=(30, 3), dtype=tf.float64, name='y')

for hidden_nodes in num_hidden_nodes:

    # 前向传播
    W1 = tf.Variable(weights1[hidden_nodes])
    W2 = tf.Variable(weights2[hidden_nodes])
    A1 = tf.sigmoid(tf.matmul(X, W1))
    y_est = tf.sigmoid(tf.matmul(A1, W2))

    # 计算预测输出
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)
        y_est_np = sess.run(y_est, feed_dict={X: Xtest, y: ytest})

    # 计算预测准确率
    correct = [estimate.argmax(axis=0) == target.argmax(axis=0) 
               for estimate, target in zip(y_est_np, ytest.as_matrix())]
    accuracy = 100 * sum(correct) / len(correct)
    print('Network architecture 4-%d-3, accuracy: %.2f%%' % (hidden_nodes, accuracy))

结果:

Network architecture 4-5-3, accuracy: 90.00%
Network architecture 4-10-3, accuracy: 96.67%
Network architecture 4-20-3, accuracy: 96.67%

总的来说,我们使用一个简单的前馈神经网络实现了相当高的准确率,这在使用相当小的数据集时尤其令人惊讶。

结论

在本文中,我们介绍了用于机器学习的 TensorFlow 库,提供了简要的安装指南,介绍了 TensorFlow 低级核心 API 的基本组件:张量、图和会话,并最终构建了一个用于鸢尾花数据集真实数据分类的神经网络模型。

一般来说,理解 TensorFlow 的编码philosophy会花费一些时间,因为这是一个符号库,但一旦你熟悉了核心组件,它对于构建机器学习应用程序来说是非常方便的。在这篇文章中,我们使用了低级核心 API 来展示基本组件并完全控制模型,但通常使用更高级的 API(例如tf.estimator)或外部库(例如Keras)会更简单。

以上关于python版本TensorFlow神经网络教程的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » python版本TensorFlow神经网络教程

发表回复