<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Fast-SCNN的解釋以及使用Tensorflow 2.0的實(shí)現(xiàn)

          共 10112字,需瀏覽 21分鐘

           ·

          2022-07-22 10:30





          點(diǎn)擊上方小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時(shí)間送達(dá)


          作者:Kshitiz Rimal

          編譯:ronghuaiyang

          導(dǎo)讀

          對(duì)圖像分割方法Fast-SCNN的解釋以及實(shí)現(xiàn)的代碼分析。


          Fast Segmentation Convolutional Neural Network (Fast- scnn)是一種針對(duì)高分辨率圖像數(shù)據(jù)的實(shí)時(shí)語(yǔ)義分割模型,適用于低內(nèi)存嵌入式設(shè)備上的高效計(jì)算。原論文的作者是:Rudra PK Poudel, Stephan Liwicki and Roberto Cipolla。本文中使用的代碼并不是作者的正式實(shí)現(xiàn),而是我對(duì)論文中描述的模型的重構(gòu)的嘗試。

          隨著自動(dòng)駕駛汽車(chē)的興起,迫切需要一種能夠?qū)崟r(shí)處理輸入的模型。目前已有一些最先進(jìn)的離線語(yǔ)義分割模型,但這些模型體積大,內(nèi)存大,計(jì)算量大,F(xiàn)ast-SCNN可以解決這些問(wèn)題。

          Fast-SCNN的一些關(guān)鍵方面是:

          1. 在高分辨率圖像(1024 x 2048px)上的實(shí)時(shí)分割
          2. 得到準(zhǔn)確率為68%的平均IOU
          3. 在Cityscapes數(shù)據(jù)集上每秒處理123.5幀
          4. 不需要大量的預(yù)訓(xùn)練
          5. 結(jié)合高分辨率的空間細(xì)節(jié)和低分辨率提取的深度特征

          此外,F(xiàn)ast-SCNN使用流行的技術(shù)中最先進(jìn)的模型來(lái)保證上述性能,像用在PSPNet中的金字塔池模塊PPM,使用反向殘余瓶頸層是用于MobileNet V2中用的反向殘差Bottleneck層,以及ContextNet中的特征融合模塊等。同時(shí)利用從低分辨率數(shù)據(jù)中提取的深度特征和從高分辨率數(shù)據(jù)中提取的空間細(xì)節(jié),確保更好、更快的分割。

          現(xiàn)在讓我們開(kāi)始 Fast-SCNN的探索和實(shí)現(xiàn)。Fast-SCNN由4個(gè)主要構(gòu)件組成。它們是:

          1. 學(xué)習(xí)下采樣
          2. 全局特征提取器
          3. 特征融合
          4. 分類(lèi)器

          論文中描述的Fast-SCNN結(jié)構(gòu)

          1. 學(xué)習(xí)下采樣

          到目前為止,我們知道深度卷積神經(jīng)網(wǎng)絡(luò)的前幾層提取圖像的邊緣和角點(diǎn)等底層特征。因此,為了充分利用這一特征并使其可用于進(jìn)一步的層次,需要學(xué)習(xí)向下采樣。它是一種粗糙的全局特征提取器,可以被網(wǎng)絡(luò)中的其他模塊重用和共享。

          學(xué)習(xí)下采樣模塊使用3層來(lái)提取這些全局特征。分別是:Conv2D層,然后是2個(gè)深度可分離的卷積層。在實(shí)現(xiàn)過(guò)程中,在每個(gè)Conv2D和深度可分離的Conv層之后,使用一個(gè)Batchnorm層和Relu激活,因?yàn)橥ǔT谶@些層之后引入Batchnorm和激活是一種標(biāo)準(zhǔn)實(shí)踐。這里,所有3個(gè)層都使用2的stride和3x3的內(nèi)核大小。

          現(xiàn)在,讓我們首先實(shí)現(xiàn)這個(gè)模塊。首先,我們安裝Tensorflow 2.0。我們可以簡(jiǎn)單地使用谷歌Colab并開(kāi)始我們的實(shí)現(xiàn)。你可以簡(jiǎn)單地使用以下命令安裝:

          !pip install tensorflow-gpu==2.0.0

          這里,' -gpu '說(shuō)明我的谷歌Colab筆記本使用GPU,而在你的情況下,如果你不喜歡使用它,你可以簡(jiǎn)單地刪除' -gpu ',然后Tensorflow安裝將利用系統(tǒng)的cpu。

          然后導(dǎo)入Tensorflow:

          import tensorflow as tf

          現(xiàn)在,讓我們首先為我們的模型創(chuàng)建輸入層。在Tensorflow 2.0使用TF.Keras的高級(jí)api,我們可以這樣:

          input_layer = tf.keras.layers.Input(shape=(204810243), name = 'input_layer')

          這個(gè)輸入層是我們要構(gòu)建的模型的入口點(diǎn)。這里我們使用Tf.Keras函數(shù)的api。使用函數(shù)api而不是序列api的原因是,它提供了構(gòu)建這個(gè)特定模型所需的靈活性。

          接下來(lái),讓我們定義學(xué)習(xí)下采樣模塊的層。為此,為了使過(guò)程簡(jiǎn)單和可重用,我創(chuàng)建了一個(gè)自定義函數(shù),它將檢查我想要添加的層是一個(gè)Conv2D層還是深度可分離層,然后檢查我是否想在層的末尾添加relu。使用這個(gè)代碼塊使得卷積的實(shí)現(xiàn)在整個(gè)實(shí)現(xiàn)過(guò)程中易于理解和重用。

          def conv_block(inputs, conv_type, kernel, kernel_size, strides, padding='same', relu=True):
            
            if(conv_type == 'ds'):
              x = tf.keras.layers.SeparableConv2D(kernel, kernel_size, padding=padding, strides = strides)(inputs)
            else:
              x = tf.keras.layers.Conv2D(kernel, kernel_size, padding=padding, strides = strides)(inputs)  
            
            x = tf.keras.layers.BatchNormalization()(x)
            
            if (relu):
              x = tf.keras.activations.relu(x)
            
            return x

          在TF.Keras中,Convolutional layer定義為tf.keras.layers,深度可分離層為tf.keras.layers.SeparableConv2D。

          現(xiàn)在,讓我們通過(guò)使用適當(dāng)?shù)膮?shù)來(lái)調(diào)用自定義函數(shù)來(lái)為模塊添加層:

          lds_layer = conv_block(input_layer, 'conv'32, (33), strides = (22))
          lds_layer = conv_block(lds_layer, 'ds'48, (33), strides = (22))
          lds_layer = conv_block(lds_layer, 'ds'64, (33), strides = (22))

          2. 全局特征提取器

          這個(gè)模塊的目的是為分割捕獲全局上下文。它直接獲取從學(xué)習(xí)下采樣模塊的輸出。在這一節(jié)中,我們引入了不同的bottleneck 殘差塊,并引入了一個(gè)特殊的模塊,即金字塔池化模塊(PPM)來(lái)聚合不同的基于區(qū)域的上下文信息。

          讓我們從bottleneck 殘差塊開(kāi)始。

          論文中的Bottleneck殘差塊

          以上是本文對(duì)bottleneck殘差塊的描述。與上面類(lèi)似,現(xiàn)在讓我們使用tf.keras高級(jí)api來(lái)實(shí)現(xiàn)。

          我們首先根據(jù)上表的描述自定義一些函數(shù)。我們從殘差塊開(kāi)始,它將調(diào)用我們的自定義conv_block函數(shù)來(lái)添加Conv2D,然后添加DepthWise Conv2D層,然后point-wise卷積層,如上表所述。然后將point-wise卷積的最終輸出與原始輸入相加,使其成為殘差。

          def _res_bottleneck(inputs, filters, kernel, t, s, r=False):
              
              tchannel = tf.keras.backend.int_shape(inputs)[-1] * t

              x = conv_block(inputs, 'conv', tchannel, (11), strides=(11))

              x = tf.keras.layers.DepthwiseConv2D(kernel, strides=(s, s), depth_multiplier=1, padding='same')(x)
              x = tf.keras.layers.BatchNormalization()(x)
              x = tf.keras.activations.relu(x)

              x = conv_block(x, 'conv', filters, (11), strides=(11), padding='same', relu=False)

              if r:
                  x = tf.keras.layers.add([x, inputs])
              return x
          這里的Bottleneck殘差塊的靈感來(lái)自于在MobileNet v2中使用的實(shí)現(xiàn)

          這個(gè)bottleneck殘差塊在架構(gòu)中被多次添加,添加的次數(shù)由表中的' n '參數(shù)表示。因此,根據(jù)本文描述的架構(gòu),為了添加n次,我們引入了另一個(gè)自定義函數(shù)來(lái)完成這個(gè)任務(wù)。

          ![1_xO4huN3z718VyT6fG73PjQ](Fast-SCNN explained and implemented using Tensorflow 2.0.assets/1_xO4huN3z718VyT6fG73PjQ.png)def bottleneck_block(inputs, filters, kernel, t, strides, n):
            x = _res_bottleneck(inputs, filters, kernel, t, strides)
            
            for i in range(1, n):
              x = _res_bottleneck(x, filters, kernel, t, 1True)

            return x
          現(xiàn)在讓我們將這些bottleneck塊添加到我們的模型中。
          gfe_layer = bottleneck_block(lds_layer, 64, (33), t=6, strides=2, n=3)
          gfe_layer = bottleneck_block(gfe_layer, 96, (33), t=6, strides=2, n=3)
          gfe_layer = bottleneck_block(gfe_layer, 128, (33), t=6, strides=1, n=3)

          在這里,你會(huì)注意到這些bottleneck塊的第一個(gè)輸入來(lái)自學(xué)習(xí)下采樣模塊的輸出。這個(gè)全局特征提取器部分的最后一塊是金字塔池化模塊,簡(jiǎn)稱(chēng)PPM。

          來(lái)自PSPNet原始論文中的圖

          PPM使用上個(gè)卷積層出來(lái)的特征圖,然后應(yīng)用多個(gè)子區(qū)域平均池化和以及上采樣函數(shù)來(lái)得到不同的子區(qū)域的特征表示,然后連接在一起,這樣就帶有了本地和全局上下文的信息,可以讓圖像的分割過(guò)程更準(zhǔn)確。

          使用TF.Keras來(lái)實(shí)現(xiàn),我們使用了另外一個(gè)自定義函數(shù):

          def pyramid_pooling_block(input_tensor, bin_sizes):
            concat_list = [input_tensor]
            w = 64
            h = 32

            for bin_size in bin_sizes:
              x = tf.keras.layers.AveragePooling2D(pool_size=(w//bin_size, h//bin_size), strides=(w//bin_size, h//bin_size))(input_tensor)
              x = tf.keras.layers.Conv2D(12832, padding='same')(x)
              x = tf.keras.layers.Lambda(lambda x: tf.image.resize(x, (w,h)))(x)

              concat_list.append(x)

            return tf.keras.layers.concatenate(concat_list)

          我們添加這個(gè)PPM模塊,它將從最后一個(gè)bottleneck塊獲取輸入。

          gfe_layer = pyramid_pooling_block(gfe_layer, [2,4,6,8])

          這里的第二個(gè)參數(shù)是要提供給PPM模塊的bin的數(shù)量,這里使用的bin的數(shù)量是按照論文中描述的一樣。這些bin用于在不同的子區(qū)域進(jìn)行AveragePooling ,如上面的自定義函數(shù)所述。

          3. 特征融合

          來(lái)自Fast-SCNN原始論文

          在這個(gè)模塊中,兩個(gè)輸入相加以更好地表示分割。第一個(gè)是從學(xué)習(xí)下采樣模塊中提取的高級(jí)特征,這個(gè)學(xué)習(xí)下采樣模塊先進(jìn)行point-wise卷積,再加入到第二個(gè)輸入中。這里在point-wise卷積的最后沒(méi)有進(jìn)行激活。

          ff_layer1 = conv_block(lds_layer, 'conv'128, (1,1), padding='same', strides= (1,1), relu=False)

          第二個(gè)輸入是全局特征提取器的輸出。但在加入第二個(gè)輸入之前,它們首先進(jìn)行上采樣(4,4),然后進(jìn)行DepthWise卷積,最后是另一個(gè)point-wise卷積。在point-wise卷積輸出中不添加激活,激活是在這兩個(gè)輸入相加后引入的。

          特征融合模塊來(lái)源于原論文

          這是使用TF.Keras實(shí)現(xiàn)的低分辨率操作:

          ff_layer2 = tf.keras.layers.UpSampling2D((44))(gfe_layer)
          ff_layer2 = tf.keras.layers.DepthwiseConv2D(128, strides=(11), depth_multiplier=1, padding='same')(ff_layer2)
          ff_layer2 = tf.keras.layers.BatchNormalization()(ff_layer2)
          ff_layer2 = tf.keras.activations.relu(ff_layer2)
          ff_layer2 = tf.keras.layers.Conv2D(12811, padding='same', activation=None)(ff_layer2)

          現(xiàn)在,讓我們將這兩個(gè)輸入添加到特征融合模塊中。

          ff_final = tf.keras.layers.add([ff_layer1, ff_layer2])
          ff_final = tf.keras.layers.BatchNormalization()(ff_final)
          ff_final = tf.keras.activations.relu(ff_final)

          4. 分類(lèi)器

          在分類(lèi)器部分,引入了2個(gè)深度可分離的卷積層和1個(gè)Point-wise的卷積層。在每個(gè)層之后,還進(jìn)行了BatchNorm層和ReLU激活。

          這里需要注意的是,在原論文中,沒(méi)有提到在point-wise卷積層之后添加上采樣和Dropout層,但在本文的后面部分描述了這些層是在 point-wise卷積層之后添加的。因此,在實(shí)現(xiàn)過(guò)程中,我也按照論文的要求引入了這兩層。

          在根據(jù)最終輸出的需要進(jìn)行上采樣之后,SoftMax將作為最后一層的激活。

          classifier = tf.keras.layers.SeparableConv2D(128, (33), padding='same', strides = (11), name = 'DSConv1_classifier')(ff_final)
          classifier = tf.keras.layers.BatchNormalization()(classifier)
          classifier = tf.keras.activations.relu(classifier)

          classifier = tf.keras.layers.SeparableConv2D(128, (33), padding='same', strides = (11), name = 'DSConv2_classifier')(classifier)
          classifier = tf.keras.layers.BatchNormalization()(classifier)
          classifier = tf.keras.activations.relu(classifier)

          classifier = conv_block(classifier, 'conv'19, (11), strides=(11), padding='same', relu=True)

          classifier = tf.keras.layers.Dropout(0.3)(classifier)

          classifier = tf.keras.layers.UpSampling2D((88))(classifier)
          classifier = tf.keras.activations.softmax(classifier)

          編譯模型

          現(xiàn)在我們已經(jīng)添加了所有的層,讓我們創(chuàng)建最終的模型并編譯它。為了創(chuàng)建模型,如上所述,我們使用了來(lái)自TF.Keras的函數(shù)api。這里,模型的輸入是學(xué)習(xí)下采樣模塊中描述的初始輸入層,輸出是最終分類(lèi)器的輸出。

          fast_scnn = tf.keras.Model(inputs = input_layer , outputs = classifier, name = 'Fast_SCNN')

          現(xiàn)在,讓我們用優(yōu)化器和損失函數(shù)來(lái)編譯它。在原論文中,作者在訓(xùn)練過(guò)程中使用了動(dòng)量值為0.9,批大小為12的SGD優(yōu)化器。他們還在學(xué)習(xí)率策略中使用了多項(xiàng)式學(xué)習(xí)率,base值為0.045,power為0.9。為了簡(jiǎn)單起見(jiàn),我在這里沒(méi)有使用任何學(xué)習(xí)率策略,但如果需要,你可以自己添加。此外,在編譯模型時(shí)從ADAM optimizer開(kāi)始總是一個(gè)好主意,但是在這個(gè)CityScapes dataset的特殊情況下,作者只使用了SGD。但在一般情況下,最好從ADAM optimizer開(kāi)始,然后根據(jù)需要轉(zhuǎn)向其他不同的優(yōu)化器。對(duì)于損失函數(shù),作者使用了交叉熵?fù)p失,在實(shí)現(xiàn)過(guò)程中也使用了交叉熵?fù)p失。

          optimizer = tf.keras.optimizers.SGD(momentum=0.9, lr=0.045)
          fast_scnn.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])

          在本文中,作者使用CityScapes數(shù)據(jù)集中的19個(gè)類(lèi)別進(jìn)行訓(xùn)練和評(píng)價(jià)。通過(guò)這個(gè)實(shí)現(xiàn),你可以根據(jù)特定項(xiàng)目所需的任意數(shù)量的輸出進(jìn)行調(diào)整。

          下面是一些Fast-SCNN的驗(yàn)證結(jié)果,與輸入圖像和ground truth進(jìn)行了比較。

          來(lái)自原始論文中的圖

          好消息!

          小白學(xué)視覺(jué)知識(shí)星球

          開(kāi)始面向外開(kāi)放啦??????




          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺(jué)」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺(jué)、目標(biāo)跟蹤、生物視覺(jué)、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目52講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目,即可下載包括圖像分割、口罩檢測(cè)、車(chē)道線檢測(cè)、車(chē)輛計(jì)數(shù)、添加眼線、車(chē)牌識(shí)別、字符識(shí)別、情緒檢測(cè)、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺(jué)實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺(jué)。

          下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講,即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱(chēng)+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~


          瀏覽 20
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产人妻人伦精品1国产 | 久久色情视频 | 91成人小电影 | 黄色做爱免费 | 欧美久久性爱视频 |