日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ResNet在分别在Keras和tensorflow框架下的应用案例

發布時間:2025/3/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ResNet在分别在Keras和tensorflow框架下的应用案例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、殘差神經網絡——ResNet的綜述

深度學習網絡的深度對最后的分類和識別的效果有著很大的影響,所以正常想法就是能把網絡設計的越深越好,

但是事實上卻不是這樣,常規的網絡的堆疊(plain network)在網絡很深的時候,效果卻越來越差了。其中原因之一

即是網絡越深,梯度消失的現象就越來越明顯,網絡的訓練效果也不會很好。?但是現在淺層的網絡(shallower network)

又無法明顯提升網絡的識別效果了,所以現在要解決的問題就是怎樣在加深網絡的情況下又解決梯度消失的問題。

(二)殘差模塊——Residual bloack

?

通過在一個淺層網絡基礎上疊加 y=x 的層(稱identity mappings,恒等映射),可以讓網絡隨深度增加而不退化。

這反映了多層非線性網絡無法逼近恒等映射網絡。但是,不退化不是我們的目的,我們希望有更好性能的網絡。

?resnet學習的是殘差函數F(x) = H(x) - x, 這里如果F(x) = 0, 那么就是上面提到的恒等映射。事實上,

resnet是“shortcut connections”的在connections是在恒等映射下的特殊情況,它沒有引入額外的參數和計算復雜度。

假如優化目標函數是逼近一個恒等映射, 而不是0映射, 那么學習找到對恒等映射的擾動會比重新學習一個映射函數要容易。

殘差函數一般會有較小的響應波動,表明恒等映射是一個合理的預處理。

殘差模塊小結:

非常深的網絡很難訓練,存在梯度消失和梯度爆炸問題,學習 skip connection它可以從某一層獲得激活,然后迅速反饋給另外一層甚至更深層,利用?skip connection可以構建殘差網絡ResNet來訓練更深的網絡,ResNet網絡是由殘差模塊構建的。

上圖中,是一個兩層的神經網絡,在l層進行激活操作,得到a[l+1],再次進行激活得到a[l+2]。由下面公式:

a[l+2] 加上了 a[l]的殘差塊,即:殘差網絡中,直接將a[l]向后拷貝到神經網絡的更深層,在ReLU非線性激活前面

加上a[l],a[l]的信息直接達到網絡深層。使用殘差塊能夠訓練更深層的網絡,構建一個ResNet網絡就是通過將很多

這樣的殘差塊堆積在一起,形成一個深度神經網絡。

?

(三)殘差網絡——ResNet

上圖中是用5個殘差塊連接在一起構成的殘差網絡,用梯度下降算法訓練一個神經網絡,若沒有殘差,會發現

隨著網絡加深,訓練誤差先減少后增加,理論上訓練誤差越來越小比較好。而對于殘差網絡來講,隨著層數增加,

訓練誤差越來越減小,這種方式能夠到達網絡更深層,有助于解決梯度消失和梯度爆炸的問題,讓我們訓練更深網絡

同時又能保證良好的性能。

殘差網絡有很好表現的原因舉例:

?

假設有一個很大的神經網絡,輸入矩陣為X,輸出激活值為a[l],加入給這個網絡額外增加兩層,最終輸出結果為a[l+2],

可以把這兩層看做一個殘差模塊,在整個網絡中使用ReLU激活函數,所有的激活值都大于等于0。

對于大型的網絡,無論把殘差塊添加到神經網絡的中間還是末端,都不會影響網絡的表現。

殘差網絡起作用的主要原因是:It's so easy for these extra layers to learn the itentity function.?

這些殘差塊學習恒等函數非常容易。可以確定網絡性能不受影響,很多時候甚至可以提高學習效率。

?

模型構建好后進行實驗,在plain上觀測到明顯的退化現象,而且ResNet上不僅沒有退化,34層網絡的效果反而比18層的更好,而且不僅如此,ResNet的收斂速度比plain的要快得多。

實際中,考慮計算的成本,對殘差塊做了計算優化,即將兩個3x3的卷積層替換為1x1 + 3x3 + 1x1, 如下圖。新結構中的中間3x3的卷積層首先在一個降維1x1卷積層下減少了計算,然后在另一個1x1的卷積層下做了還原,既保持了精度又減少了計算量。

?

這相當于對于相同數量的層又減少了參數量,因此可以拓展成更深的模型。于是作者提出了50、101、152層的ResNet,而且不僅沒有出現退化問題,錯誤率也大大降低,同時計算復雜度也保持在很低的程度。

這個時候ResNet的錯誤率已經把其他網絡落下幾條街了,但是似乎還并不滿足,于是又搭建了更加變態的1202層的網絡,對于這么深的網絡,優化依然并不困難,但是出現了過擬合的問題,這是很正常的,作者也說了以后會對這個1202層的模型進行進一步的改進。

?

二、ResNet在Keras框架下的實現

(一)概況

?利用殘差神經網絡ResNet構建一個很深度的卷積神經網絡。理論上,很深的神經網絡代表著復雜的函數,實際上它們很難訓練,而ResNet比其他很深的神經網絡訓練起來更加實際可行。

1、構建基本的ResNet模塊。

2、把這些ResNet模塊集成在一起,實現和訓練一個用于圖像分類的最先進的神經網絡。

3、該ResNet網絡在深度學習框架?Keras下構建完成。

?近年來,神經網絡已變得更深,與最先進的網絡從幾層(如AlexNet)到一百層。一個非常深的網絡的主要好處是:它可以代表非常復雜的函數。它還可以從許多不同層次的抽象中學習特征,從邊緣(在較低的層)到非常復雜的特性(在更深的層次)。然而,使用更深層的網絡并不總是有用的。訓練它們巨大的障礙就是梯度消失:很深的網絡往往梯度信號變為零的速度快,從而使梯度下降法非常地慢。更特別的是,在梯度下降,當你從最后一層BackProp回到第一層,每一步乘以權重矩陣,從而梯度以指數方式迅速減為為零(或者,在罕見的情況下,成倍的增長,迅速“爆炸”為非常大的值)。

在訓練過程中,可能會看到前面層的梯度的量級或標準減小到零的速度很快,如下圖所示:

(二)、構建殘差塊

在ResNet中,"shortcut" 或 "skip connection" 使得梯度反向傳播到更前面的層:下圖中左邊的圖片展示了神經網絡的主路徑“main path”,右側的圖片為“main path”添加了一個“short cut”,通過堆疊這些ResNet模塊,可以構建很深的神經網絡。

?帶有“shortcut”的ResNet模塊,使得它對每一個模塊很容易學習到恒等函數“identy function”,這意味著你可以疊加額外ResNet模塊而對訓練集的性能產生風險小的危害。還有一些證據表明,學習恒等函數“identy function”?甚至比"skip connection" 對于梯度消失問題更有幫助,且更能說明ResNets表現出色。在ResNet中使用兩種主要類型的模塊,主要取決于輸入/輸出尺寸是相同還是不同。

1、恒等殘差塊——The identity block

?The identity block是ResNets中使用的標準塊,對應于輸入激活(例如 a [1])與輸出激活具有相同維度(例如a [l +2])。

(1)、兩層恒等殘差塊

下圖展示了ResNets的兩層的恒等殘差塊?identity block:

上面的路徑是“shortcut path”,下面的路徑是“main path”,在這個圖中,同樣也進行了CONV2D和ReLU操作,為了加速訓練的速度也加入了Batch正則化“Batch Norm”,Batch Norm在Keras框架中就一句代碼。

(2)、三層恒等殘差塊

在下面的這個例子中,將實際上實現一個略微更強大的版本,這個跳轉連接“跳過”3個隱藏層而不是2層。

(3)、下面是細節的步驟:

a、主路徑的第一部分:

第一個CONV2D的過濾器F1大小是(1*1),步長s大小為(1*1),卷積填充padding="valid"即無填充卷積。

將這一部分命名為conv_name_base+'2a',初始化時利用種子為seed=0。

第一個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'2a'.

應用ReLU激活函數,這里沒有超參數。

b、主路徑的第二部分:

第二個CONV2D的過濾器F2大小是(f*f),步長s大小為(1*1),卷積填充padding="same"即相同卷積。

將這一部分命名為conv_name_base'2b',初始化時利用種子為seed=0。

第二個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'2b'.

應用ReLU激活函數,這里沒有超參數。

c、主路徑的第三部分:

?

第三個CONV2D的過濾器F3大小是(1*1),步長s大小為(1*1),卷積填充padding="valid"即無填充卷積。

將這一部分命名為conv_name_base+'2c',初始化時利用種子為seed=0。

第三個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base +'2c'.

這一部分中沒有應用ReLU激活函數。

d、最后部分:

將shortcut和輸入一起添加到模塊中,然后再應用ReLU激活函數,這里沒有超參數。

#卷積殘差塊——convolutional_block def convolutional_block(X,f,filters,stage,block,s=2):"""param :X -- 輸入的張量,維度為(m, n_H_prev, n_W_prev, n_C_prev)f -- 整數,指定主路徑的中間 CONV 窗口的形狀(過濾器大小)filters -- python整數列表,定義主路徑的CONV層中的過濾器stage -- 整數,用于命名層,取決于它們在網絡中的位置block --字符串/字符,用于命名層,取決于它們在網絡中的位置s -- 整數,指定使用的步幅return:X -- 卷積殘差塊的輸出,維度為:(n_H, n_W, n_C)"""# 定義基本的名字conv_name_base = "res" + str(stage) + block + "_branch"bn_name_base = "bn" + str(stage) + block + "_branch"# 過濾器F1, F2, F3 = filters# 保存輸入值,后面將需要添加回主路徑X_shortcut = X# 主路徑第一部分X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding="valid",name=conv_name_base + "2a", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2a")(X)X = Activation("relu")(X)# 主路徑第二部分X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding="same",name=conv_name_base + "2b", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2b")(X)X = Activation("relu")(X)# 主路徑第三部分X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding="valid",name=conv_name_base + "2c", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2c")(X)#shortcut路徑X_shortcut = Conv2D(filters=F3,kernel_size=(1,1),strides=(s,s),padding="valid",name=conv_name_base+"1",kernel_initializer=glorot_uniform(seed=0))(X_shortcut)X_shortcut = BatchNormalization(axis=3,name=bn_name_base+"1")(X_shortcut)# 主路徑最后部分,為主路徑添加shortcut并通過relu激活X = layers.add([X, X_shortcut])X = Activation("relu")(X)return Xtf.reset_default_graph()with tf.Session() as test:np.random.seed(1)A_prev = tf.placeholder("float", [3, 4, 4, 6])X = np.random.randn(3, 4, 4, 6)A = convolutional_block(A_prev, f = 2, filters = [2, 4, 6], stage = 1, block = 'a')test.run(tf.global_variables_initializer())out = test.run([A], feed_dict={A_prev: X, K.learning_phase(): 0})print("out = " + str(out[0][1][1][0])) #運行結果: out = [0.09018463 1.2348977 0.46822017 0.0367176 0. 0.65516603]

運行結果:

out = [0.19716813 0. 1.3561227 2.1713073 0. 1.3324987 ]

2、卷積殘差塊——The convolutional block

(1)、綜述

ResNet的convolutional_block是另一種類型的殘差塊,當輸入和輸出尺寸不匹配時,可以使用這種類型的塊。

與identity block恒等殘差塊不同的地方是:在shortcut路徑中是一個CONV2D的層。

shortcut路徑中的CONV2D層用于將輸入x調整為不同的尺寸,以便在添加shortcut殘差塊的值返回到主路徑時需要最后添加的尺寸相匹配(與矩陣Ws的作用相同)。例如,要將激活值維度的高度和寬度縮小2倍,可以使用步長為2的1x1卷積。shortcut路徑上的CONV2D層路徑不使用任何非線性激活函數。 它的主要作用是只應用一個(學習的)線性函數來減小輸入的尺寸,使得尺寸匹配后面的添加步驟。

(2)、convolutional_block的細節步驟

a、主路徑第一部分

第一個CONV2D的過濾器F1大小是(1*1),步長s大小為(s*s),卷積填充padding="valid"即無填充卷積。

將這一部分命名為conv_name_base+'2a'。

第一個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'2a'.

應用ReLU激活函數,這里沒有超參數。

b、主路徑第二部分

第二個CONV2D的過濾器F2大小是(f*f),步長s大小為(1*1),卷積填充padding="same"即相同卷積。

將這一部分命名為conv_name_base+'2b',初始化時利用種子為seed=0。

第二個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'2b'.

?應用ReLU激活函數,這里沒有超參數。

c、主路徑第三部分

第三個CONV2D的過濾器 F3大小是(1*1),步長s大小為(1*1),卷積填充padding="valid"即無填充卷積。

將這一部分命名為 conv_name_base+'2c',初始化時利用種子為seed=0。

第三個BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'2c'.

這一部分中沒有應用ReLU激活函數。

d、shortcut 路徑

該部分CONV2D的過濾器 F3大小是(1*1),步長s大小為(s*s),卷積填充 padding="valid"即無填充卷積。

將這一部分命名為conv_name_base+'1'。

該部分BatchNorm是在通道/厚度的軸上進行標準化,并命名為bn_name_base+'1'?

e、最后部分

將shortcut和輸入一起添加到模塊中,然后再應用ReLU激活函數,這里沒有超參數。

#卷積殘差塊——convolutional_blockdef convolutional_block(X,f,filters,stage,block,s=2):"""param :X -- 輸入的張量,維度為(m, n_H_prev, n_W_prev, n_C_prev)f -- 整數,指定主路徑的中間 CONV 窗口的形狀(過濾器大小)filters -- python整數列表,定義主路徑的CONV層中的過濾器stage -- 整數,用于命名層,取決于它們在網絡中的位置block --字符串/字符,用于命名層,取決于它們在網絡中的位置s -- 整數,指定使用的步幅return:X -- 卷積殘差塊的輸出,維度為:(n_H, n_W, n_C)"""# 定義基本的名字conv_name_base = "res" + str(stage) + block + "_branch"bn_name_base = "bn" + str(stage) + block + "_branch"# 過濾器F1, F2, F3 = filters# 保存輸入值,后面將需要添加回主路徑X_shortcut = X# 主路徑第一部分X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding="valid",name=conv_name_base + "2a", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2a")(X)X = Activation("relu")(X)# 主路徑第二部分X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding="same",name=conv_name_base + "2b", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2b")(X)X = Activation("relu")(X)# 主路徑第三部分X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding="valid",name=conv_name_base + "2c", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2c")(X)#shortcut路徑X_shortcut = Conv2D(filters=F3,kernel_size=(1,1),strides=(s,s),padding="valid",name=conv_name_base+"1",kernel_initializer=glorot_uniform(seed=0))(X_shortcut)X_shortcut = BatchNormalization(axis=3,name=bn_name_base+"1")(X_shortcut)# 主路徑最后部分,為主路徑添加shortcut并通過relu激活X = layers.add([X, X_shortcut])X = Activation("relu")(X)return Xtf.reset_default_graph()with tf.Session() as test:np.random.seed(1)A_prev = tf.placeholder("float", [3, 4, 4, 6])X = np.random.randn(3, 4, 4, 6)A = convolutional_block(A_prev, f = 2, filters = [2, 4, 6], stage = 1, block = 'a')test.run(tf.global_variables_initializer())out = test.run([A], feed_dict={A_prev: X, K.learning_phase(): 0})print("out = " + str(out[0][1][1][0]))

運行結果:

out = [0.09018463 1.2348977 0.46822017 0.0367176 0. 0.65516603]

三、在Keras框架下構建50層的殘差卷積神經網絡ResNet

?


50層的殘差卷積神經網絡ResNet的細節部分:

0、為輸入224*224*3填充大小為(3*3)的zero_padding。

1、第一階段,輸出大小為:56*56*64

2、第二階段,輸出大小為:56*56*256

3、第三階段,輸出大小為:28*28*512

4、第四階段,輸出大小為:14*14*1024

?5、第五階段,輸出大小為:7*7*2048

6、最后階段,輸出6個類別

注意:

(1)正如在Keras教程中所看到的,在事先訓練模型之前,需要通過編譯模型來配置學習過程。

(2)模型訓練20次epches,批樣本數目batch_size = 32,在單個CPU上運行大概每個epoch需5分鐘。

(3)當訓練足夠數量的迭代時,ResNet50是一個強大的圖像分類模型。

#!/usr/bin/env python # -*- coding:utf-8 -*-#構建50層的ResNet神經網絡實現圖像的分類 #深度學習框架 Keras中實現import numpy as np import tensorflow as tf from keras import layers from keras.layers import Input,Add,Dense,Activation,ZeroPadding2D,\BatchNormalization,Flatten,Conv2D,AveragePooling2D,MaxPooling2D,GlobalMaxPooling2D from keras.models import Model,load_model from keras.preprocessing import image from keras.utils import layer_utils from keras.utils.data_utils import get_file from keras.applications.imagenet_utils import preprocess_input from keras.utils.vis_utils import model_to_dot from keras.utils import plot_model from keras.initializers import glorot_uniform import pydoc from IPython.display import SVG from resnets_utils import * import scipy.misc from matplotlib.pyplot import imshowimport keras.backend as K K.set_image_data_format("channels_last") K.set_learning_phase(1)#恒等模塊——identity_block def identity_block(X,f,filters,stage,block):"""三層的恒等殘差塊param :X -- 輸入的張量,維度為(m, n_H_prev, n_W_prev, n_C_prev)f -- 整數,指定主路徑的中間 CONV 窗口的形狀filters -- python整數列表,定義主路徑的CONV層中的過濾器數目stage -- 整數,用于命名層,取決于它們在網絡中的位置block --字符串/字符,用于命名層,取決于它們在網絡中的位置return:X -- 三層的恒等殘差塊的輸出,維度為:(n_H, n_W, n_C)"""#定義基本的名字conv_name_base = "res"+str(stage)+block+"_branch"bn_name_base = "bn"+str(stage)+block+"_branch"#過濾器F1,F2,F3 = filters#保存輸入值,后面將需要添加回主路徑X_shortcut = X#主路徑第一部分X = Conv2D(filters=F1,kernel_size=(1,1),strides=(1,1),padding="valid",name=conv_name_base+"2a",kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3,name=bn_name_base+"2a")(X)X = Activation("relu")(X)# 主路徑第二部分X = Conv2D(filters=F2,kernel_size=(f,f),strides=(1,1),padding="same",name=conv_name_base+"2b",kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3,name=bn_name_base+"2b")(X)X = Activation("relu")(X)# 主路徑第三部分X = Conv2D(filters=F3,kernel_size=(1,1),strides=(1,1),padding="valid",name=conv_name_base+"2c",kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3,name=bn_name_base+"2c")(X)# 主路徑最后部分,為主路徑添加shortcut并通過relu激活X = layers.add([X,X_shortcut])X = Activation("relu")(X)return Xtf.reset_default_graph() with tf.Session() as sess:np.random.seed(1)A_prev = tf.placeholder("float",shape=[3,4,4,6])X = np.random.randn(3,4,4,6)A = identity_block(A_prev,f=2,filters=[2,4,6],stage=1,block="a")sess.run(tf.global_variables_initializer())out = sess.run([A],feed_dict={A_prev:X,K.learning_phase():0})print("out = "+str(out[0][1][1][0]))#卷積殘差塊——convolutional_block def convolutional_block(X,f,filters,stage,block,s=2):"""param :X -- 輸入的張量,維度為(m, n_H_prev, n_W_prev, n_C_prev)f -- 整數,指定主路徑的中間 CONV 窗口的形狀(過濾器大小,ResNet中f=3)filters -- python整數列表,定義主路徑的CONV層中過濾器的數目stage -- 整數,用于命名層,取決于它們在網絡中的位置block --字符串/字符,用于命名層,取決于它們在網絡中的位置s -- 整數,指定使用的步幅return:X -- 卷積殘差塊的輸出,維度為:(n_H, n_W, n_C)"""# 定義基本的名字conv_name_base = "res" + str(stage) + block + "_branch"bn_name_base = "bn" + str(stage) + block + "_branch"# 過濾器F1, F2, F3 = filters# 保存輸入值,后面將需要添加回主路徑X_shortcut = X# 主路徑第一部分X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding="valid",name=conv_name_base + "2a", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2a")(X)X = Activation("relu")(X)# 主路徑第二部分X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding="same",name=conv_name_base + "2b", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2b")(X)X = Activation("relu")(X)# 主路徑第三部分X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding="valid",name=conv_name_base + "2c", kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3, name=bn_name_base + "2c")(X)#shortcut路徑X_shortcut = Conv2D(filters=F3,kernel_size=(1,1),strides=(s,s),padding="valid",name=conv_name_base+"1",kernel_initializer=glorot_uniform(seed=0))(X_shortcut)X_shortcut = BatchNormalization(axis=3,name=bn_name_base+"1")(X_shortcut)# 主路徑最后部分,為主路徑添加shortcut并通過relu激活X = layers.add([X, X_shortcut])X = Activation("relu")(X)return Xtf.reset_default_graph()with tf.Session() as test:np.random.seed(1)A_prev = tf.placeholder("float", [3, 4, 4, 6])X = np.random.randn(3, 4, 4, 6)A = convolutional_block(A_prev, f = 2, filters = [2, 4, 6], stage = 1, block = 'a')test.run(tf.global_variables_initializer())out = test.run([A], feed_dict={A_prev: X, K.learning_phase(): 0})print("out = " + str(out[0][1][1][0]))#50層ResNet模型構建 def ResNet50(input_shape = (64,64,3),classes = 6):"""構建50層的ResNet,結構為:CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3-> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYERparam :input_shape -- 數據集圖片的維度classes -- 整數,分類的數目return:model -- Keras中的模型實例"""#將輸入定義為維度大小為 input_shape的張量X_input = Input(input_shape)# Zero-PaddingX = ZeroPadding2D((3,3))(X_input)# Stage 1X = Conv2D(64,kernel_size=(7,7),strides=(2,2),name="conv1",kernel_initializer=glorot_uniform(seed=0))(X)X = BatchNormalization(axis=3,name="bn_conv1")(X)X = Activation("relu")(X)X = MaxPooling2D(pool_size=(3,3),strides=(2,2))(X)# Stage 2X = convolutional_block(X,f=3,filters=[64,64,256],stage=2,block="a",s=1)X = identity_block(X,f=3,filters=[64,64,256],stage=2,block="b")X = identity_block(X,f=3,filters=[64,64,256],stage=2,block="c")#Stage 3X = convolutional_block(X,f=3,filters=[128,128,512],stage=3,block="a",s=2)X = identity_block(X,f=3,filters=[128,128,512],stage=3,block="b")X = identity_block(X,f=3,filters=[128,128,512],stage=3,block="c")X = identity_block(X,f=3,filters=[128,128,512],stage=3,block="d")# Stage 4X = convolutional_block(X,f=3,filters=[256,256,1024],stage=4,block="a",s=2)X = identity_block(X,f=3,filters=[256,256,1024],stage=4,block="b")X = identity_block(X,f=3,filters=[256,256,1024],stage=4,block="c")X = identity_block(X,f=3,filters=[256,256,1024],stage=4,block="d")X = identity_block(X,f=3,filters=[256,256,1024],stage=4,block="e")X = identity_block(X,f=3,filters=[256,256,1024],stage=4,block="f")#Stage 5X = convolutional_block(X,f=3,filters=[512,512,2048],stage=5,block="a",s=2)X = identity_block(X,f=3,filters=[256,256,2048],stage=5,block="b")X = identity_block(X,f=3,filters=[256,256,2048],stage=5,block="c")#最后階段#平均池化X = AveragePooling2D(pool_size=(2,2))(X)#輸出層X = Flatten()(X) #展平X = Dense(classes,activation="softmax",name="fc"+str(classes),kernel_initializer=glorot_uniform(seed=0))(X)#創建模型model = Model(inputs=X_input,outputs=X,name="ResNet50")return model#運行構建的模型圖 model = ResNet50(input_shape=(64,64,3),classes=6)#編譯模型來配置學習過程 model.compile(optimizer="adam",loss="categorical_crossentropy",metrics=["accuracy"])#加載數據集 X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()# Normalize image vectors X_train = X_train_orig/255. X_test = X_test_orig/255.# Convert training and test labels to one hot matrices Y_train = convert_to_one_hot(Y_train_orig, 6).T Y_test = convert_to_one_hot(Y_test_orig, 6).Tprint ("number of training examples = " + str(X_train.shape[0])) print ("number of test examples = " + str(X_test.shape[0])) print ("X_train shape: " + str(X_train.shape)) print ("Y_train shape: " + str(Y_train.shape)) print ("X_test shape: " + str(X_test.shape)) print ("Y_test shape: " + str(Y_test.shape))#訓練模型 model.fit(X_train,Y_train,epochs=20,batch_size=32)#測試集性能測試 preds = model.evaluate(X_test,Y_test) print("Loss = "+str(preds[0])) print("Test Accuracy ="+str(preds[1]))

四、在tensorflow框架下構建殘差卷積神經網絡ResNet V2

?ResNet V2中的殘差學習單元為 bottleneck,與ResNet V1的主要區別在于:

1、在每一層前都使用了Batch Normalization;2、對輸入進行preactivation,而不是在卷積進行激活函數處理。

(一)基礎知識應用

1、Python內建的集合模塊——collections

--------------------- 作者:loveliuzz 來源:CSDN 原文:https://blog.csdn.net/loveliuzz/article/details/79117397?utm_source=copy 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的ResNet在分别在Keras和tensorflow框架下的应用案例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。