【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

时间:2022-12-27 09:52:45

一.TensorFlow

使用深度学习框架TensorFlow。
目标:

1.了解TensorFlow的基本用法;
2.学习使用TensorFlow构建全连接的神经网络,实现手写数字识别,
3.学习使用TensorFlow构建CNN网络,实现手写数字识别程序,
4.比较两种网络结构的识别精度,以进一步了解深度学习和TensorFlow。

1.1 内容介绍

TensorFlow是一个开源软件库,使用数据流图进行数值计算。

(Operation)表示图中的数学运算,而图中的边表示节点之间互连的多维数据数组,即张量。
Tensorflow作为最流行的深度学习框架之一,具有非常好的性能和强大的功能。它广泛应用于各个领域。

自2015年TensorFlow诞生以来,已有三个主要版本。
TensorFlow更适合大规模部署,特别是跨平台和嵌入式部署

二.开始实验

1.为了消除 numpy 版本过高造成的输出中有太多WARING 警告日志,此处先降低 numpy 版本

!pip install -U numpy==1.15.0

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

2.版本检查,看一下刚刚降低 numpy 版本的版本号。

import numpy as np
print(np.__version__)

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

2.1TensorFlow的基本使用

1.打印出 Hello tensorflow

import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()      # 建立一个session
print (sess.run(hello))  # 通过session里面的run来运行结果
sess.close()

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

2.基本运算

a = tf.constant(3)   # 定义常量3
b = tf.constant(4)   # 定义常量4
 
with tf.Session() as sess:  # 建立session
    print ("相加: %i" % sess.run(a+b))  # 计算输出两个变量相加的值
    print( "相乘: %i" % sess.run(a*b))  # 计算输出两个变量相乘的值

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

3.定义变量

var1 = tf.Variable(10.0 , name="varname")     
var2 = tf.Variable(11.0 , name="varname")     
var3 = tf.Variable(12.0 )     
var4 = tf.Variable(13.0 )   
with tf.variable_scope("test1" ): 
    var5 = tf.get_variable("varname",shape=[2],dtype=tf.float32)   
    
with tf.variable_scope("test2"):
    var6 = tf.get_variable("varname",shape=[2],dtype=tf.float32)  

print("var1:",var1.name)   
print("var2:",var2.name)  
print("var3:",var3.name)   
print("var4:",var4.name)   
print("var5:",var5.name)  
print("var6:",var6.name)  

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

2.2基于全连接神经网络的手写数字识别

1.从OBS公共桶中下载MNIST数据集

import os
import moxing as mox

if not os.path.isdir("./MNIST_data"):
    mox.file.copy_parallel("obs://modelarts-labs-bj4/course/hwc_edu/python_module_framework/datasets/tensorflow_data/MNIST_data/","./MNIST_data")

2.导入数据集,使用TensorFlow可以直接进行本地数据加载

设置tensorflow日志级别 过滤WARNING

import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)  
from tensorflow.examples.tutorials.mnist import input_data   

下载到本地的文件夹

data_folder="./MNIST_data"  

导入已经下载好的数据集,如果数据集不存在,会自动在线下载,可能比较耗时。

mnist = input_data.read_data_sets(data_folder, one_hot = True)  

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

3.查看数据集的相关信息

# 训练数据集
print(mnist.train.images.shape, mnist.train.labels.shape)

# 测试数据集
print(mnist.test.images.shape, mnist.test.labels.shape)

# 验证数据集
print(mnist.validation.images.shape, mnist.validation.labels.shape)

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

4.展示部分加载后的数据

import matplotlib.pyplot as plt
%matplotlib inline

plt.figure()
for i in range(9):
    plt.subplot(3,3,i+1)
    plt.imshow(mnist.train.images[i].reshape((28,28)))
plt.show()

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

5.下载测试图片

if not os.path.exists("./num.png"):
    mox.file.copy("obs://modelarts-labs-bj4/course/hwc_edu/python_module_framework/datasets/tensorflow_data/num.png", "./num.png")

6.处理测试图片为网络支持的输入格式

import numpy as np
import cv2

def make_label(label_num):
    label = np.zeros((1,10),dtype='float32')
    label[:,label_num] = 1.0
    return label

label_test = make_label(3)

img_path = "./num.png"  # 图片路径
img_file=cv2.imread(img_path,0)
img_file=cv2.resize(img_file,(28,28))
plt.imshow(img_file,'gray')
plt.show()

data_test = img_file
data_test = np.float32(data_test.reshape(1, 28*28))
print(data_test.shape)

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

7.设置网络中会用到的超参数。

# 参数
learning_rate = 0.1
num_steps = 600
batch_size = 128
display_step = 100

# 神经网络的参数
n_hidden_1 = 256  # 第1层神经元数
n_hidden_2 = 256  # 第2层神经元数
num_input = 784   # MNIST数据输入(img形状:28 * 28)
num_classes = 10  # MNIST总类(0-9位)

8.全连接网络

# 计算图的input
X = tf.placeholder("float", [None, num_input])
Y = tf.placeholder("float", [None, num_classes])

# 隐藏层1
W1 = tf.Variable(tf.truncated_normal([num_input, n_hidden_1],stddev=0.1))
B1 = tf.Variable(tf.zeros([n_hidden_1]))
hidden1 = tf.nn.relu(tf.matmul(X,W1) + B1)

# 隐藏层2
W2 = tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2],stddev=0.1))
B2 = tf.Variable(tf.zeros([n_hidden_2]))
hidden2 = tf.nn.relu(tf.matmul(hidden1,W2) + B2)

#输出层
W3 = tf.Variable(tf.zeros([n_hidden_2,num_classes]))
B3 = tf.Variable(tf.zeros([num_classes]))
logits = tf.matmul(hidden2, W3) + B3

#softmax
y = tf.nn.softmax(logits)

9.优化器和损失函数

损失函数

loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=Y))

优化器:Adam

train_op = tf.train.AdagradOptimizer(learning_rate).minimize(loss_op)

模型评估指标和初始化变量

correct_pred = tf.equal(tf.argmax(y, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()

10.训练并验证

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

    for step in range(1, num_steps+1):
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        # 运行优化器,反向传播
        sess.run(train_op, feed_dict={X: batch_x, Y: batch_y})
        if step % display_step == 0 or step == 1:
            # 计算loss和acc
            loss, acc = sess.run([loss_op, accuracy], feed_dict={X: batch_x, Y: batch_y})
            print("Step " + str(step) + ", Minibatch Loss= " + \
                  "{:.4f}".format(loss) + ", Training Accuracy= " + \
                  "{:.3f}".format(acc))

    print("Optimization Finished!")

    # 在MNIST test images上验证效果
    print("Testing Accuracy:", \
        sess.run(accuracy, feed_dict={X: mnist.test.images,
                                      Y: mnist.test.labels}))
    
    # 对自己手写的数字进行识别
    test_acc,test_value = sess.run([accuracy,y], feed_dict={X:data_test, Y:label_test})
    # 设置numpy矩阵显示3位小数
    np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
    
    print(test_value)
    print("AI判断的数字是{}".format(list(test_value[0]).index(test_value[0].max())))

运行结果如下:

【深度学习框架TensorFlow】使用TensorFlow框架构建全连接的神经网络,实现手写数字识别

2.3 结论

可以看到模型在测试集的精度为96%,并在我们给的手写数字上识别正确。