您的位置:首页 > 理论基础 > 计算机网络

CNN 入门讲解:图片在卷积神经网络中是怎么变化的(前向传播)

2018-03-05 12:59 507 查看

CNN 入门讲解:图片在卷积神经网络中是怎么变化的(前向传播)

微信公众号:follow_bobo知乎:蒋竺波首发于卷积神经网络(CNN)入门讲解​zhuanlan.zhihu.com


为了看懂这一期,请你先看:CNN入门讲解:如何理解卷积神经网络的结构
蒋竺波:CNN入门讲解:如何理解卷积神经网络的结构​zhuanlan.zhihu.com

CNN入门讲解:什么是卷积
蒋竺波:CNN 入门讲解:什么是卷积​zhuanlan.zhihu.com

CNN入门讲解:卷积层是如何提取特征
蒋竺波:CNN入门讲解:卷积层是如何提取特征的?​zhuanlan.zhihu.com

CNN入门讲解:什么是采样层(pooling)
蒋竺波:CNN入门讲解:什么是采样层(pooling)​zhuanlan.zhihu.com

CNN入门讲解:什么是激活函数(Activation Function)
蒋竺波:CNN入门讲解:什么是激活函数(Activation Function)​zhuanlan.zhihu.com

CNN入门讲解:什么是全连接层(04/03/2018有更新)
蒋竺波:CNN 入门讲解:什么是全连接层​zhuanlan.zhihu.com


这一期我们主要一边写代码一边看图片经过卷积层发生了什么变化经过采样层发生了什么变化经过激活层发生了什么变化相当于实践了前向传播走着
----------我又来当分割线了---------------------看到代码不要慌,很容易看懂的。第一步:把需要的functions 全部先导进去,我们这里主要是使用kerasimport cv2from keras import backend as Kfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization,Activation, Dropout, Dense,UpSampling2D,Input,addfrom keras.models import Model, Sequential, load_modelimport numpy as np------------------------------------------------------------------------------------------我们今天的网络结构如下,没有经过训练的:model = Sequential()model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_1'))#加入一个卷积层,filter数量为3,卷积核size为(3,3)model.add(MaxPooling2D(pool_size=(3,3)))#加入一个pooling 层,size为(3,3)model.add(Activation('relu'))# 加入激活函数'ReLu', 只保留大于0 的值model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Activation('relu'))model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_3'))model.add(Activation('relu'))model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_4'))model.add(Activation('relu'))model.add(Flatten())#把上层输出平铺model.add(Dense(8, activation='relu',name='dens_1'))#加入全连接层,分为8类-----------------------------------------------------------------------------------------------因为conv2d这个function 对于权值是随机初始化的每运行一次程序权值就变了,权值变了就没有比较意义了,而我们不用pretrained model,所以我们要保存第一次初始化的权值-----------------------------------------------------------------------------------------------model.save_weights('girl.h5')
第二步:我们先来看看我们的输入数据:girl = cv2.imread(‘girl.jpg’)

girl.jpg shape= (575,607)

第三步:搭建一个卷积层girl = cv2.imread('girl.jpg')model = Sequential()model.add(Conv2D(3,3,3,input_shape= girl.shape ,name='conv_1')) # filter =3, kernel_size =(3,3)model.load_weights('girl.h5', by_name=True) # ‘by_name’表示只给和保存模型相同卷积层名字的卷积层导入权值,这里就是把上一步‘conv_1’的权值导入这一步‘conv_1’,当然结构得相同
第四步:数据增维
由于keras 只能按批处理数据,因此需要把单个数据提高一个维度
girl_batch = np.expand_dims(girl,axis=0)#数据维度由(575,607,3)变为(1,575,607,3)
第五步:查看卷积层输出---特征图conv_girl = model.predict(girl_batch)
girl_img = np.squeeze(conv_girl,axis=0)#把图像的像素值大小rescale 到0-255之间max_img = np.max(img)min_img = np.min(img)img = img-(min_img)img=img/(max_img - min_img)img = img*255cv2.imwrite('conv1_output.jpg',girl_img)


conv_1,filter=3,kernel =3x3 ,shape = (573,605)可以看到图像的一些纹理,边缘,或者颜色信息被一定程度上提取出来了,shape也发生了变化
第七步:加入pooling 层model = Sequential()model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_1'))model.add(MaxPooling2D(pool_size=(2,2)))


conv_1, filter=3,kernel =3x3,pool=(3,3) shape=(191,201)从上图可以明显的看到特征更加明显,并且shape减为三分之一了
第八步 加入激活函数'ReLu'model = Sequential()model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_1'))model.add(MaxPooling2D(pool_size=(3,3)))model.add(Activation('relu'))# 只保留大于0 的值


ReLu

conv_1, filter=3, kernel =3x3, pool=(2,2), activation ='ReLu', shape=(191,201)可以看到只有一些边缘的特征被保留下来了
第九步 在原来的基础上加入新的卷积层model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))


conv_2, filter=3,kernel =3x3,shape=(189,199)纹理的信息更明显了
第九步 在原来的基础上加入新的采样层model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))model.add(MaxPooling2D(pool_size=(2,2)))


conv_2, filter=3,kernel =3x3,pool=(2,2),shape=(94,99)

第十步:在原来的基础上加入新的激活函数'ReLu’model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Activation('relu')


conv_2, filter=3, kernel =3x3, pool=(2,2), activation =‘relu', shape=(94,99)
番外步:把原来激活函数'relu', 全部改为‘sigmoid’model = Sequential()model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_1'))model.add(MaxPooling2D(pool_size=(3,3)))model.add(Activation('sigmoid'))model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Activation('sigmoid'))

Sigmoid


conv_2, filter=3, kernel =3x3, pool=(2,2), activation =‘sigmoid', shape=(94,99)番外步:把原来激活函数'Relu',全部改为'tanh’model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_2'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Activation('tanh'))


tanh


conv_2, filter=3, kernel =3x3, pool=(2,2), activation = 'tanh', shape=(94,99)
第十一步 增加两个卷积层和激活函数‘relu’model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_3'))model.add(Activation('relu'))model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_4'))model.add(Activation('relu'))


conv_4, filter=3, kernel =3x3, activation = 'relu', shape=(90,95)第十一步 全连接层输出model.add(Conv2D(3,3,3,input_shape= girl.shape,name='conv_4'))model.add(Activation('relu'))model.add(Flatten())model.add(Dense(8, activation='relu',name='dens_1'))#分为8类


dens_1, classes = 8 ,shape = (1,8)
番外篇:不同kernel size 之间的对比这里只用一个卷积层做测试,为了方便比较,所有的weights 值都设为0.12model = Sequential()model.add(Conv2D(filter1,ke_width,ke_height,kernel_initializer = keras.initializers.Constant(value=0.12),input_shape= girl.shape,name='conv_1'))


conv_1, filter=3, kernel =3x3, shape=(573,605)

conv_1, filter=3, kernel =12x12, shape=(564,596)


conv_1, filter=3, kernel =24x24, shape=(552,584)
摆代码什么的最轻松了,嘿嘿嘿喜欢的朋友点个赞再走啊你的赞是我写下去的动力!!!Come on!!!!!全部代码如下:jiangzhubo/cnn_forward_propagation-​github.com

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  深度学习