當前位置:
首頁 > 最新 > CNN 入門講解:圖片在卷積神經網路中是怎麼變化的

CNN 入門講解:圖片在卷積神經網路中是怎麼變化的

微信公眾號:follow_bobo

首發於知乎:蔣竺波

這一期我們主要一邊寫代碼

一邊看圖片經過卷積層發生了什麼變化

經過採樣層發生了什麼變化

經過激活層發生了什麼變化

相當於實踐了前向傳播

走著

----------我又來當分割線了---------------------

看到代碼不要慌,很容易看懂的。

第一步:把需要的functions 全部先導進去,我們這裡主要是使用keras

import cv2

from keras import backend as K

from keras.layers import Conv2D, MaxPooling2D, BatchNormalization,Activation, Dropout, Dense,UpSampling2D,Input,add

from keras.models import Model, Sequential, load_model

import 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*255

cv2.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.12

model = 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!!!!!

全部代碼如下:https://github.com/jiangzhubo/cnn_forward_propagation-


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 隨波竺流 的精彩文章:

TAG:隨波竺流 |