tensorboard 可视化卷积层

不说废话先上代码:

#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个卷积结果在一张图片上显示。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值