前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >卷积神经网络实战MNIST

卷积神经网络实战MNIST

作者头像
公众号guangcity
发布2019-09-20 15:26:47
7010
发布2019-09-20 15:26:47
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

导语

关于卷积神经网络理论的学习,可以看:卷积神经网络

本节学习来源斯坦福大学cs20课程,有关本节源代码已同步只至github,欢迎大家star与转发,收藏!

cs20是一门对于深度学习研究者学习Tensorflow的课程,今天学习第 六与七节,非常有收获,并且陆续将内容写入jupytebook notebook中,有关这个源代码及仓库地址,大家可以点击阅读原文或者直接复制下面链接!

直通车: https://github.com/Light-City/Translating_documents

TensorFlow中的卷积

在TensorFlow中去做卷积,我们有很多内建的层可以使用。你可以输入2维数据做1维卷积,输入3维数据做2维卷积,输入4维数据做3维卷积,最常用的是2维卷积。

代码语言:javascript
复制
# 函数模型
tf.nn.conv2d(
    input,
    filter,
    strides,
    padding,
    use_cudnn_on_gpu=True,
    data_format='NHWC',
    dilations=[1, 1, 1, 1],
    name=None)

Input: Batch size (N) x Height (H) x Width (W) x Channels (C)
Filter: Height x Width x Input Channels x Output Channels
(e.g. [5, 5, 3, 64])
Strides: 4 element 1-D tensor, strides in each direction
(often [1, 1, 1, 1] or [1, 2, 2, 1])
Padding: 'SAME' or 'VALID'
Dilations: The dilation factor. If set to k > 1, there will be k-1 skipped cells between each filter element on that dimension.
Data_format: default to NHWC

作一个有趣的练习:在上面GitHub中的kernes.py文件中看到一些著名的核的值,在07_run_kernels.py中看到它们的用法。

用CNN处理MNIST

在第三课中学习了逻辑回归处理MNIST,现在我们使用CNN来处理,看看结果如何!

将采用如下架构:两个步长为1的卷积层,每个卷积层后跟一个relu激活层与最大池化层Maxpool,最后跟两个全连接层。

1.卷积层

  • 输入尺寸(W)
  • 过滤器尺寸(F)
  • 步长(S)
  • 零填充(P)

在定义函数之前,让我们看一下获取输出大小的公式。当您具有上述输入值时,输出的大小如下所示:

在我们的MNIST模型中,输入为28x28,滤波器为5x5。并且步幅使用1和填充使用2。因此,输出的大小如下:

代码语言:javascript
复制
def conv_relu(inputs, filters, k_size, stride, padding, scope_name):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        # rgb通道
        in_channels = inputs.shape[-1]
        # 卷积核
        kernel = tf.get_variable('kernel', [k_size, k_size, in_channels, filters],
                                initializer=tf.truncated_normal_initializer())
        biases = tf.get_variable('biases', [filters],
                            initializer=tf.random_normal_initializer())
        # 卷积结果
        conv = tf.nn.conv2d(inputs, kernel, strides=[1, stride, stride, 1], padding=padding)
    # relu层对卷积结果处理
    return tf.nn.relu(conv + biases, name=scope.name)

2.池化层

池化可减少要素图的维数,提取要素并缩短执行时间。

通常使用max-pooling或average-pooling。

由于在此模型中使用了max-pooling,因此我们定义了max-pooling函数,如下所示:

  • 输入尺寸(W)
  • 池化大小(K)
  • 池化步长(S)
  • 池化零填充(P)

在我们的模型中,输入是28x28,池大小是2x2,补长是2,零填充,所以我们将输出大小如下。

代码语言:javascript
复制
def maxpool(inputs, ksize, stride, padding='VALID', scope_name='pool'):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        pool = tf.nn.max_pool(inputs,
                            ksize=[1, ksize, ksize, 1],
                            strides=[1, stride, stride, 1],
                            padding=padding)
    return pool

3.全连接层

代码语言:javascript
复制
def fully_connected(inputs, out_dim, scope_name='fc'):
    with tf.variable_scope(scope_name, reuse=tf.AUTO_REUSE) as scope:
        in_dim = inputs.shape[-1]
        w = tf.get_variable('weights', [in_dim, out_dim],
                            initializer=tf.truncated_normal_initializer())
        b = tf.get_variable('biases', [out_dim],
                            initializer=tf.constant_initializer(0.0))
        out = tf.matmul(inputs, w) + b
    return out

4.组合调用

现在让我们通过组合我们创建的函数来创建整个模型。您可以使用我们按顺序创建的功能。

需要注意的一点是,当您在最后一次池化后转到fc层时,必须通过将一维向量的大小乘以原始数组的每个维度的长度来重新整形三维数组的一维数组。

最后,将dropout应用到fc层。

代码语言:javascript
复制
def inference(self):
        conv1 = conv_relu(inputs=self.img,
                        filters=32,
                        k_size=5,
                        stride=1,
                        padding='SAME',
                        scope_name='conv1')
        pool1 = maxpool(conv1, 2, 2, 'VALID', 'pool1')
        conv2 = conv_relu(inputs=pool1,
                        filters=64,
                        k_size=5,
                        stride=1,
                        padding='SAME',
                        scope_name='conv2')
        pool2 = maxpool(conv2, 2, 2, 'VALID', 'pool2')
        feature_dim = pool2.shape[1] * pool2.shape[2] * pool2.shape[3]
        pool2 = tf.reshape(pool2, [-1, feature_dim])
        fc = tf.nn.relu(fully_connected(pool2, 1024, 'fc'))
        dropout = tf.layers.dropout(fc, self.keep_prob, training=self.training, name='dropout')

        self.logits = fully_connected(dropout, self.n_classes, 'logits')

5.loss

代码语言:javascript
复制
def loss(self):
        '''
        define loss function
        use softmax cross entropy with logits as the loss function
        compute mean cross entropy, softmax is applied internally
        '''
        # 
        with tf.name_scope('loss'):
            entropy = tf.nn.softmax_cross_entropy_with_logits(labels=self.label, logits=self.logits)
            self.loss = tf.reduce_mean(entropy, name='loss')

6.评估

在训练时,需要评估每个epoch的准确率。

代码语言:javascript
复制
def eval(self):
        '''
        Count the number of right predictions in a batch
        '''
        with tf.name_scope('predict'):
            preds = tf.nn.softmax(self.logits)
            correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(self.label, 1))
            self.accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))

7.运行

7.1 数据shape变化
代码语言:javascript
复制
conv:Tensor("conv1_1:0", shape=(?, 28, 28, 32), dtype=float32)
pool1:Tensor("pool1/MaxPool:0", shape=(?, 14, 14, 32), dtype=float32)
conv2:Tensor("conv2_1:0", shape=(?, 14, 14, 64), dtype=float32)
pool2:Tensor("pool2/MaxPool:0", shape=(?, 7, 7, 64), dtype=float32)
feature_dim:3136
pool2:Tensor("Reshape:0", shape=(?, 3136), dtype=float32)
fc:Tensor("fc/add:0", shape=(?, 1024), dtype=float32)
dropout:Tensor("relu_dropout/mul:0", shape=(?, 1024), dtype=float32)
self.logits:Tensor("logits/add:0", shape=(?, 10), dtype=float32)
7.2 运行精度
代码语言:javascript
复制
...
...
...
Loss at step 19: 15894.556640625
Loss at step 39: 8952.953125
Loss at step 59: 6065.05322265625
Loss at step 79: 2913.25048828125
Loss at step 99: 2803.952392578125
Loss at step 119: 1727.0462646484375
Loss at step 139: 2886.213134765625
Loss at step 159: 2611.1953125
Loss at step 179: 1743.4693603515625
Loss at step 199: 898.48046875
Loss at step 219: 2171.2890625
Loss at step 239: 475.59246826171875
Loss at step 259: 1289.218017578125
Loss at step 279: 933.6298828125
Loss at step 299: 614.7198486328125
Loss at step 319: 1771.800048828125
Loss at step 339: 1211.3431396484375
Loss at step 359: 1274.873291015625
Loss at step 379: 820.397705078125
Loss at step 399: 633.9185791015625
Loss at step 419: 830.4837646484375
Average loss at epoch 0: 3882.1572788682097
...
...
...
Average loss at epoch 29: 3.834926734323245
Took: 13.498510360717773 seconds
Accuracy at epoch 29: 0.9825 
Took: 0.7468070983886719 seconds
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
  • TensorFlow中的卷积
  • 用CNN处理MNIST
    • 1.卷积层
      • 2.池化层
        • 3.全连接层
          • 4.组合调用
            • 5.loss
              • 6.评估
                • 7.运行
                  • 7.1 数据shape变化
                  • 7.2 运行精度
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档