Notas del estudio de Tensorflow: creación de una red neuronal convolucional

Aquí se construye una red neuronal convolucional, que solo se usa para el reconocimiento de un solo objetivo. La estructura de la red es la siguiente:
Inserte la descripción de la imagen aquí
Tome el reconocimiento de números escritos a mano como ejemplo, el código es el siguiente:

import os
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

# os.environ['TF_CPP_MIN_LOG_LEVEL']='1' # 显示所有信息
os.environ['TF_CPP_MIN_LOG_LEVEL']='2' # 只显示warning和error
# os.environ['TF_CPP_MIN_LOG_LEVEL']='3' # 只显示error

# 获取数据集
# one_hot设置为True,将标签数据转化为0/1,如[1,0,0,0,0,0,0,0,0,0]
mnist=input_data.read_data_sets('MNIST_data',one_hot=True)

# 定义一个批次的大小
batch_size=100
# 所有训练数据一共可以分为几个批次
n_batch=mnist.train.num_examples//batch_size

# 变量分析
def variable_summaries(var):
	with tf.name_scope('summaries'):
		mean=tf.reduce_mean(var)
		stddev=tf.sqrt(tf.reduce_mean(tf.square(var-mean)))
		tf.summary.scalar('mean',mean)
		tf.summary.scalar('stddev',stddev)
		tf.summary.scalar('max',tf.reduce_max(var))
		tf.summary.scalar('min',tf.reduce_min(var))
		tf.summary.histogram('histogram',var) #直方图

# 初始化权重
def weight_variable(shape, name):
	# 权重初始值为0不是最优的,应该设置为满足截断正态分布的随机数,收敛速度更快
	initial = tf.truncated_normal(shape, stddev=0.1)
	return tf.Variable(initial, name=name)

# 初始化偏置
def bias_variable(shape, name):
	# 偏置初始值为0不是最优的,可以设置为0.1,收敛速度更快
	initial = tf.constant(0.1, shape=shape)
	return tf.Variable(initial, name=name)

# 卷积层
def conv2d(x,w):
	# x:input tensor of shape [batch, height, width, channels]
	# w:filter or kernel tensor of shape [height, width, in_channels, out_channels]
	# strides:strides[1]表示x方向的步长,strides[2]表示y方向的步长
	# padding:'SAME'表示周围补0,'VALID'表示周围不补0
	return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')

# 池化层
def max_pool_2x2(x):
	# x:input tensor of shape [batch, height, width, channels]
	# ksize:ksize[1]表示池化核的宽度,ksize[2]表示池化核的高度
	# strides:strides[1]表示x方向的步长,strides[2]表示y方向的步长
	# padding:'SAME'表示周围补0,'VALID'表示周围不补0
	return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

# 定义三个placeholder
# 行数值为None,None可以取任意数,本例中将取值100,即取决于pitch_size
# 列数值为784,因为输入图像尺寸已由28*28转换为1*784
with tf.name_scope('input'):
	x=tf.placeholder(tf.float32,[None,784],name='x_input')
	y=tf.placeholder(tf.float32,[None,10],name='y_input')
	with tf.name_scope('x_image'):
		# 将一维变为二维
		x_image=tf.reshape(x,[-1,28,28,1],name='x_image')

# 定义keep_prob,表示不执行dropout的神经元的比例
with tf.name_scope('keep_prob'):
	keep_prob=tf.placeholder(tf.float32, name='keep_prob')

# 定义学习率
with tf.name_scope('lr'):
	lr=tf.Variable(0.001,dtype=tf.float32)

# 定义第一个卷积层
with tf.name_scope('conv1'):
	with tf.name_scope('conv1_w'):
		# 8个尺寸为5x5的卷积核对1张图像做卷积计算
		conv1_w = weight_variable([5,5,1,8], name='conv1_w')
	with tf.name_scope('conv1_b'):
		conv1_b = bias_variable([8], name='conv1_b')
	# 卷积运算
	with tf.name_scope('conv2d_1'):
		conv2d_1=conv2d(x_image,conv1_w)+conv1_b
	# 激活运算
	with tf.name_scope('relu'):
		h_conv1=tf.nn.relu(conv2d_1)
	# 池化运算
	with tf.name_scope('h_pool1'):
		h_pool1=max_pool_2x2(h_conv1) # 该层图像尺寸变为14*14

# 定义第二个卷积层
with tf.name_scope('conv2'):
	with tf.name_scope('conv2_w'):
		# 16个尺寸为5x5的卷积核对8张图像做卷积计算
		conv2_w = weight_variable([5,5,8,16], name='conv2_w')
	with tf.name_scope('conv2_b'):
		conv2_b = bias_variable([16], name='conv2_b')
	# 卷积运算
	with tf.name_scope('conv2d_2'):
		conv2d_2=conv2d(h_pool1,conv2_w)+conv2_b
	# 激活运算
	with tf.name_scope('relu'):
		h_conv2=tf.nn.relu(conv2d_2)
	# 池化运算
	with tf.name_scope('h_pool2'):
		h_pool2=max_pool_2x2(h_conv2) # 该层图像尺寸变为7*7

# 定义第一个全连接层
with tf.name_scope('fc1'):
	with tf.name_scope('fc1_w'):
		fc1_w=weight_variable([7*7*16,100], name='fc1_w')
	with tf.name_scope('fc1_b'):
		fc1_b=bias_variable([100],name='fc1_b')
	# 将二维变为一维
	with tf.name_scope('h_pool2_flat'):
		h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*16],name='h_pool2_flat')
	# 求一个全连接层的输出
	with tf.name_scope('wx_plus_b1'):
		wx_plus_b1=tf.matmul(h_pool2_flat,fc1_w)+fc1_b
	with tf.name_scope('relu'):
		h_fc1=tf.nn.relu(wx_plus_b1)
	# 引入dropout
	with tf.name_scope('h_fc1_drop'):
		h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob,name='h_fc1_drop')

# 定义第二个全连接层
with tf.name_scope('fc2'):
	with tf.name_scope('fc2_w'):
		fc2_w=weight_variable([100,10], name='fc2_w')
	with tf.name_scope('fc2_b'):
		fc2_b=bias_variable([10],name='fc2_b')
	# 求一个全连接层的输出
	with tf.name_scope('wx_plus_b2'):
		wx_plus_b2=tf.matmul(h_fc1_drop,fc2_w)+fc2_b
	with tf.name_scope('softmax'):
		prediction=tf.nn.softmax(wx_plus_b2)

# 定义损失函数
with tf.name_scope('loss'):
	# 由于输出神经元为softmax,交叉熵损失函数比均方误差损失函数收敛速度更快
	# loss=tf.reduce_mean(tf.square(y-prediction))
	loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction),name='loss')
	# loss分析
	tf.summary.scalar('loss',loss)

# 定义训练方式
with tf.name_scope('train'):
	# 优化器通过调整loss里的参数,使loss不断减小
	# AdamOptimizer比GradientDescentOptimizer收敛速度更快
	# train=tf.train.GradientDescentOptimizer(0.2).minimize(loss)
	train=tf.train.AdamOptimizer(lr).minimize(loss)

# 计算准确率
with tf.name_scope('accuracy'):
	# tf.argmax返回第一个参数中最大值的下标
	# tf.equal比较两个参数是否相等,返回True或False
	correct_prediction=tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
	# tf.cast将布尔类型转换为浮点类型
	accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
	# accuracy分析
	tf.summary.scalar('accuracy',accuracy)

# 合并所有summary
merged=tf.summary.merge_all()

with tf.Session() as sess:
	# 变量初始化
	sess.run(tf.global_variables_initializer())
	# 生成计算图
	train_writer=tf.summary.FileWriter('logs/train',sess.graph)
	test_writer=tf.summary.FileWriter('logs/test',sess.graph)
	# epoch为周期数,所有批次训练完为一个周期
	for epoch in range(20):
		# 调整学习率
		sess.run(tf.assign(lr,0.001*(0.95**epoch)))
		for batch in range(n_batch):
			# 每次取出batch_size条数据进行训练
			batch_xs, batch_ys = mnist.train.next_batch(batch_size)
			sess.run(train, feed_dict={
    
    x:batch_xs, y:batch_ys, keep_prob:0.5})
			# 记录训练集计算的loss和accuracy
			summary=sess.run(merged, feed_dict={
    
    x:batch_xs, y:batch_ys, keep_prob:1.0})
			train_writer.add_summary(summary, epoch*n_batch+batch)
			# 记录测试集计算的loss和accuracy
			batch_xs, batch_ys = mnist.test.next_batch(batch_size)
			summary=sess.run(merged, feed_dict={
    
    x:batch_xs, y:batch_ys, keep_prob:1.0})
			test_writer.add_summary(summary, epoch*n_batch+batch)
		learning_rate=sess.run(lr)
		test_acc = sess.run(accuracy,feed_dict={
    
    x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})
		train_acc = sess.run(accuracy,feed_dict={
    
    x:mnist.train.images,y:mnist.train.labels,keep_prob:1.0})
		print('epoch=',epoch,' ','learning_rate=%.7f' % learning_rate,' ','test_acc=',test_acc,' ','train_acc=',train_acc)

resultado de la operación:
Inserte la descripción de la imagen aquí

Ingrese en la ventana de línea de comando para tensorboard --logdir logsobtener una URL, abra la URL con Google Chrome, puede ver el gráfico de cálculo y
Inserte la descripción de la imagen aquí
la
Inserte la descripción de la imagen aquí
prueba de tren de resumen
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/wxsy024680/article/details/114652133
Recomendado
Clasificación