卷积神经网络学习理解(CNN)

很多时候看似自己懂了,其实不把自己的理解总结出来,永远不会发现自己真正不懂得地方。所以借着学习卷积神经网络的机会,记录一下自己的理解。如果有出现偏差的地方,希望大家指正,共同学习。



一 卷积神经网络



积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。[2]  它包括卷积层(convolutional layer)和池化层(pooling layer)。




二 卷积神经网络结构





 
卷积神经网络结构如上图所示,输入是图像处理后的数据,以矩阵的形式表示,如上面汽车图片;然后经过
卷积层CONV转换;在经过线性整流RELU;卷积层和线性整流层可以多次叠加;再经过池化POOL;卷积层,
线性整流层和池化过程也可以多次叠加;最后经过全连接FC;全连接也可以叠加多次。结构如下:
Input->((CONV->RELU)*m->POOL)*n->(FC)*k->output

输入图像如下,高度height, 宽度width,图片像素rgb表示channels, 所以图片表示如下,
 X[width, height, channels]。


三 卷积层




 卷积层主要要解决的问题是,我们使用全连接的神经网络处理图片输入,如果图片比较小,没有任何问题,但是当图片
 信息量比较大时,这样全连接计算量就变得非常大,训练模型代价就非常昂贵。为了解决这个问题,卷积神经网络使用卷积
 层的概念,将卷积层神经网络设计成m*n的大小k个filter网络层。如果用m*n的网络层对输入进行拟合呢,就需要用m*n的
视野在输入图片特征上进行滑动,滑动的步伐会再x和y方向进行[S1,S2]步长的滑动。m*n*k的神经网络在所有图片输入特征
上是共享的。


简化一下,我们只在图片的一个方向进行窗口滑动,如上图所示。我们在图片的X轴上进行滑动,我们再X轴上的视野是F=3,
图片在x轴的宽度W=5,我们用0补偿图片x轴的两边P=1,第一幅度滑动步长S=1,第二幅图步长S=2。卷积层的输出大小等于
SIZE(Output) = (W - F + 2*P)/S + 1,所以第一个神经网络的输出大小等于5,第二神经网络的输出大小等于3。


二维图片输入卷积过程,类似于上面简化的图片处理过程,只不过卷积的视野沿着x轴y轴的方向进行滑动,并产生二维的
输出结果。

四 线性整流(ReLU)



通常意义下,线性整流函数代指代数学中的斜坡函数,即



而在神经网络中,线性整流函数作为神经元的激活函数,定义了该神经元在线性变换 


 之后的的非线性输出结果。换言之,对于进入神经元的来自上一层神经网络的输入向量 X


 ,使用线性整流激活函数的神经元会输出


至下一层神经元或作为整个神经网络的输出(取决现神经元在网络结构中所处位置)。



五 池化



池化的过程是信息压缩的过程,池化层以上面卷积层和线性整流后的输出结果作为输入,然后对输入的图片信息,进行下采样,采样filter是一个width*height的窗口。如右图所示,输入是8*8的输入图片,通过2*2的filters,以S=2的步伐滑动,然后进行max采样,会产生2*2的输出特征。

五 全连接

全连接层是普通的神经网络结构,会把输入全部连接到全连接层神经元。

六 TensorFlow实现卷积神经网络

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# Imports
import numpy as np
import tensorflow as tf

tf.logging.set_verbosity(tf.logging.INFO)

# Our application logic will be added here

def cnn_model_fn(features, labels, mode):
  """Model function for CNN."""
  # Input Layer
  input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])

  # Convolutional Layer #1
  # 卷积层1
  # 卷积核大小为5x5,卷积核数量为32, 激活方法使用RELU
  # 输入Tensor维度: [batch_size, 28, 28, 1]
  # 输出Tensor维度: [batch_size, 28, 28, 32]
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=32,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

  # Pooling Layer #1
  # 池化层1
  # 采用2x2维度的最大化池化操作,步长为2
  # 输入Tensor维度: [batch_size, 28, 28, 32]
  # 输出Tenso维度: [batch_size, 14, 14, 32]
  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

  # Convolutional Layer #2 and Pooling Layer #2
  # 卷积层2
  # 卷积核大小为5x5,卷积核数量为64, 激活方法使用RELU.
  # 输入Tensor维度: [batch_size, 14, 14, 32]
  # 输出Tensor维度: [batch_size, 14, 14, 64]
  conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=64,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
  # 池化层2
  # 采用2x2维度的最大化池化操作,步长为2
  # 输入Tensor维度: [batch_size, 14, 14, 64]
  # 输出Tensor维度: [batch_size, 7, 7, 64]
  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

  # Dense Layer
  # 展开并列池化层输出Tensor为一个向量
  # 输入Tensor维度: [batch_size, 7, 7, 64]
  # 输出Tensor维度: [batch_size, 7 * 7 * 64]
  pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
  # 全链接层
  # 该全链接层具有1024神经元
  # 输入Tensor维度: [batch_size, 7 * 7 * 64]
  # 输出Tensor维度: [batch_size, 1024]
  dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
  # 对全链接层的数据加入dropout操作,防止过拟合
  # 40%的数据会被dropout,
  dropout = tf.layers.dropout(
      inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

  # Logits Layer
  # Logits层,对dropout层的输出Tensor,执行分类操作
  # 输入Tensor维度: [batch_size, 1024]
  # 输出Tensor维度: [batch_size, 10]
  logits = tf.layers.dense(inputs=dropout, units=10)

  predictions = {
      # Generate predictions (for PREDICT and EVAL mode)
      "classes": tf.argmax(input=logits, axis=1),
      # Add `softmax_tensor` to the graph. It is used for PREDICT and by the
      # `logging_hook`.
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  # Calculate Loss (for both TRAIN and EVAL modes)
  loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

  # Configure the Training Op (for TRAIN mode)
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  # Add evaluation metrics (for EVAL mode)
  eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(
          labels=labels, predictions=predictions["classes"])}
  return tf.estimator.EstimatorSpec(
      mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

def main(unused_argv):
  # Load training and eval data
  mnist = tf.contrib.learn.datasets.load_dataset("mnist")
  train_data = mnist.train.images # Returns np.array
  train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
  eval_data = mnist.test.images # Returns np.array
  eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
  mnist_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")
  # Set up logging for predictions
  tensors_to_log = {"probabilities": "softmax_tensor"}
  logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)
  # Train the model
  train_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": train_data},
      y=train_labels,
      batch_size=100,
      num_epochs=None,
      shuffle=True)
  mnist_classifier.train(
      input_fn=train_input_fn,
      steps=10000,
      hooks=[logging_hook])
  # Evaluate the model and print results
  eval_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={"x": eval_data},
      y=eval_labels,
      num_epochs=1,
      shuffle=False)
  eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
  print(eval_results)

if __name__ == "__main__":
  tf.app.run()

七 相关链接

  1. http://blog.csdn.net/witsmakemen/article/details/79183395
  2. http://blog.csdn.net/witsmakemen/article/details/79188393






  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WitsMakeMen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值