【TensorFlow】TensorFlow 的卷积神经网络 CNN - 无TensorBoard版

前面 有篇博文讲了多层感知器,也就是一般的前馈神经网络,文章里使用 CIFAR10 数据集得到的测试准确率是 46.98%。今天我们使用更适合处理图像的卷积神经网络来处理相同的数据集 - CIFAR10,来看下准确率能达到多少。

本文代码基于 TensorFlow 的官方文档 做了些许修改,完整代码及结果图片可从 这里 下载。

这篇文章是对本文的一个升级,增加了 TensorBoard 的实现,可以在浏览器中查看可视化结果,包括准确率、损失、计算图、训练时间和内存信息等。

更新

这里我会列出对本文的更新。

  • 2017年3月17日:增加实现 TensorBoard 的文章的链接。

原理

关于卷积神经网络(Convolutional Neural Network,以下简称 CNN)网上有很多优秀的教程,我在这里也不再重复造轮子,强烈推荐 斯坦福的CS321n,讲的很全面。

还是和以前一样,我在这里简单说下 CNN 的原理。首先来看下一个典型的 CNN - LeNet5 的结构图,

这个 CNN 是 Yann LeCun 在 1998 年发表的论文 Gradient-Based Learning Applied to Document Recognition 中所提出的,用于字符识别。如上图,模型输入是一个字符图像,然后对输入进行卷积操作(矩阵点乘求和)得到 C1 卷积层,再进行下采样操作(缩减维度)得到 S2 池化层或者叫下采样层,然后重复一遍刚才的操作,将二维数据 拉平,连着一个多层的普通神金网络,最终得到输出。训练这个模型的方法还是梯度下降法,或者其变种。

数据集

数据集仍然采用 CIFAR10,包含 6000032×32 的彩色RGB图像,共有 10 类,每类有 6000 张图像。完整数据集可以从 这里 下载,注意选择 Python 版本,大概是 163 MB。

下载好后解压会看到有 5 个训练文件和 1 个测试文件,还有一个说明文件 batches.meta,这个文件说明了每个数字类别(0-9)具体代表哪些类别。这几个文件都是用 cPickle 打包好的,所以载入数据也要用 cPickle 来载入。注意 Python2Python3 的载入方式稍微有些不同,具体见代码,我使用的是 Python3

目前在此数据集上做的实验在没有数据增加的情况下最低的错误率是 18%,数据增加的情况下最低的错误率是 11%,都是采用的卷积神经网络(CNN)的结构。

数据集中的图像和分类大致是这样的:

代码

由于完整代码较长,这里仅列出关键代码,便于理解整个模型,完整代码可从 这里 下载。

# coding: utf-8

with tf.device('/cpu:0'):

    # 模型参数
    learning_rate = 1e-3
    training_iters = 500
    batch_size = 50
    display_step = 5
    n_features = 3072  # 32*32*3
    n_classes = 10
    n_fc1 = 384
    n_fc2 = 192

    # 构建模型
    x = tf.placeholder(tf.float32, [None, n_features])
    y = tf.placeholder(tf.float32, [None, n_classes])


    w = {
        'conv1': tf.Variable(tf.truncated_normal([5, 5, 3, 64], stddev=5e-2)),
        'conv2': tf.Variable(tf.truncated_normal([5, 5, 64, 64], stddev=0.1)),
        'fc1': tf.Variable(tf.truncated_normal([8*8*64, n_fc1], stddev=0.04)),
        'fc2': tf.Variable(tf.truncated_normal([n_fc1, n_fc2], stddev=0.1)),
        'fc3': tf.Variable(tf.truncated_normal([n_fc2, n_classes], stddev=1/192.0))
    }
    b = {
        'conv1': tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[64])),
        'conv2': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[64])),
        'fc1': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[n_fc1])),
        'fc2': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[n_fc2])),
        'fc3': tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[n_classes]))
    }

    x4d = tf.reshape(x, [-1, 32, 32, 3])
    # 卷积层 1
    conv1 = tf.nn.conv2d(x4d, w['conv1'], strides=[1, 1, 1, 1], padding='SAME')
    conv1 = tf.nn.bias_add(conv1, b['conv1'])
    conv1 = tf.nn.relu(conv1)
    # 池化层 1
    pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')
    # LRN层,Local Response Normalization
    norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)
    # 卷积层 2
    conv2 = tf.nn.conv2d(norm1, w['conv2'], strides=[1, 1, 1, 1], padding='SAME')
    conv2 = tf.nn.bias_add(conv2, b['conv2'])
    conv2 = tf.nn.relu(conv2)
    # LRN层,Local Response Normalization
    norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001/9.0, beta=0.75)
    # 池化层 2
    pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')
    reshape = tf.reshape(pool2, [-1, 8*8*64])
    dim = reshape.get_shape()[1].value
    fc1 = tf.add(tf.matmul(reshape, w['fc1']), b['fc1'])
    fc1 = tf.nn.relu(fc1)
    # 全连接层 2
    fc2 = tf.add(tf.matmul(fc1, w['fc2']), b['fc2'])
    fc2 = tf.nn.relu(fc2)
    # 全连接层 3, 即分类层
    fc3 = tf.add(tf.matmul(fc2, w['fc3']), b['fc3'])

    # 定义损失
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(fc3, y))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
    # 评估模型
    correct_pred = tf.equal(tf.argmax(fc3, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

    init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    c = []
    total_batch = int(X_train.shape[0] / batch_size)
    for i in range(training_iters):
        avg_cost = 0
        for batch in range(total_batch):
            batch_x = X_train[batch*batch_size : (batch+1)*batch_size, :]
            batch_y = y_train[batch*batch_size : (batch+1)*batch_size, :]
            _, co = sess.run([optimizer, cost], feed_dict={x: batch_x, y: batch_y})
            avg_cost += co

        c.append(avg_cost)
        if (i+1) % display_step == 0:
            print("Iter " + str(i+1) + ", Training Loss= " + "{:.6f}".format(avg_cost))

    print("Optimization Finished!")

    # Test
    test_acc = sess.run(accuracy, feed_dict={x: X_test, y: y_test})
    print("Testing Accuracy:", test_acc)

结果

其中的缩写仍然遵照我以前博文的习惯:

  • lr:learning rate,学习率
  • ti:training iters,训练迭代次数
  • bs:batch size,batch大小
  • acc:测试准确率

每次结果都会不一样,上图是最好的结果的时候,其他结果图的下载链接和上面一样,测试准确率大约为 60%,其实这个准确率并不高,和 TensorFlow 的官方文档 所得到的 86% 还差一段距离,和官方文档的差距在于我并没有对数据进行更多的预处理,例如图像裁剪到 24×24 的尺寸、标准化、随机左右翻转图像或者随机改变图像亮度和对比度以扩大数据集等等,等有时间再进行进一步的实验,与本次实验进行对比。

在其他条件一样的情况下,本次实验得到的准确率可能并不是最高的,鉴于机器太垃圾,运行一次实验需要两三天,未能进行更多的测试。

END

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

深度学习Matlab工具箱代码注释之MnistTest.m

%%========================================================================= %...

23670
来自专栏AI研习社

Github 项目推荐 | 100+ Chinese Word Vectors 上百种预训练中文词向量

该项目提供了不同表征(密集和稀疏)上下文特征(单词,ngram,字符等)和语料库训练的中文单词向量。开发者可以轻松获得具有不同属性的预先训练的向量,并将它们用于...

21020
来自专栏云时之间

深度学习与神经网络:mnist数据集实现手写数字识别

对于mnist数据集,具体的一些介绍我这里就不搬运过来了,这里我直接说我们如何在TensorFlow上使用mnist数据集.

430110
来自专栏求索之路

cs231n之KNN算法

1.环境搭建以及前置条件 1.前置环境: 1.mac 2.pycharm 3.python3 4.Anaconda 2.环境搭建: 1.官网下载并安装Ana...

36290
来自专栏大数据挖掘DT机器学习

Tensorflow:基于LSTM轻松生成各种古诗

RNN不像传统的神经网络-它们的输出输出是固定的,而RNN允许我们输入输出向量序列。RNN是为了对序列数据进行建模而产生的。 样本序列性:样本间存在顺序关系,...

54060
来自专栏和蔼的张星的图像处理专栏

4. 经典卷积网络之AlexNet

原文:《ImageNet Classification with Deep Convolutional Neural Networks》 我没有读原文,这个已...

18620
来自专栏AI科技评论

深度丨机器学习零基础?手把手教你用TensorFlow搭建图像识别系统(三)

AI科技评论按:本文是介绍用TensorFlow构建图像识别系统的第三部分。 在前两部分中,我们构建了一个softmax分类器来标记来自CIFAR-10数据集的...

39160
来自专栏智能算法

深度学习三人行(第9期)----卷积神经网络实战进阶(附代码)

接下来我们一起学习下关于CNN的代码实现,内存计算和池化层等相关知识,我们多多交流,共同进步。本期主要内容如下:

11230
来自专栏贾志刚-OpenCV学堂

干货 | Tensorflow设计简单分类网络实现猫狗图像分类训练与测试

第一层:32个feature map 5x5卷积、步长为2、最大值池化 局部相应归一化处理(LRN) 第二层:64个feature map 3x3卷积、步长为...

79840
来自专栏AI研习社

TensorFlow | 自己动手写深度学习模型之全连接神经网络

前半个多月总共写了三篇深度学习相关的理论介绍文章,另外两个月前,我们使用逻辑回归算法对sklearn里面的moons数据集进行了分类实验,最终准确率和召回率都达...

600100

扫码关注云+社区

领取腾讯云代金券