Keras【Deep Learning With Python】更优模型探索Keras实现CNN

廉价感情. 提交于 2020-02-26 10:07:09

CNN

1.CNN介绍

CNN是应用在图像识别领域较多的一种机器学习算法,它与普通的神经网络有点类似,通过输入层然后乘以权重加上偏置,并且通过一个非线性的激活函数,即可得到输出值。CNN要做的是给定一幅图,对该图像进行编码最终即可将该图进行分类,而此过程中参数相比普通神经网络的参数要少,并且更加高效。

CNN通常由三个部分组成,分别是Conv layer、Pooling layer、Full-connected layer,它们组成了一个完整的CNN结构。通常输入是一幅图片,whc,分别为图像的宽度高度以及频道数目(RGB),conv layer将计算输入层与权重矩阵的卷积,然后将该结果通过ReLU函数,Pooling layer用于对卷积后的矩阵进行抽样降维,例如按22矩形大小对原卷积矩阵分成若干个22大小的块,然后对于每个块只取其中的最大值,这样就可以使得维度降低为原来的1/4,而这就是max pooling方法,该方法的优点是减少了计算过程中参数的个数以及防止过拟合的产生。最后,经过的是MLP,方法类似,可以参考以前的博文(逻辑回归及感知器)。

总结一下,CNN就是将一幅图像经过一层又一层的编码过后,可以得到一个结论值,该值是对该图像的分类或描述。

2.CNN基本原理

当输入数据的维度很大时,如图像,就不能简单地每个输入值连接一个神经元,这时候每一个神经元要负责一片感知场,例如若输入数据为32323,而感知场的个数为55,则此时conv layer的权重为55*3,因此共有75个权重。这样就可以有效减少参数的数目。

一般情况下,CNN的结构形式是:输入层—>Conv层—>Pooling层—>(重复Conv、Pooling层)…—>FC层—>输出结果。具体说来,通常还有以下几种形式:

Input--->((Conv--->ReLU--->Conv--->ReLU)--->Pooling)*3--->(FC--->ReLU)*2--->Output

Input--->(Conv--->ReLU--->Pooling)*2--->FC--->ReLU--->Output

通常输入层大小一般为2的整数倍,如32,64,96,224,384等。

通常卷积层使用较小的filter,如33,最多也就55,并且使用stride=1(stride表示卷积时对input进行每次移动一步,上下左右都是),并且对原来的input进行padding(使用0元素填充)。

Pooling层用于对卷积结果进行降低维度,例如选择22的区域对卷积层进行降低维度,则选择22区域的最大值作为输出,这样卷积层的维度就降为之前一半。

卷积层和Pooling层是CNN的核心所在,下图显示了CNN的结构图:
在这里插入图片描述
较低层是用来卷积以及抽样的,较高的层用来进行逻辑回归。

代码实现

import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Convolution2D,MaxPooling2D,Flatten
from keras.optimizers import Adam
 
# 载入数据
(x_train,y_train),(x_test,y_test) = mnist.load_data()
 
# (60000,28,28)->(60000,28,28,1)
x_train = x_train.reshape(-1,28,28,1)/255.0
x_test = x_test.reshape(-1,28,28,1)/255.0
# 换one hot格式
y_train = np_utils.to_categorical(y_train,num_classes=10)
y_test = np_utils.to_categorical(y_test,num_classes=10)
 
# 定义顺序模型
model = Sequential()
 
# 第一个卷积层
# input_shape 输入平面
# filters 卷积核/滤波器个数
# kernel_size 卷积窗口大小
# strides 步长
# padding padding方式 same/valid
# activation 激活函数
model.add(Convolution2D(
    input_shape = (28,28,1),
    filters = 32,
    kernel_size = 5,
    strides = 1,
    padding = 'same',
    activation = 'relu'
))
# 第一个池化层
model.add(MaxPooling2D(
    pool_size = 2,
    strides = 2,
    padding = 'same',
))
 
# 第二个卷积层
model.add(Convolution2D(64,5,strides=1,padding='same',activation = 'relu'))
# 第二个池化层
model.add(MaxPooling2D(2,2,'same'))
# 把第二个池化层的输出扁平化为1维
model.add(Flatten())
 
# 第一个全连接层
model.add(Dense(1024,activation = 'relu'))
# Dropout
model.add(Dropout(0.5))
# 第二个全连接层
model.add(Dense(10,activation='softmax'))
 
# 定义优化器
adam = Adam(lr=1e-4)
# 定义优化器,loss function,训练过程中计算准确率
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])
 
# 训练模型
model.fit(x_train,y_train,batch_size=64,epochs=10)
 
# 评估模型
loss,accuracy = model.evaluate(x_test,y_test)
 
print('test loss',loss)
print('test accuracy',accuracy)

在这里插入图片描述

手写数字复杂网络层抽特征可视化工具http://scs.ryerson.ca/~aharley/vis/conv/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!