一.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
运行结果如下:
2.版本检查,看一下刚刚降低 numpy 版本的版本号。
import numpy as np
print(np.__version__)
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()
运行结果如下:
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)) # 计算输出两个变量相乘的值
运行结果如下:
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)
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)
运行结果如下:
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)
运行结果如下:
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()
运行结果如下:
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)
运行结果如下:
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())))
运行结果如下:
2.3 结论
可以看到模型在测试集的精度为96%,并在我们给的手写数字上识别正确。