众所周知,VGG16为深度学习在计算机视觉一个典型卷积神经网络算法。它是由卷积层的堆叠组合而成的。tensorflow是谷歌开源的深度学习的框架,而tensorboard为深度学习的可视化工具。我们通过tensorboard可视化可以很好的判断深度学习的结构以及训练过程的参数。接下来,我们就简单的介绍下使用tensorflow训练VGG16以及用tensorboard来可视化训练过程和图结构。本文使用的数据集为mnist手写数字。
首先我们来看看tensorboard中GRAPH模块来查看VGG16的图结构
GRAPHS面板是对理解神经网络结构最有帮助的一个面板,它直观地展示了数据流图。通过这个模块,我们可以很快的确认我们构建的深度学习结构是否与我们所想的一样,可以可视化对其中进行调整结构。在GRAPHS面板的左侧,可以选择迭代的步骤。可以用不同的Color(颜色)来表示不同的Structure(整个数据流的结构),或者用不同Color来表示不同的Device(设备)。例如当使用了多个GPU时,各个节点分别使用的GPU不同。当我们选择特定的某次迭代时,可以显示出各个节点的compute time(计算时间)以及memory(内存消耗),如上图。
其次我们来看看scaras模块,这个模块可以可视化模型训练的过程中,具体如下:
SCALARS 面板的左边是一些选项,包括 Split on undercores(用下划线分开显示)、 Data downloadlinks(数据下载链接)、 Smoothing(图像的曲线平滑程度)以及 Horizontal Axis(水平轴)的表示,其中水平轴的表示分3种(STEP代表迭代次数,RELATIVE代表按照训练集和测试集的相对值,WALL代表按照时间)。在这里,我只表示了accuracy以及loss的model evaluation,读者可以根据自己选择的model evaluation选择也可以表示每一层权重的最大值、最小值、平均值等信息。
最后介绍一下image
上图展示了训练数据集和测试数据集经过预处理后图片的样子。
接下来给出上面实现的代码:
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import numpy as np import time #paras n_classes = 10 # Training Parameters learning_rate = 0.001 num_steps = 200 batch_size = 128 display_step = 10 X = tf.placeholder(tf.float32,[None,28*28]) y = tf.placeholder(tf.float32,[None,n_classes]) #build vgg16 model x = tf.reshape(X,[-1,28,28,1]) tf.summary.image('x',x) #conv_1 with tf.name_scope('conv1_1') as scope: kernel = tf.Variable(tf.truncated_normal([3,3,1,16],dtype=tf.float32,stddev=1e-1),name='weights') conv = tf.nn.conv2d(x,kernel,[1,1,1,1],padding='SAME') biases = tf.Variable(tf.constant(0.0,shape=[16],dtype=tf.float32),trainable=True,name='biases') out = tf.nn.bias_add(conv,biases) conv1_1 = tf.nn.relu(out, name='scope') with tf.name_scope('conv1_2') as scope: kernel = tf.Variable(tf.truncated_normal([3,3,16,16],dtype=tf.float32,stddev=1e-1),name='weights') conv = tf.nn.conv2d(conv1_1,kernel,[1,1,1,1],padding='SAME') biases = tf.Variable(tf.constant(0.0,shape=[16],dtype=tf.float32),trainable=True,name='biases') out = tf.nn.bias_add(conv,biases) conv1_2 = tf.nn.relu(out,name='scope') #pool1 pool_1 = tf.nn.max_pool(conv1_2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name='pool_1') #conv_2 with tf.name_scope('conv2_1') as scope: kernel = tf.Variable(tf.truncated_normal([3,3,16,32],dtype=tf.float32,stddev=1e-1),name='weights') conv = tf.nn.conv2d(pool_1,kernel,[1,1,1,1],padding='SAME') biases = tf.Variable(tf.constant(0.0,shape=[32],dtype=tf.float32),trainable=True,name='biases') out = tf.nn.bias_add(conv,biases) conv2_1 = tf.nn.relu(out,name='scope') with tf.name_scope('conv2_2') as scope: kernel = tf.Variable(tf.truncated_normal([3,3,32,32],dtype=tf.float32,stddev=1e-1),name='weights') conv = tf.nn.conv2d(conv2_1,kernel,[1,1,1,1],padding='SAME') biases = tf.Variable(tf.constant(0.0,shape=[32],dtype=tf.float32),trainable=True,name='biases') out = tf.nn.bias_add(conv,biases) conv2_2 = tf.nn.relu(out,name='scope') #pool2 pool_2 = tf.nn.max_pool(conv2_2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name='pool_1') #conv_3 with tf.name_scope('conv3_1') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 32, 64], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(pool_2, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv3_1 = tf.nn.relu(out, name='scope') with tf.name_scope('conv3_2') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv3_1, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv3_2 = tf.nn.relu(out, name='scope') with tf.name_scope('conv3_3') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv3_2, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv3_3 = tf.nn.relu(out, name='scope') #pool_3 pool_3 = tf.nn.max_pool(conv3_3,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME',name='pool_3') # conv_4 with tf.name_scope('conv4_1') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(pool_3, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv4_1 = tf.nn.relu(out, name='scope') with tf.name_scope('conv4_2') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv4_1, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv4_2 = tf.nn.relu(out, name='scope') with tf.name_scope('conv4_3') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv4_2, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv4_3 = tf.nn.relu(out, name='scope') # pool_4 pool_4 = tf.nn.max_pool(conv4_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name='pool_4') # conv_5 with tf.name_scope('conv5_1') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 256], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(pool_4, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv5_1 = tf.nn.relu(out, name='scope') with tf.name_scope('conv5_2') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv5_1, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv5_2 = tf.nn.relu(out, name='scope') with tf.name_scope('conv5_3') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(conv5_2, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), trainable=True, name='biases') out = tf.nn.bias_add(conv, biases) conv5_3 = tf.nn.relu(out, name='scope') # pool_5 pool_5 = tf.nn.max_pool(conv5_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name='pool_5') #fc1 with tf.name_scope('fc1') as scope: shape = int(np.prod(pool_5.get_shape()[1:])) fc1w = tf.Variable(tf.truncated_normal([shape,100],dtype=tf.float32,stddev=1e-1),name='weights') fc1b = tf.Variable(tf.constant(1.0,shape=[100],dtype=tf.float32),trainable=True,name='biases') pool5_flat = tf.reshape(pool_5,[-1,shape]) fc11 = tf.nn.bias_add(tf.matmul(pool5_flat,fc1w),fc1b) fc1 = tf.nn.relu(fc11,name='scope') #fc2 with tf.name_scope('fc2') as scope: fc2w = tf.Variable(tf.truncated_normal([100,100],dtype=tf.float32,stddev=1e-1),name='weights') fc2b = tf.Variable(tf.constant(1.0,shape=[100],dtype=tf.float32),trainable=True,name='biases') fc21 = tf.nn.bias_add(tf.matmul(fc1,fc2w),fc2b) fc2 = tf.nn.relu(fc21,name='scope') #fc3 with tf.name_scope('fc3') as scope: fc3w = tf.Variable(tf.truncated_normal([100, 10], dtype=tf.float32, stddev=1e-1), name='weights') fc3b = tf.Variable(tf.constant(1.0, shape=[10], dtype=tf.float32), trainable=True, name='biases') fc31 = tf.nn.bias_add(tf.matmul(fc2, fc3w), fc3b,name='scope') mnist = input_data.read_data_sets('../data/',one_hot=True) prediction = tf.nn.softmax(fc31) #tensorboard事件保存地址 log_dir = 'E:/VGG16/tensorboard/' # Define loss and optimizer with tf.name_scope('loss'): loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=fc31, labels=y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) train_op = optimizer.minimize(loss_op) #evaluate model with tf.name_scope('accuracy'): correct_pred = tf.equal(tf.argmax(prediction,1),tf.argmax(y,1)) accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32)) #tensorboard tf.summary.scalar('loss',loss_op) tf.summary.scalar('accuracy',accuracy) merged_summary_op = tf.summary.merge_all() summary_writer = tf.summary.FileWriter(log_dir,graph=tf.get_default_graph()) # initialize the variables init = tf.global_variables_initializer() # Start training with tf.Session() as sess: # Run the initializer sess.run(init) for step in range(1, num_steps+1): batch_x, batch_y = mnist.train.next_batch(batch_size) # Run optimization op (backprop) sess.run(train_op, feed_dict={X: batch_x, y: batch_y}) if step % display_step == 0 or step == 1: # Calculate batch loss and accuracy loss, acc,summary = sess.run([loss_op, accuracy,merged_summary_op], feed_dict={X: batch_x, y: batch_y}) summary_writer.add_summary(summary,step) print("Step " + str(step) + ", Minibatch Loss= " + \ "{:.4f}".format(loss) + ", Training Accuracy= " + \ "{:.3f}".format(acc)) print("Optimization Finished!") # Calculate accuracy for 256 MNIST test images print("Testing Accuracy:", \ sess.run(accuracy, feed_dict={X: mnist.test.images[:256], y: mnist.test.labels[:256]})) print("run the tensorbord:tensorboard --logdir=E:/VGG16/tensorboard") 本次就先简单介绍使用tensorboard可视化VGG16,有兴趣的小伙伴,可以去试试看。