赞
踩
不说废话先上代码:
- #coding:utf-8
-
- #learning how to use tensorboard in cnn
- import tensorflow.examples.tutorials.mnist.input_data as input_data
- mnist = input_data.read_data_sets("data/", one_hot=True)
- import tensorflow as tf
- import matplotlib.pyplot as plt
- import numpy as np
-
- #define fuctions*******************************************************************************************************************
- def weight_variable(shape):
- initial = tf.truncated_normal(shape,stddev = 0.1)
- return tf.Variable(initial)
-
- def bias_variable(shape):
- initial = tf.constant(0.1,shape=shape)#行向量
- return tf.Variable(initial)
-
- def conv2d(x,w):
- return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')
-
- def max_pool_2X2(x):
- return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
-
- def variable_summaries(var,name):
- with tf.name_scope('summaries'):
- mean = tf.reduce_mean(var)
- tf.summary.scalar('mean/'+name,mean)
- with tf.name_scope('stddev'):
- stddev = tf.sqrt(tf.reduce_mean(tf.square(var-mean)))
- tf.summary.scalar('stddev/'+name,stddev)
- tf.summary.histogram(name,var)
- def conv_image_visual(conv_image,image_weight,image_height,cy,cx,channels):
- #slice off one image ande remove the image dimension
- #original image is a 4d tensor[batche_size,weight,height,channels]
- conv_image = tf.slice(conv_image,(0,0,0,0),(1,-1,-1,-1))
- conv_image = tf.reshape(conv_image,(image_height,image_weight,channels))
- #add a couple of pixels of zero padding around the image
- image_weight += 4
- image_height += 4
- conv_image = tf.image.resize_image_with_crop_or_pad(conv_image,image_height,image_weight)
- conv_image = tf.reshape(conv_image,(image_height,image_weight,cy,cx))
- conv_image = tf.transpose(conv_image,(2,0,3,1))
- conv_image = tf.reshape(conv_image,(1,cy*image_height,cx*image_weight,1))
- return conv_image
- #**********************************************************************************************************************************
-
- with tf.name_scope('intput'):
- x = tf.placeholder(tf.float32,shape = [None,784],name = 'x')
- y_ = tf.placeholder(tf.float32,shape = [None,10],name = 'labels')
- input_image = tf.reshape(x,shape = [-1,28,28,1])
- tf.summary.image('input_image',input_image,max_outputs = 1 )
- with tf.name_scope('cnn_block'):
- w_conv1 = weight_variable([5,5,1,32])
- b_conv1 = bias_variable([32])
- variable_summaries(w_conv1,'first_cnn_layer_weight')
- variable_summaries(b_conv1,'first_cnn_layer_bais')
- with tf.name_scope('reshape'):
- #将输入数据转换成28×28,channel = 1的图像
- x_image = tf.reshape(x,[-1,28,28,1])
- with tf.name_scope('first_cnn_layer'):
- #进行第一层卷积网络的运算h_conv1=[-1,28,28,32]
- h_conv1 = tf.nn.relu(conv2d(x_image,w_conv1)+b_conv1)
- with tf.name_scope('conv1_vis'):
- conv1_image = conv_image_visual(h_conv1,28,28,4,8,32)
- tf.summary.image('h_conv1',conv1_image)
- with tf.name_scope('first_pool_layer'):
- h_pool1 = max_pool_2X2(h_conv1)
- with tf.name_scope('second_cnn_layer'):
- #第二层卷积网络
- w_conv2 = weight_variable([5,5,32,64])
- b_conv2 = bias_variable([64])
- #第二层卷积输出[batch_size,14,14,64]
- h_conv2 = tf.nn.relu(conv2d(h_pool1,w_conv2)+b_conv2)
- with tf.name_scope('conv2_vis'):
- conv2_iamge = conv_image_visual(h_conv2,14,14,8,8,64)
- tf.summary.image('h_conv2',conv2_iamge)
- with tf.name_scope('second_pool_layer'):
- h_pool2 = max_pool_2X2(h_conv2)
- with tf.name_scope('first_fullconect_layer'):
- #经过两个池化操作图片从28*28降维到了7*7,
- w_fc1 = weight_variable([7*7*64,1024])
- b_fc1 = bias_variable([1024])
- #reshape为行向量
- with tf.name_scope('h_pool2_reshape'):
- h_pool2_reshape = tf.reshape(h_pool2,[-1,7*7*64])
- h_fc1 = tf.nn.relu(tf.matmul(h_pool2_reshape,w_fc1)+b_fc1)
- #使用dropout防止过拟合
- with tf.name_scope('dropout'):
- keep_prob = tf.placeholder(tf.float32)
- h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
- with tf.name_scope('out_put_layer'):
- #输出层
- w_fc2 = weight_variable([1024,10])
- b_fc2 = bias_variable([10])
- with tf.name_scope('softmax'):
- y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop,w_fc2)+b_fc2)
- #损失函数
- with tf.name_scope('cross_entropy'):
- cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
- tf.summary.scalar('cross_entropy',cross_entropy)
- with tf.name_scope('train_step'):
- train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
-
- with tf.name_scope('accuracy'):
- with tf.name_scope('correct_prediction'):
- correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
- with tf.name_scope('accuracy'):
- accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
- tf.summary.scalar('accuracy',accuracy)
- init_op = tf.global_variables_initializer()
- merged = tf.summary.merge_all()
- with tf.Session() as sess:
- sess.run(init_op)
- train_writer = tf.summary.FileWriter("tensorboard/",sess.graph)
- for i in range(1000):
- batch = mnist.train.next_batch(50)
- summary, _ = sess.run([merged,train_step],feed_dict = {x:batch[0],y_:batch[1],keep_prob:0.5})
- train_writer.add_summary(summary,i)
- if i%10 == 0:
- summary,acc = sess.run([merged,accuracy],feed_dict = {x:batch[0],y_:batch[1],keep_prob:0.5})
- train_writer.add_summary(summary,i)
- print "step %d,training accuracy %g"%(i,acc)
- train_writer.close();
- #print "test accuracy %g"%accuracy.eval(feed_dict = {x:mnist.test.images,y_:mnist.test.labels,keep_prob:1.0}
效果图:
分析一下可视化卷积层最终要的一段代码:
- def conv_image_visual(conv_image,image_weight,image_height,cy,cx,channels):
- #slice off one image ande remove the image dimension
- #original image is a 4d tensor[batche_size,weight,height,channels]
- conv_image = tf.slice(conv_image,(0,0,0,0),(1,-1,-1,-1))
- conv_image = tf.reshape(conv_image,(image_height,image_weight,channels))
- #add a couple of pixels of zero padding around the image
- image_weight += 4
- image_height += 4
- conv_image = tf.image.resize_image_with_crop_or_pad(conv_image,image_height,image_weight)
- conv_image = tf.reshape(conv_image,(image_height,image_weight,cy,cx))
- conv_image = tf.transpose(conv_image,(2,0,3,1))
- conv_image = tf.reshape(conv_image,(1,cy*image_height,cx*image_weight,1))
- return conv_image
该函数的参数:conv_image:待可视化的卷积结果;image_w:卷积后图像的宽;iamge_h:卷积后图像的高;cy:图像显示的行数;cx:图像显示的列数;channels:图像的通道数;
比如我要显示第一个卷积层经过激活函数后的图像,经过一次卷积后图像的channels变成了32,如果我要将这32个通道的结果以4行8列显示的话,则cy=4,cx=8;
- conv_image = tf.slice(conv_image,(0,0,0,0),(1,-1,-1,-1))
- conv_image = tf.reshape(conv_image,(image_height,image_weight,channels))
因为tf.summary.image()函数输入的tensor的格式为:[batch_size,height,width,channels]而channel只能为1,3,4分别表示gray,RGB,RGBA图像,而卷积后的图像格式为[batch_size,height,width,channels],这里的channel=卷积核的个数,因此如果直接将卷积后的图像输入到tf.summary.image()会报错,而且不能显示每一个卷积核作用到图像后的结果,因此我们第一步就是要消减卷积结果的维度tf.slice()操作后,消去了第一个(batch_size)维度,这个操作可以理解为从每一个batch中挑选了第一张图片进行显示,这也就造成了每一步显示的图片是不同的。
经过slice操作以后图像还是四维的因此使用reshape将图像降维成3维彻底剔除batch_size。以下例子说明了此操作的必要性
slice后数据是三维[[[7,8,9]]](三个括号),reshape后为[[7,8,9]]二维。
- #add a couple of pixels of zero padding around the image
- image_weight += 4
- image_height += 4
- conv_image = tf.image.resize_image_with_crop_or_pad(conv_image,image_height,image_weight)
使用零填充图像的边界,这里对原图像以外的四个像素进行了扩充
- conv_image = tf.reshape(conv_image,(image_height,image_weight,cy,cx))
- conv_image = tf.transpose(conv_image,(2,0,3,1))
- conv_image = tf.reshape(conv_image,(1,cy*image_height,cx*image_weight,1))
第一个reshape()是为了将n个channel拆分为cy×cx,tf.transpose()将图像由[image_height,image_weight,cy,cx]转换为[cy,image_height,cx,image_width]最后通过reshape()将n个卷积结果在一张图片上显示。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。