在TensorFlow中训练CNN详细步骤示例

本文概述

  • 第1步:上传数据集
  • 定义CNN(卷积神经网络)
  • CNN架构
  • 步骤2:输入层
  • 步骤3:卷积层
  • 步骤4:汇聚层
  • 步骤5:池化层和第二卷积层
  • 步骤6:完全连接(密集)层
  • 步骤7:Logits层
MNIST数据库(美国国家标准技术研究院的改良数据库)是一个广泛的手写数字数据库, 用于训练各种图像处理系统。它是通过” 重新整合” MNIST原始数据集中的样本创建的。
如果我们熟悉Connects的构建基块, 就可以使用TensorFlow来构建一个。我们使用MNIST数据集进行图像分类。
准备数据与上一教程中的相同。我们可以运行代码, 直接跳入CNN的体系结构。
在这里, 我们正在Google Colab(机器学习的在线编辑器)中执行代码。
我们可以通过以下链接转到TensorFlow编辑器:https://colab.research.google.com
【在TensorFlow中训练CNN详细步骤示例】这些是用于训练CNN(卷积神经网络)的步骤。
步骤
第1步:上传数据集
步骤2:输入层
步骤3:卷积层
步骤4:汇聚层
步骤5:卷积层和池化层
步骤6:密集层
步骤7:Logit层
在TensorFlow中训练CNN详细步骤示例

文章图片
第1步:上传数据集 scikit可提供MNIST数据集, 以便在此URL(统一资源定位符)中进行学习。我们可以下载它并将其存储在我们的下载文件中。我们可以使用fetch_mldata(” MNIST原始” )上传它。
创建测试/训练集
我们需要将数据集拆分为train_test_split。
缩放功能
最后, 我们借助MinMax Scaler缩放功能。
import numpy as npimport tensorflow as tffrom sklearn.datasets import fetch_mldata#Change USERNAME by the username of the machine##Windows USERmnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')## Mac Usermnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')print(mnist.data.shape)print(mnist.target.shape)from sklearn.model_selection import train_test_splitA_train, A_test, B_train, B_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=45)B_train= B_train.astype(int)B_test= B_test.astype(int)batch_size =len(X_train)print(A_train.shape, B_train.shape, B_test.shape )## rescalefrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()# Train the DatasetX_train_scaled = scaler.fit_transform(A_train.astype(np.float65))

#test the datasetX_test_scaled = scaler.fit_transform(A_test.astype(np.float65))feature_columns = [tf.feature_column.numeric_column('x', shape=A_train_scaled.shape[1:])]X_train_scaled.shape[1:]

定义CNN(卷积神经网络) 与传统神经网络的全局模式相比, CNN使用任何图像像素上的滤镜来学习详细模式。要创建CNN, 我们必须定义:
  1. 卷积层:将过滤器的数量应用于特征图。卷积后, 我们需要使用中继激活功能为网络添加非线性。
  2. 汇聚层:《公约》之后的下一步是对最大设施进行缩减采样。目的是减少特征图的移动性, 以防止过度拟合并提高计算速度。最大池化是一种传统技术, 该技术将要素图拆分为子字段, 并且仅保留最大值。
  3. 完全连接的层:过去层中的所有神经元都与其他下一层相关联。 CNN已根据卷积层的特征对标签进行了分类, 并通过任何合并层进行了缩减。
CNN架构
  • 卷积层:应用14个5× 5滤镜(提取5× 5像素子区域),
  • 池化层:这将使用2× 2过滤器执行最大池化, 步幅为2(指定池化区域不重叠)。
  • 卷积层:应用36个5× 5滤镜, 并具有ReLU激活功能
  • 池化层:同样, 使用2× 2过滤器执行最大池化, 步幅为2。
  • 1, 764个神经元, 辍学正规化率为0.4(其中任何给定元素在训练中被丢弃的概率为0.4)
  • 密集层(登录层):有十个神经元, 每个数字目标类别(0-9)一个。
创建CNN时要使用的重要模块:
  1. Conv2d()。用过滤器的数量, 过滤器内核的大小, 填充和像参数一样的激活函数构造一个二维卷积层。
  2. max_pooling2d()。使用最大池化算法构造一个二维池化层。
  3. 密集()。使用隐藏的图层和单位构造一个密集的图层
我们可以定义一个函数来构建CNN。
让我们详细了解如何在将所有内容包装到函数中之前构造每个构造块。
步骤2:输入层
#Input layerdef cnn_model_fn(mode, features, labels):input_layer = tf.reshape(tensor= features["x"], shape=[-1, 26, 26, 1])

我们需要用数据的形状定义一个张量。为此, 我们可以使用模块tf.reshape。在此模块中, 我们需要声明张量以重塑和成形张量。第一个参数是数据的特征, 它是在函数的参数中定义的。
图片具有宽度, 高度和通道。 MNIST数据集是大小为28× 28的单色图片。我们在shape参数中将批处理大小设置为-1, 以便采用特征[” x” ]的形状。好处是可以将批量大小调整为超参数。如果批量大小为7, 则张量将馈送5488个值(28 * 28 * 7)。
步骤3:卷积层
# first CNN Layerconv1 = tf.layers.conv2d( inputs= input_layer, filters= 18, kernel_size= [7, 7], padding="same", activation=tf.nn.relu)

第一卷积层具有18个滤镜, 内核大小为7× 7, 且填充相同。相同的填充使输出张量和输入张量具有相同的宽度和高度。 TensorFlow将在行和列中添加零以确保大小相同。
我们使用Relu激活功能。输出大小将为[28、28和14]。
步骤4:汇聚层 卷积之后的下一步是合并计算。池计算将减少数据的扩展。我们可以使用大小为3× 3, 步幅为2的模块max_pooling2d。我们使用上一层作为输入。输出大小可以为[batch_size, 14、14和15]。
##first Pooling Layer pool1 = tf.layers.max_pooling2d (inputs=conv1, pool_size=[3, 3], strides=2)

步骤5:池化层和第二卷积层 第二个CNN恰好具有32个过滤器, 输出大小为[batch_size, 14, 14, 32]。池化层的大小与前面相同, 输出形状为[batch_size, 14、14和18]。
conv2 = tf.layers.conv2d(inputs=pool1, filters=36, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)pool2 = tf.layers.max_pooling2d (inputs=conv2, pool_size=[2, 2], strides=2).

步骤6:完全连接(密集)层 我们必须定义完全连接的层。在与密集层组合之前, 必须先压缩特征图。我们可以使用尺寸为7 * 7 * 36的模块重塑。
密集层将连接1764个神经元。我们添加了Relu激活功能, 并且可以添加Relu激活功能。我们以0.3的比率添加一个辍学正则化项, 这意味着30%的权重将为0。辍学仅在训练阶段发生。 cnn_model_fn()具有参数模式, 用于声明模型是否需要训练或评估。
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)

步骤7:Logits层 最后, 我们用模型的预测定义最后一层。输出形状等于批处理大小12, 等于图层中图像的总数。
#Logit Layerlogits = tf.layers.dense(inputs=dropout, units=12)

我们可以创建一个包含类和每个类的可能性的字典。如果logit层, 模块将使用tf.argmax()返回最大值。 softmax函数返回每个类别的概率。
predictions= { # Generate predictions "classes":tf.argmax(input=logits, axis=1), "probabilities":tf.nn.softmax (logits, name="softmax_tensor")}

当模式设置为预测时, 我们只想返回字典预测。我们添加这些代码以显示预测。
If mode== tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

下一步包括计算模型损失。可以使用以下代码轻松计算损失:
# Calculate Loss (for both EVAL and TRAIN modes)loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

最后一步是优化模型, 即找到最佳的权重值。为此, 我们使用学习速率为0.001的梯度下降优化器。目的是减少损失。
optimizer= tf.train.GradientDescentOptimizer(learning_rate=0.0001)train_op= optimizer.minimize(loss=loss, global_step=tf.train.get_global_step())

我们已经完成了CNN。但是, 我们希望在评估模式下显示性能指标。多类模型的性能指标是准确性指标。 TensorFlow配备了具有两个参数, 标签和预测值的精度模型。
eval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

我们可以创建第一个CNN, 并准备将所有内容包装到一个函数中以使用它, 并训练和评估模型。
def cnn_model_fn(features, labels, mode):""Model function for CNN.""# Input Layerinput_layer = tf.reshape(features["x"], [-1, 28, 28, 1])# Convolutional Layerconv1 = tf.layers.conv2d(inputs=input_layer, filters=32, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)# Pooling Layerpool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)# Convolutional Layer #2 and Pooling Layerconv2 = tf.layers.conv2d(inputs=pool1, filters=36, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)# Dense Layerpool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)# Logits Layerlogits = tf.layers.dense(inputs=dropout, units=10)predictions = {# Generate predictions (for PREDICT and EVAL mode)"classes": tf.argmax(input=logits, axis=1), "probabilities": tf.nn.softmax(logits, name="softmax_tensor")}if mode == tf.estimator.ModeKeys.PREDICT:return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)# Calculate Lossloss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)# Configure the Training Op (for TRAIN mode)if mode == tf.estimator.ModeKeys.TRAIN:optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)train_op = optimizer.minimize(loss=loss, global_step=tf.train.get_global_step())return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)# Add evaluation metrics Evaluation modeeval_metric_ops = {"accuracy": tf.metrics.accuracy( labels=labels, predictions=predictions["classes"])} return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

CNN需要花费很多时间进行训练, 因此, 我们创建了一个日志挂钩, 以每50次迭代存储软件层的值。
# Set up logging for predictionstensors_to_log = {"probabilities": "softmax_tensor"}logging_hook =tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)

我们准备估计模型。我们的批次大小为100, 并将数据随机分成许多部分。请注意, 我们将训练步骤设置为18000, 这将花费大量时间进行训练。
#Train the modeltrain_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": X_train_scaled}, y=y_train, batch_size=100, num_epochs=None, shuffle=True) mnist_classifier.train( input_fn=train_input_fn, steps=18000, hooks=[logging_hook])

现在, 模型已经过训练, 我们可以对其进行评估并轻松打印结果。
# Evaluate the model and print the resultseval_input_fn = tf.estimator.inputs.numpy_input_fn(x= {"x": X_test_scaled}, y=y_test, num_epochs=1, shuffle=False)eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)print(eval_results)

INFO:tensorflow:Calling model_fnINFO:tensorflow:Done calling model_fnINFO:tensorflow:Starting evaluation at 2019-08-10-12:53:40INFO:tensorflow:Graph is finalized.INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652INFO:tensorflow: Running local_init_opINFO:tensorflow: Running local_init_opINFO:tensorflow:Finished evaluation at 2019-07-05-12:52:56INFO:tensorflow: Saving dict for global step 15652: accuracy = 0.9589586, global_step = 15852, loss = 0.13894269{'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}

在体系结构的帮助下, 我们的准确性达到了97%。我们可以更改体系结构, 批处理大小和迭代次数以提高准确性。体系结构, 批处理大小和迭代次数可提高准确性。
CNN神经网络的性能远远优于ANN或逻辑回归。在关于人工神经网络的教程中, 我们的准确度为96%, 即CNN较低。在速度计算和准确性方面, CNN凭借丰富的图像集的性能令人印象深刻。
要构建CNN, 我们需要遵循以下六个步骤:
1)输入层:
此步骤将重置数据。大小等于像素数的平方根。例如, 如果图片有156个像素, 则数字为26× 26。我们需要指定图像是否包含颜色。如果是这样, 我们的RGB-大小为3到3, 否则为1。
Input_layer= tf.reshape(tensor= features["x"], shape= [-1, 30, 30, 1])

2)卷积层
我们需要创建一致的图层。我们应用各种过滤器来学习网络的重要功能。我们定义内核的大小和过滤器的体积。
conv1= tf.layers.conv2d(inputs=input_layer, filters=14, kernel_size=[6, 6], padding="same", activation= tf.nn.relu)

3)池化层
第三步, 我们添加一个池化层。该层减小了输入的大小。它通过取子矩阵的最大值来实现。
pool1 = tf.layers.max_pooling2d(inputs=conv1, strides=2, pool_size=[2, 2])

4)添加卷积层和池化层
在此步骤中, 我们可以根据需要添加任意数量的池化层。它使用具有20多个硬层的Google体系结构。
5)致密层
步骤5压平前一个以形成完全连接的层。在此步骤中, 我们可以使用其他激活函数并添加退出效果。
pool2_flat = tf.reshape(pool2, [-1, 8 * 8 * 36])dense = tf.layers.dense(inputs=pool3_flat, units=8 * 8 * 36, activation=tf.nn.relu)dropout = tf.layers.dropout(Inputs=dense, rate=0.3, trainingmode == tf.estimator.ModeKeys.TRAIN)

6)Logit层
最后一步是预测。
logits = tf.layers.dense(inputs=dropout, units=12)

    推荐阅读