使用Python和TensorFlow创建您的第一个神经网络

目录

您的第一个神经网络

让我们开始编码

卷积层

激活层

池化层

到目前为止可视化我们的模型

扁平和密集的层

分类层

训练模型

测试出来

结论


神经网络是许多现代人工智能(AI)应用的核心。人工神经网络(ANN)是一个松散地基于大脑结构的模型:它由称为神经元的连接元素组成,每个连接都有一个数字权重。卷积神经网络(CNN)是特殊类型的人工神经网络,可以解决计算机视觉(CV)问题,例如图像分类、对象检测和一般识别。

CNN的主要构建块是卷积层。这些层由小过滤器组成,这些过滤器提取图像中的相关特征,每一层根据前几层的输入提取更抽象的特征——一直到最终结果。这种方法非常有效,以至于最先进的CNN在从一大集中准确识别不同人的面孔方面可以胜过人类。

在本文中,我们将向您展示如何从头开始创建非常简单的图像分类CNN。我们将使用以下工具:

我们假设你熟悉Python并具有神经网络的基本知识,可以遵循本指南。

您可以使用以下Anaconda命令安装软件包的Intel发行版:

conda install -c intel intelpython
conda install -c intel tensorflow

我们建议您在工作机器上使用这些工具设置深度学习(DL)环境,如使用 Python和Anaconda构建深度学习环境一文中所述。

您的第一个神经网络

我们将使用PythonTensorFlow创建一个CNN,该CNN获取从09的类型数字的小图像,并输出它是什么数字。这是一个很好的用例,它将为你理解TensorFlow框架的关键原则打下良好的基础。

我们将使用Intel Optimization for TensorFlow,它可以优化在Intel®架构上运行时的TensorFlow性能。此优化的核心是Intel® oneAPI深度神经网络库 (oneDNN),它是一组用于DL应用的构建模块,包括卷积层和池化层任何CNN模型的基本组件。该库是Intel® oneAPI基础工具包的一部分,该工具包是一组用于开发跨不同架构的高性能人工智能、机器学习(ML)和其他应用的库。

所有oneAPI 组件的编程模型是统一的,因此它可以使用相同的代码在CPUGPUFPGA上进行部署。Intel继续开发oneAPI组件,以支持新的处理器,并通过利用新的指令集扩展来优化性能。

使用oneDNN原语作为核心TensorFlow算法的后端实现可为DNN模型提供更高的性能,并确保性能针对较新的处理器架构进行优化。

让我们开始编码

让我们从简单的CNN开始。该神经网络使用键入的数字对图像进行分类。网络的输入将是28 × 28像素的小灰度图像,输出将是09的每个数字的概率数组。第一步是构建CNNTensorFlow模型。我们将使用 Keras API来完成此任务,因为在创建第一个神经网络时更容易理解。

DL环境中编写并运行以下代码:

import os
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '1'

import tensorflow
tensorflow.__version__

代码的前两行打开会话的oneDNN 优化,最后两行检查TensorFlow框架的版本。请注意,从 TensorFlow 2.9 开始,oneDNN优化默认处于打开状态,如您希望在没有这些优化的情况下测试性能,则必须将其设置为 0

接下来,使用输入层初始化CNN模型:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input

model = Sequential()
inp = Input(shape=(28, 28, 1))
model.add(inp)

我们为CNN使用了“顺序”模型。该模型具有最简单的结构,具有顺序层,其中一层的输出是下一层的输入。然后,我们将输入层添加到模型中。所有TensorFlow模型都需要知道输入数据类型。在我们的例子中,这是一个三维为28281的张量。此输入对应于具有一个颜色通道的28 × 28像素的图像(灰度图像)。

卷积层

让我们继续编写以下代码:

from tensorflow.keras.layers import Conv2D
conv = Conv2D(32, (5, 5), padding="same", strides=(1, 1))
model.add(conv)

该代码初始化卷积层“Conv2D”并将其放置在第一个输入层之后。这个卷积层是我们神经网络的关键元素。它负责从输入图像中提取几何特征,然后由下一层使用。我们创建了具有32个大小为(55)的内核(或过滤器)的层。接下来的两个参数指定如何将这些滤镜应用于输入图像:步幅指定垂直和水平偏移,填充指定是否必须使用额外的像素填充输入图像以处理输入数据。

激活层

任何卷积层后面都应该有一个激活层。该层为模型引入了激活函数,该函数根据神经元的权重和输入控制神经元是否会触发(提供输出)。最近深度神经网络(DNN)最流行的激活函数是整流线性单元ReLU)。以下代码将激活层添加到我们的模型中:

from tensorflow.keras.layers import Activation
conv_act = Activation("relu")
model.add(conv_act)

池化层

DNN的另一个重要元素是池化操作。该操作的目标是减少将馈送到下一层的数据的空间维度。我们将使用最大池化操作,因为它已被证明在CNN模型中对特征图进行下采样是有效的。

from tensorflow.keras.layers import MaxPooling2D

pool = MaxPooling2D((4, 4))
model.add(pool)

添加的MaxPooling2D图层初始化为池大小(4 4)。这意味着对于垂直轴和水平轴,图层数据输出的空间维度都会减少四倍。因此,在第一层之后,最初的28 × 28像素图像将减少为7 × 7的数字输出,依此类推。

池化操作有两个目的。一种是使模型独立于提取的特征位置的细微差异,另一种是减少下一个处理层的数据量,从而使模型更快。

到目前为止可视化我们的模型

现在,我们的模型由四层组成:输入层、卷积层、激活层和池化层。在模型构建的任何阶段,我们都可以通过调用model.summary方法来查看有关其结构的信息。该方法的输出如下图所示:

我们可以看到有关每个图层的输出形状的信息。例如,在池化层之后,我们可以看到输出的空间维度从28减少到7四倍,正如预期的那样。另一个重要的信息是每层中可训练参数的数量。我们模型中的卷积层有832个这样的参数。可训练参数是图层的系数(权重),其值随训练过程进行调整。它们的数量直接影响训练时间:数量越大,训练过程越长。

扁平和密集的层

让我们继续使用以下代码构建模型:

from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense

flat = Flatten()
model.add(flat)
   	
dense = Dense(128)
model.add(dense)

dense_act = Activation("sigmoid")
model.add(dense_act)

在此之后,我们的模型输出以下摘要:

上面的代码添加了一个扁平化层,该层将三维张量(7732 从池化层转换为具有1568个分量的平面向量。然后,它将一个具有128个神经元的密集层和一个sigmoid激活函数添加到模型中。这就是所谓的隐藏全连接层。它位于最后一个分类层之前,其目标是在神经模型的最后一部分构建多层感知器(MLP),因为MLP通常是分类神经网络中的最后一个块。

分类层

模型的最后一层必须是具有10个输出值的分类层:每个数字的概率。我们将使用具有10个神经元的密集层和Softmax激活函数作为现代分类器模型的常见选择。

out = Dense(10)
model.add(out)

out_act = Activation("softmax")
model.add(out_act)

我们模型的最终摘要如下图所示:

训练模型

模型创建的下一阶段是加载训练和验证数据集。我们将使用一个小数据集1,训练数据中的每个数字有100个图像,验证数据中每个数字有10个图像。下载数据集并将其提取到工作文件夹。我们使用ImageDataGenerator类,它是一个实用程序类,提供数据集加载、图像预处理和数据增强等功能。若要加载数据集,请在创建模型后立即运行以下代码:

from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(rescale=1.0/255.0)

train_dataset = datagen.flow_from_directory("<your-train-data-file-path-here>", color_mode='grayscale', target_size=(28, 28), class_mode="categorical")
val_dataset = datagen.flow_from_directory("<your-validation-data-file-path-here>", color_mode='grayscale', target_size=(28, 28), class_mode="categorical")

这会使用rescale参数初始化生成器,以将图像数据规范化为[01.0]的间隔。加载数据时,我们将类模式指定为分类模式,以便为分类问题生成适当的数据。

最后一步是使用数据集训练我们的模型

from tensorflow.keras.optimizers import SGD

opt_method = SGD(learning_rate=0.1)
model.compile(optimizer=opt_method, loss="categorical_crossentropy", metrics=["accuracy"])

history = model.fit(train_dataset, validation_data=val_dataset, epochs=10)

我们使用SGD优化器,这应该是训练新模型时的默认选择。categorical_crossentropy是多类分类问题的推荐损失函数。对于我们的简单模型和小数据集来说,10个训练epoch的小计数就足够了。以下是训练过程的输出:

模型的最终准确率为训练数据的96.6%,验证数据的最终准确率为94%。请注意,由于过程的非确定性,使用相同的数据训练相同的模型可能会产生略有不同的结果。

测试出来

现在我们可以测试模型并为单个图像运行它:

from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.preprocessing.image import img_to_array

img_file = "<your-test-data-file-path-here>\\7.png"
img = load_img(img_file, color_mode="grayscale")
img_array = img_to_array(img)
in_data = img_array.reshape((1, 28, 28, 1))/255.0

prob = model.predict(in_data)[0]
digit = prob.argmax()
digit_prob = prob[digit]

print(prob)
print("Predicted digit = " + str(digit))
print("Digit probability = " + str(digit_prob))

我们得到以下输出:

[7.85533484e-05 1.45643018e-03 1.24442745e-02 1.29656109e-03
 1.41729815e-05 4.06741965e-05 4.37598487e-07 9.83559847e-01
 3.04310001e-04 8.04647047e-04]
Predicted digit = 7
Digit probability = 0.98355985

该模型正确预测图像包含数字7,概率约为98%

祝贺!您已经创建了第一个神经网络。如果要保存已训练的模型,可以使用以下命令:

model.save("<your-model-file-path-here>")

结论

在本文中,我们学习了如何使用TensorFlow框架创建一个非常简单的神经网络。作为一个实际的例子,我们构建了一个CNN,用于用键入的数字对图像进行分类。我们提供了构建包含两个块的顺序模型的步骤。第一个块包含一个卷积层,充当特征提取器。第二个块是一个带有一个隐藏的全连接层的感知器,是一种常见的分类器,通常用于现代DNN

在训练模型和运行推理时,我们使用Intel TensorFlow 优化加快了周转时间。此版本的框架由oneDNN库提供支持,该库是用于AI应用程序的oneAPI工具包的一部分。

虽然我们创建了一个非常简单的神经网络,但这演示了使用TensorFlow框架构建和训练DNN是多么容易。现代最先进的模型包含数百甚至数千层,TensorFlow框架允许您轻松创建它们,而Intel TensorFlow优化可加快训练和推理运行。

本文最初发表于 Create Your First Neural Network with Python and TensorFlow

https://www.codeproject.com/Articles/5344692/Create-Your-First-Neural-Network-with-Python-and-T

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值