开发环境:Python3.9+Tensorflow2.9.1
以经典的**手写数字集MNIST**识别为例,采用**LeNet-5网络**。最简单的网络和数据集,之后的网络将会越来越深,数据集会越来越复杂,做好准备🤣
MNIST数据集是机器学习领域中非常经典的一个数据集,由**60000个训练样本和10000个测试样本**组成,每个样本都是一张**28*28**像素的灰度手写数字图片。
LeNet 是一系列网络的合称,包括LeNet1 - LeNet5,由Yann LeCun 等人在 1990 年《Handwritten Digit Recognition with a Back-Propagation Network》中提出,是**卷积神经网络的 HelloWorld**。
# coding: utf-8# # TensorFlow卷积神经网络(CNN)示例 - 高级API# ### Convolutional Neural Network Example - tf.layers API# ## CNN网络结构图示# # ![CNN](http://personal.ie.cuhk.edu.hk/~ccloy/project_target_code/images/fig3.png)# # ## MNIST数据库# # ![MNIST Dataset](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)# # More info: http://yann.lecun.com/exdb/mnist/from__future__importdivision, print_function, absolute_import# Import MNIST data,MNIST数据集导入fromtensorflow.examples.tutorials.mnistimportinput_datamnist=input_data.read_data_sets("/tmp/data/", one_hot=False) importtensorflowastfimportmatplotlib.pyplotaspltimportnumpyasnp# Training Parameters,超参数learning_rate=0.001# 学习率num_steps=2000# 训练步数batch_size=128# 训练数据批的大小# Network Parameters,网络参数num_input=784# MNIST数据输入 (img shape: 28*28)num_classes=10# MNIST所有类别 (0-9 digits)dropout=0.75# Dropout, probability to keep units,保留神经元相应的概率# Create the neural network,创建深度神经网络defconv_net(x_dict, n_classes, dropout, reuse, is_training): # Define a scope for reusing the variables,确定命名空间withtf.variable_scope('ConvNet', reuse=reuse): # TF Estimator类型的输入为像素x=x_dict['images'] # MNIST数据输入格式为一位向量,包含784个特征 (28*28像素)# 用reshape函数改变形状以匹配图像的尺寸 [高 x 宽 x 通道数]# 输入张量的尺度为四维: [(每一)批数据的数目, 高,宽,通道数]x=tf.reshape(x, shape=[-1, 28, 28, 1]) # 卷积层,32个卷积核,尺寸为5x5conv1=tf.layers.conv2d(x, 32, 5, activation=tf.nn.relu) # 最大池化层,步长为2,无需学习任何参量conv1=tf.layers.max_pooling2d(conv1, 2, 2) # 卷积层,32个卷积核,尺寸为5x5conv2=tf.layers.conv2d(conv1, 64, 3, activation=tf.nn.relu) # 最大池化层,步长为2,无需学习任何参量conv2=tf.layers.max_pooling2d(conv2, 2, 2) # 展开特征为一维向量,以输入全连接层fc1=tf.contrib.layers.flatten(conv2) # 全连接层fc1=tf.layers.dense(fc1, 1024) # 应用Dropout (训练时打开,测试时关闭)fc1=tf.layers.dropout(fc1, rate=dropout, training=is_training) # 输出层,预测类别out=tf.layers.dense(fc1, n_classes) returnout# 确定模型功能 (参照TF Estimator模版)defmodel_fn(features, labels, mode): # 构建神经网络# 因为dropout在训练与测试时的特性不一,我们此处为训练和测试过程创建两个独立但共享权值的计算图logits_train=conv_net(features, num_classes, dropout, reuse=False, is_training=True) logits_test=conv_net(features, num_classes, dropout, reuse=True, is_training=False) # 预测pred_classes=tf.argmax(logits_test, axis=1) pred_probas=tf.nn.softmax(logits_test) ifmode==tf.estimator.ModeKeys.PREDICT: returntf.estimator.EstimatorSpec(mode, predictions=pred_classes) # 确定误差函数与优化器loss_op=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( logits=logits_train, labels=tf.cast(labels, dtype=tf.int32))) optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate) train_op=optimizer.minimize(loss_op, global_step=tf.train.get_global_step()) # 评估模型精确度acc_op=tf.metrics.accuracy(labels=labels, predictions=pred_classes) # TF Estimators需要返回EstimatorSpecestim_specs=tf.estimator.EstimatorSpec( mode=mode, predictions=pred_classes, loss=loss_op, train_op=train_op, eval_metric_ops={'accuracy': acc_op}) returnestim_specsif__name__=="__main__": # 构建Estimatormodel=tf.estimator.Estimator(model_fn) # 确定训练输入函数input_fn=tf.estimator.inputs.numpy_input_fn( x={'images': mnist.train.images}, y=mnist.train.labels, batch_size=batch_size, num_epochs=None, shuffle=True) # 开始训练模型model.train(input_fn, steps=num_steps) # 评判模型# 确定评判用输入函数input_fn=tf.estimator.inputs.numpy_input_fn( x={'images': mnist.test.images}, y=mnist.test.labels, batch_size=batch_size, shuffle=False) model.evaluate(input_fn) # 预测单个图像n_images=4# 从数据集得到测试图像test_images=mnist.test.images[:n_images] # 准备输入数据input_fn=tf.estimator.inputs.numpy_input_fn( x={'images': test_images}, shuffle=False) # 用训练好的模型预测图片类别preds=list(model.predict(input_fn)) # 可视化显示foriinrange(n_images): plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray') plt.show() print("Model prediction:", preds[i])
总结🍟
对于图像处理来说,深度学习只需掌握CNN即可。下一节开始介绍近年来火爆的原始CNN基础上不断改进的神经网络模型,敬请期待🚗