卷积神经网络(CNN)概念构建

从数学开始
先从字面意思开始吧。
何谓卷积:卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果:

如果卷积的变量是函数x(t)和h(t),则卷积的计算变为:

我猜叫卷积神经网络大概是在构建神经网络过程中会用到卷积操作。

我懂你的特别
传统神经网络中,一般采取 全连接 的方式,下面就是这样一个4层神经网络,输入和第一个隐层的每个神经元都相连接。这样神经网络参数量巨大,很难训练。

而在CNN中采取 局部连接权值共享 的方式来避免这个问题。
假设有一个有1000×1000的输入图像的神经网络,并且隐层有10^6个神经元。

  • 那么采取 全连接 的方式,就需要1000×1000×10^6即10^12个权值参数。
  • 如果采用 局部连接,将隐层神经元和输入图像eg.10×10的局部图像相连,那么需要权值:10×10×10^6即10^8个权值。
  • 如果在采用局部连接的基础上,再进行 权值共享,即10^6个隐层神经元共享一组10×10的权值,那么只需要10×10个权值参数。在这种情况下,10×10就是卷积核的大小。

但是这样仅提取了图像的 一种特征,想要多提取几个特征,就需要 多个卷积核。不同的卷积核能够得到图像的不同映射下的特征,称之为Feature Map。
(哪里不会点哪里~(≧∀≦)ゞ送上卷积核)
卷积核:卷积时使用到的权用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行、列都是奇数,是一个权矩阵。

CNN中两种网络层

  • 卷积层:用于提取图像的各种特征。将卷积层在上一层输入层逐一 滑动窗口 得到,在滑动过程中将 卷积核中的参数局部像素 对应相乘之和。通常还会加上偏置。
  • 池化/采样层(pooling):对原始特征信号进行抽象,大幅度减少训练参数,减轻过拟合。通常有两种方式:
    • Max-Pooling:将Pooling窗口最大值作为采样值;
    • Mean-Pooling:Pooling窗口的平均值作为采样值。

示例:

从上图中我们可以看到有一个5×5的图像(绿色),一个3×3的卷积核(黄色),一个3×3的的特征图(右边)。
图像上面的黄色区域表示正在进行卷积操作。
即(1×1+1×0+1×1)+(0×0+1×1+1×0)+(0×1+0×0+1×1)=4
卷积核的滑动过程见下图:

再理解MINIST进阶代码
看这里构建神经网络代码的时候看懵了,然后就跑去了解卷积神经网络到底是什么,到这时候就大概能够看懂这些代码到底在干嘛,为什么要这么做,对于卷积神经网络的结构也有一个大致的了解。

# -*- coding: utf-8 -*-
"""
Created on Mon Mar  6 10:56:46 2017

@author: Administrator
"""

#minist存储训练、校验和测试数据集。
#并提供函数,用于在迭代中获得minibatch
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)


import tensorflow as tf
#创建交互式会话
sess = tf.InteractiveSession()

#为输入图像和目标输出类创建节点
x = tf.placeholder("float", shape=[None, 784])
y_ = tf.placeholder("float", shape=[None, 10])

#模型参数:权重和偏置,初始化为零向量
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

#变量要在session中初始化后才能使用
sess.run(tf.initialize_all_variables())

#回归模型:softmax
y = tf.nn.softmax(tf.matmul(x,W) + b)

#损失函数:采用目标类别和预测类别之间的交叉熵
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

#用梯度下降训练模型:步长为0.01,目的是使cross_entropy最小化
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

#训练模型:迭代1000次,每次迭代加载50个训练样本
for i in range(1000):
  batch = mnist.train.next_batch(50)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

#评估模型:检测预测是否与真实标签匹配
#tf.argmax能给出某个tensor对象在某一维上的其数据最大值所在的索引值
#correct_prediction是一个布尔数组
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

#将上面的布尔数组装换为预测准确率
#tf.cast()将correct_prediction里的数据转换为float类型
#eg:a = [1.8, 2.2]  tf.cast(a, tf.int32) ==> [1, 2]
#tf.reduce_mean(x)取x的均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
#计算在测试机上的准确率
print (accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

#初始化权重
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

#卷积和池化函数定义
#用2×2的窗口,采取最大池化方法
def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')

#第一层卷积
#卷积核32@5×5
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
#使图像和计算层匹配
x_image = tf.reshape(x, [-1,28,28,1])
#卷积并使用ReLU激活函数
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
#池化
h_pool1 = max_pool_2x2(h_conv1)

#第二层卷积
#卷积核64@5×5
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)

#全连接层
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
#将最后的pooling层的输出reshape为一个一维向量
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

#Dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)


#输出层
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
#使用softmax得到各类别上概率
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

#训练和评估模型
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
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, "float"))
sess.run(tf.initialize_all_variables())
for i in range(20000):
  batch = mnist.train.next_batch(50)
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:batch[0], y_: batch[1], keep_prob: 1.0})
    print ("step %d, training accuracy %g"%(i, train_accuracy))
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print ("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

参考资料

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值