卷积神经网络的组成:【输入-CONV-RELU-POOL-FC】
- 输入层
- 卷积层
- 激活函数
- 池化层
- 全连接层
卷积层:
这一层就是卷积神经网络最重要的一个层次,也是“卷积神经网络”的名字来源。
在这个卷积层,有两个关键操作:
•局部关联。每个神经元看做一个滤波器(过滤器)
•窗口(receptive field)滑动,过滤对局部数据计算
先介绍卷积层遇到的几个名词:
•深度/ depth(解释见下图)
•步长/ stride(窗口一次滑动的长度)
•填充值/零填充
筛选最后的维度与输入的维度相同
数据经过卷积操作以后,得到的是一张特征图
填充值是什么呢?以下图为例子,比如有这么一个5×5的图片(一个格子一个像素),我们滑动窗口取2×2,步长取2,那么我们发现还剩下1个像素没法滑完,那怎么办呢?
我们在原先的矩阵加了一层填充值,使得变成6×6的矩阵,那么窗口就可以刚好把所有像素遍历完。这就是填充值的作用。
卷积的计算过程:
蓝色的区域为原始的输入(7 * 7 * 3),有一张图像长宽为7通道为3(RGB)
接下来我们进行卷积操作,首先我们要确定一个过滤器大小我们指定的是(H = 3,W = 3)大小的
接下来就是原始输入上找出一个跟过滤大小相同的小区域,然后求内积,比如第一次内积0 * 1 + 0 * 1 + 0 * 1 + 0 * 1 + -1 * 1 + 1 * 0 + 0 * -1 + 1 * 1 + 0 * 1 = 0这只是第一层深度的计算结果,还有第二层,第三层深度,进行分别计算
下面的动态图产品形象地展示了卷积层的计算过程
步幅和填充
斯瑞德表示每次过滤器滑动的步长,我们可以通过stide定义输出的矩阵大小,阔步选择不能选择太大,也不能选择太小
填充在原始的输入上加上一层0
参数共享机制
•在卷积层中每个神经元连接数据窗的权重是固定的,每个神经元只关注一个特性。神经元就是图像处理中的滤波器,比如边缘检测专用的Sobel滤波器,即卷积层的每个滤波器都会有自己所关注一个图像特征,比如垂直边缘,水平边缘,颜色,纹理等等,这些所有神经元加起来就好比就是整张图像的特征提取器集合。
•需要估算的权重个数减少:AlexNet 1亿=> 3.5w
•一组固定的权重和不同窗口内数据做内积:卷积
池化层:特征的压缩
池化层用的方法有最大池和平均池,而实际用的较多的是最大池。
Max pooling,就是每一个区域取最大值
下面用代码说明:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(".",one_hot = True)
import tensorflow as tf
import os
#Parameters
learning_rate = 0.1
training_epochs = 5
batch_size = 100
display_step = 1
#Network Parameters
n_input = 784
n_classes = 10
#tf Graph input
x = tf.placeholder("float",[None,n_input])
y = tf.placeholder("float",[None,n_classes])
#pre-define
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')
#Create model
def multilayer_preceptron(x,weights,biases):
#now,we want to change this to a CNN network
#first,reshape the data to 4_D ,
x_image=tf.reshape(x,[-1,28,28,1])
#then apply cnn layers ,cnn layer and activation function --relu
h_conv1=tf.nn.relu(conv2d(x_image,weights['conv1'])+biases['conv_b1'])
#first pool layer
h_pool1=max_pool_2x2(h_conv1)
#second cnn layer
h_conv2=tf.nn.relu(conv2d(h_pool1,weights['conv2'])+biases['conv_b2'])
#second pool layer
h_pool2=max_pool_2x2(h_conv2)
h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64])
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,weights['fc1'])+biases['fc1_b'])
out_layer=tf.matmul(h_fc1,weights['out'])+biases['out_b']
return out_layer
weights={
'conv1':tf.Variable(tf.random_normal([5,5,1,32])),
'conv2':tf.Variable(tf.random_normal([5,5,32,64])),
'fc1':tf.Variable(tf.random_normal([7*7*64,256])),
'out':tf.Variable(tf.random_normal([256,n_classes]))
}
biases={
'conv_b1':tf.Variable(tf.random_normal([32])),
'conv_b2':tf.Variable(tf.random_normal([64])),
'fc1_b':tf.Variable(tf.random_normal([256])),
'out_b':tf.Variable(tf.random_normal([n_classes]))
}
#Construct model
pred = multilayer_preceptron(x,weights,biases)
#Define loss and optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y))
optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
#Initializing the variables
init = tf.global_variables_initializer()
#saver model
model_saver = tf.train.Saver()
#Launch the gtrph
with tf.Session() as sess:
sess.run(init)
#Training cycle
for epoch in range(training_epochs):
avg_cost=0.
total_batch=int(mnist.train.num_examples/batch_size)
#Loop over all batches
for i in range(total_batch):
batch_x,batch_y=mnist.train.next_batch(batch_size)
#run optimization op (backprop)and cost op (to get loss value)
_,c=sess.run([optimizer,cost],feed_dict={x:batch_x,y:batch_y})
#Compute average loss
avg_cost+=c/total_batch
#Display logs per epoch step
if epoch % display_step==0:
print("Epoch:",'%04d' % (epoch+1),"cost=","{:.9f}".format(avg_cost))
print("Optimization Finished!")
correct_prediction=tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
#Calcuate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
print("Accuracy:",accuracy.eval({x:mnist.test.images,y:mnist.test.labels}))
#create dir for model saver
model_dir = "mnist"
model_name = "cpk"
if not os.path.exists(model_dir):
os.makedirs(model_dir)
model_saver.save(sess,os.path.join(model_dir,model_name))
print("model saved sucessfully")