TensorFlow实现简单卷积网络

来源:互联网 发布:2016搞笑网络剧排行榜 编辑:程序博客网 时间:2024/06/05 16:16

CNN基本介绍

  • 卷积神经网络的概念最早出自19世纪60年代科学家提出的感受野(Receptive Field)。当时科学家对猫的视觉皮层细胞进行研究发现,每一个视觉神经元只会处理一小块的视觉图像,即感受野。
  • CNN的最大特点在于卷积的权值共享结构,可以大幅度减少神经网络的参数量,防止过拟合同时又降低了神经网络模型的复杂度。
  • 一般的卷积神经网络有多个卷基层构成,每个卷积层通常进行如下操作:
    • 图像通过多个不同的卷积核的滤波,并加以偏置(bias),提取局部特征,每一个卷积核会映射出一个新的2D图像。
    • 将前面的卷积核的滤波输出结果,进行非线性的激活函数处理。目前常见的是使用ReLU函数。
    • 对激活函数的结果进行池化操作。
  • 一个卷积核滤波得到的图像就是一类特征的映射,即一个Feature Map。
  • 一个卷积层可以有多个不同的卷积核,而每一个卷积核都对应一个滤波后映射出的新图像,同一个新图像中每一个像素都来自完全相同的卷积核,这就是权值共享。
    • eg:第一个卷积层C1包含6个卷积核,尺寸大小为5*5,即总共(5*5+1)*6个参数,其中1表示bias。

代码

#!/usr/bin/python3.5import tensorflow as tfimport tensorflow.examples.tutorials.mnist.input_data as input_datamnist = input_data.read_data_sets("MNIST_data", one_hot=True)sess = tf.InteractiveSession()def weight_variable(shape):    # 截断的正态分布噪声,标准差设为0.1    init = tf.truncated_normal(shape, stddev=0.1)    return tf.Variable(init)def bias_variable(shape):    init = tf.constant(0.1, shape=shape)    return tf.Variable(init)"""卷积x: 代表输入W: 卷积的参数    eg: [5, 5, 1, 32]    卷积核尺寸为5*5    图片channel为1,这里是灰度图片,如果RGB,值为3    卷积核的数量为32,也就是这个卷积层会提取多少特征strides: 卷积模板移动步长,都为1表示不遗漏划过图片每一个点         表示步长:一个长度为4的一维列表,每个元素跟data_format互相对应,         表示在data_format每一维上的移动步长。当输入的默认格式为:“NHWC”,         则 strides = [batch , in_height , in_width, in_channels]。         其中 batch 和 in_channels 要求一定为1,即只能在一个样本的一个通         道上的特征图上进行移动,in_height , in_width表示卷积核在特征图的         高度和宽度上移动的布长,即 strideheight 和 stridewidth 。padding: 边界的处理方式.         SAME简单地理解为以0填充边缘,但还有一个要求,左边(上边)补0的个数和右边(下边)补0的个数一样或少一个,         VALID表示采用不填充的方式,多余地进行丢弃。具体公式:         “SAME”: output_spatial_shape[i]=(input_spatial_shape[i] / strides[i])         “VALID”: output_spatial_shape[i]=((input_spatial_shape[i]-(spatial_filter_shape[i]-1)/strides[i])"""def conv2d(x, W):    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')"""ksize: 表示池化窗口的大小:一个长度为4的一维列表,一般为[1, height, width, 1],        因不想在batch和channels上做池化,则将其值设为1。"""def max_pool_2x2(x):    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')# -1代表不确定,自动算x = tf.placeholder(tf.float32, [None, 784])y_ = tf.placeholder(tf.float32, [None, 10])x_image = tf.reshape(x, [-1, 28, 28, 1])# 处理第一层W_conv1 = weight_variable([5, 5, 1, 32])b_conv1 = bias_variable([32])h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)h_pool1 = max_pool_2x2(h_conv1)# 处理第二层W_conv2 = weight_variable([5, 5, 32, 64])b_conv2 = bias_variable([64])h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)h_pool2 = max_pool_2x2(h_conv2)# 经过二次池化后图片变成了7x7,之后建立一个全连接,隐含节点为1024W_f1 = weight_variable([7*7*64, 1024])b_f1 = bias_variable([1024])h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_f1) + b_f1)# 使用dropout层减少过拟合keep_prob = tf.placeholder(tf.float32)h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)# softmax层W_f2 = weight_variable([1024, 10])b_f2 = bias_variable([10])y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_f2) + b_f2)cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))test_images = tf.placeholder(tf.float32, [None, 784])test_labels = tf.placeholder(tf.float32, [None, 10])# traintf.global_variables_initializer().run()for i in range(3000):    batch = mnist.train.next_batch(50)    if (i%100 == 0):  #训练100次,验证一次        train_accurancy = accuracy.eval(feed_dict={x: batch[0], y_: batch[1], keep_prob : 1.0})        print("step %d, traning accurancy %g" % (i, train_accurancy))    sess.run(train_step, feed_dict={x: batch[0], y_: batch[1], keep_prob : 0.5})# 我内存太小,我用小数据集test_images = mnist.test.images[0:300, :]test_labels = mnist.test.labels[0:300, :]print("test accuracy %g" % accuracy.eval({x: test_images, y_: test_labels, keep_prob: 1.0}))

运行结果

step 0, traning accurancy 0.02step 100, traning accurancy 0.8step 200, traning accurancy 0.94step 300, traning accurancy 0.86step 400, traning accurancy 0.94step 500, traning accurancy 0.96step 600, traning accurancy 1step 700, traning accurancy 0.92step 800, traning accurancy 0.96step 900, traning accurancy 0.96step 1000, traning accurancy 0.98step 1100, traning accurancy 0.96step 1200, traning accurancy 1step 1300, traning accurancy 1step 1400, traning accurancy 1step 1500, traning accurancy 0.98step 1600, traning accurancy 0.98step 1700, traning accurancy 0.96step 1800, traning accurancy 0.98step 1900, traning accurancy 0.96step 2000, traning accurancy 0.94step 2100, traning accurancy 0.92step 2200, traning accurancy 0.98step 2300, traning accurancy 0.98step 2400, traning accurancy 0.96step 2500, traning accurancy 1step 2600, traning accurancy 0.96step 2700, traning accurancy 1step 2800, traning accurancy 1step 2900, traning accurancy 0.98test accuracy 0.99

代码

#!/usr/bin/python3.5import tensorflow as tfimport cifar10, cifar10_inputimport numpy as np import timemax_steps = 3000batch_size = 128data_dir = '/tmp/cifar10_data/cifar-10-batches-bin'def variable_with_weight_loss(shape, stddev, w1):    var = tf.Variable(tf.truncated_normal(shape, stddev=stddev))    if w1 is not None:        weight_loss = tf.multiply(tf.nn.l2_loss(var), w1, name='weight_loss')        tf.add_to_collection('losses', weight_loss)    return varcifar10.maybe_download_and_extract()# 训练集和测试集images_train, labels_train = cifar10_input.distorted_inputs(data_dir=data_dir, batch_size=batch_size)images_test, labels_test = cifar10_input.inputs(eval_data=True, data_dir=data_dir, batch_size=batch_size)# 创建输入数据image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3])label_holder = tf.placeholder(tf.int32, [batch_size])# 第一个卷积层weigth1 = variable_with_weight_loss(shape=[5, 5, 3, 64], stddev=5e-2, w1=0.0)kernel1 = tf.nn.conv2d(image_holder, weigth1, [1, 1, 1, 1], padding='SAME')bias1 = tf.Variable(tf.constant(0.0, shape=[64]))conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')norml = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)# 第二个卷积层weigth2 = variable_with_weight_loss(shape=[5, 5, 64, 64], stddev=5e-2, w1=0.0)kernel2 = tf.nn.conv2d(norml, weigth2, [1, 1, 1, 1], padding='SAME')bias2 = tf.Variable(tf.constant(0.0, shape=[64]))conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2))norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')# 全连接层,隐含节点数为384reshape = tf.reshape(pool2, [batch_size, -1])dim = reshape.get_shape()[1].valueweight3 = variable_with_weight_loss(shape=[dim, 384], stddev=0.04, w1=0.004)bias3 = tf.Variable(tf.constant(0.1, shape=[384]))local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3)# 隐含层192个节点weight4 = variable_with_weight_loss(shape=[384, 192], stddev=0.04, w1=0.004)bias4 = tf.Variable(tf.constant(0.1, shape=[192]))local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4)# 输出层weight5 = variable_with_weight_loss(shape=[192, 10], stddev=1/192.0, w1=0.0)bias5 = tf.Variable(tf.constant(0.1, shape=[10]))logits = tf.add(tf.matmul(local4, weight5), bias5)# 计算lossdef loss(logits, labels):    labels = tf.cast(labels, tf.int64)    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels, name='cross_entropy_per_wxample')    cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')    tf.add_to_collection('losses', cross_entropy_mean)    return tf.add_n(tf.get_collection('losses'), name='total_loss')loss = loss(logits, label_holder)train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)# 计算top k 准确率top_k_op = tf.nn.in_top_k(logits, label_holder, 1)# 运行sess = tf.InteractiveSession()tf.global_variables_initializer().run()# 使用线程加速tf.train.start_queue_runners()# 训练#for step in range(max_steps):for step in range(200):    start_time = time.time()    image_batch, label_batch = sess.run([images_train, labels_train])    _, loss_value = sess.run([train_op, loss], feed_dict={image_holder: image_batch, label_holder: label_batch})    duration = time.time() - start_time    if (step % 100 == 0):        exmaples_per_sec = batch_size / duration        sec_per_batch = float(duration)        format_src = ('step %d, loss = %.2f(%.1f examlpes/sec, %.3f sec/batch)')        print(format_src % (step, loss_value, exmaples_per_sec, sec_per_batch))# 测试num_examples = 1000import mathnum_iter = int(math.ceil(num_examples / batch_size))true_count = 0total_sample_count = num_iter * batch_sizestep = 0while step < num_iter:    image_batch, label_batch = sess.run([images_test, labels_test])    predicition = sess.run([top_k_op], feed_dict={image_holder: image_batch, label_holder: label_batch})    true_count += np.sum(predicition)    step += 1precision = true_count / total_sample_countprint('precision = %.3f' % precision)

运行结果

step 0, loss = 4.67(48.7 examlpes/sec, 2.629 sec/batch)step 100, loss = 1.89(242.1 examlpes/sec, 0.529 sec/batch)step 200, loss = 1.95(224.8 examlpes/sec, 0.569 sec/batch)step 300, loss = 1.61(243.5 examlpes/sec, 0.526 sec/batch)step 400, loss = 1.45(237.7 examlpes/sec, 0.538 sec/batch)step 500, loss = 1.45(268.5 examlpes/sec, 0.477 sec/batch)step 600, loss = 1.43(245.8 examlpes/sec, 0.521 sec/batch)step 700, loss = 1.17(227.3 examlpes/sec, 0.563 sec/batch)step 800, loss = 1.38(215.6 examlpes/sec, 0.594 sec/batch)step 900, loss = 1.45(260.5 examlpes/sec, 0.491 sec/batch)step 1000, loss = 1.39(226.1 examlpes/sec, 0.566 sec/batch)step 1100, loss = 1.38(266.3 examlpes/sec, 0.481 sec/batch)step 1200, loss = 1.36(230.3 examlpes/sec, 0.556 sec/batch)step 1300, loss = 1.19(217.4 examlpes/sec, 0.589 sec/batch)step 1400, loss = 1.26(270.3 examlpes/sec, 0.474 sec/batch)step 1500, loss = 1.16(277.0 examlpes/sec, 0.462 sec/batch)step 1600, loss = 1.10(244.0 examlpes/sec, 0.525 sec/batch)step 1700, loss = 1.23(272.3 examlpes/sec, 0.470 sec/batch)step 1800, loss = 1.24(289.6 examlpes/sec, 0.442 sec/batch)step 1900, loss = 1.07(274.2 examlpes/sec, 0.467 sec/batch)step 2000, loss = 1.23(281.0 examlpes/sec, 0.456 sec/batch)step 2100, loss = 1.23(278.8 examlpes/sec, 0.459 sec/batch)step 2200, loss = 1.14(257.5 examlpes/sec, 0.497 sec/batch)step 2300, loss = 0.94(261.4 examlpes/sec, 0.490 sec/batch)step 2400, loss = 1.06(175.3 examlpes/sec, 0.730 sec/batch)step 2500, loss = 1.15(230.4 examlpes/sec, 0.556 sec/batch)step 2600, loss = 1.08(250.8 examlpes/sec, 0.510 sec/batch)step 2700, loss = 1.15(253.3 examlpes/sec, 0.505 sec/batch)step 2800, loss = 1.10(250.6 examlpes/sec, 0.511 sec/batch)step 2900, loss = 1.10(220.0 examlpes/sec, 0.582 sec/batch)precision = 0.738
原创粉丝点击