初始CNN及tensorflow实现

孤街醉人 提交于 2020-08-18 02:54:57

1、初识CNN

卷积神经网络(CNN),主要用于图像识别、特征提取、自然语言处理、分类。由输入层、卷积层(Convolutional Layer)、池化层(Pooling Layer)、和全连接层(Fully Connected Layer)组成,其中卷积用于提取高层次特征,池化用于缩小参数,一般为一层卷积加一层池化反复叠加或多层卷积加一层池化;全连接层用于卷积池化后,对数据列化然后经过一两层全连接层,得出结果。

2、CNN进行手写体识别

(1)数据来源:Mnist数据集,从tensorflow导入mnist数据集。首先,在你正在写的项目下创建文件夹MNIST_data;接着,从官网下载四个压缩包,不用解压直接放入文件夹中,http://yann.lecun.com/exdb/mnist/

import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets('mnist_data',one_hot=True)  #one_hot为T代表标签是一个向量

(2)网络结构的搭建

定义网络的输入、输出:首先将输入进行初始化,接着将输入重构成4维;输出为一个二维向量,每行代表着一个数字的分类。

input_x=tf.placeholder(tf.float32,[None,28*28])/255  #图像的像素值为255,将
input_x_images=tf.reshape(input_x,[-1,28,28,1])      #重构为4维
output_y=tf.placeholder(tf.int32,[None,10])          #定义输出

定义卷积层和池化层:卷积使用tensorflow中的 layers.conv2d,需要设置卷积的深度(filters)、卷积核的尺寸(kernel_size)、扫描步长(strides)、激活函数(activation)和卷积核补(padding);池化层使用tensorflow中的 layers.max_pooling2d,需要设置过滤器的尺寸(pool_size)和扫描步长(strides)。

#卷积层1,输入为[-1,28,28,1],输出为[?,28,28,32],其中?为数据的条数
conv1=tf.layers.conv2d(
    inputs=input_x_images,
    filters=32,
    kernel_size=[5,5],
    strides=1,
    padding='same',    #卷积核自动补0
    activation=tf.nn.relu
)
#池化层1,输入为[?,28,28,32],输出为[?,14,14,32]
pool1=tf.layers.max_pooling2d(
    inputs=conv1,
    pool_size=[2,2],
    strides=2
)
#卷积层2,输入为[?,14,14,32],输出为[?,14,14,64]
conv2=tf.layers.conv2d(
    inputs=pool1,
    filters=64,
    kernel_size=[5,5],
    strides=1,
    padding='same',
    activation=tf.nn.relu
)
#池化层2,输入为[?,14,14,64],输出为[?,7,7,64]
pool2=tf.layers.max_pooling2d(
    inputs=conv2,
    pool_size=[2,2],
    strides=2
)

平坦化和全连接层:先对输出池化层输出进行平坦化,再输入全连接层。平坦化后形状变为[?,7*7*64],全连接层处理后形状变成[?,1024]

flat=tf.reshape(pool2,[-1,7*7*64])    #平坦化形状变成了[?,3136]
#全连接层,[?,1024]
dense=tf.layers.dense(
    inputs=flat,
    units=1024,
    activation=tf.nn.relu
)

输出层:进行防止过拟合处理,最后进行网络的输出,输出形状为[?,10]

#防止过拟合,rate 为丢弃率
dropout=tf.layers.dropout(
    inputs=dense,
    rate=0.5,
)
#输出层,不用激活函数(本质就是一个全连接层)
logits=tf.layers.dense(
    inputs=dropout,
    units=10
)

(3)基础操作

主要包括:损失函数、模型训练、准确率的定义

损失函数的定义,使用交叉熵损失函数(cross entropy),并用百分比概率进行表示;使用GD优化器进行优化;准确率使用tensorflow中的tf.metrics.accuracy。

loss=tf.losses.softmax_cross_entropy(onehot_labels=output_y,   #标签值    
                                     logits=logits)             #预测网络的输出值
train_op=tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)   
accuracy_op=tf.metrics.accuracy( 
    labels=tf.argmax(output_y,axis=1),    #真实标签     
    predictions=tf.argmax(logits,axis=1)  #预测值
)[1]                                      #输出为准确率

(4)主函数

主函数包括:创建会话、数据流动和结果展示

#创建会话
sess=tf.Session()
init=tf.group(tf.global_variables_initializer(),   #初始化全局变量
              tf.local_variables_initializer())    #初始化全局变量
sess.run(init)
#数据流动
for i in range(10000):                       #训练次数          
    batch=mnist.train.next_batch(50)         #将训练图像和标签对随机化,每次选择50个样本
    train_loss,train_op_=sess.run([loss,train_op],{input_x:batch[0],output_y:batch[1]})
    if i%100==0:                             #显示训练次数为100倍数的损失和训练误差
        test_accuracy=sess.run(accuracy_op,{input_x:test_x,output_y:test_y})
        print("Step=%d, Train loss=%.4f,[Test accuracy=%.2f]"%(i,train_loss,test_accuracy))
#结果测试和展示
test_output=sess.run(logits,{input_x:test_x[:20]})   #计算预测向量[20,10]
inferenced_y=np.argmax(test_output,1)                #计算预测向量的最大索引[20,1]   
print(inferenced_y,'Inferenced numbers')             #输出预测值
print(np.argmax(test_y[:20],1),'Real numbers')       #输出真实值
sess.close()

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!