計(jì)算機(jī)視覺的自動(dòng)編碼器有無限可能
介紹
大家好,在過去的幾個(gè)月中,我致力于計(jì)算機(jī)視覺自動(dòng)編碼器 的開發(fā),坦白地說,我對(duì)使用它們可以構(gòu)建的大量應(yīng)用程序印象深刻。本文的目的是解釋自動(dòng)編碼器,可以使用自動(dòng)編碼器構(gòu)建的一些應(yīng)用程序,未連接的編碼器-解碼器層的缺點(diǎn)以及諸如U-Net之類的體系結(jié)構(gòu)如何幫助提高自動(dòng)編碼器的質(zhì)量。
1. 什么是自動(dòng)編碼器?
簡單來說,自動(dòng)編碼器是一種順序神經(jīng)網(wǎng)絡(luò),由兩個(gè)組件組成,一個(gè)是編碼器,另一個(gè)是**解碼器。**供我們參考,假設(shè)我們正在處理圖像,**編碼器的工作是從圖像中提取特征,從而減小圖像的高度和寬度,但同時(shí)增加其深度,**即編碼器對(duì)圖像進(jìn)行了潛在表示,F(xiàn)在,解碼器的工作是解碼潛在表示并形成滿足我們給定標(biāo)準(zhǔn)的圖像。從下面的圖像中可以很容易理解。
圖1:自動(dòng)編碼器架構(gòu)自動(dòng)編碼器的輸入和輸出都是圖像,在下面給出的示例中,自動(dòng)編碼器將輸入轉(zhuǎn)換為Monet樣式的繪畫。
圖2:自動(dòng)編碼器的輸入和輸出
2. 自動(dòng)編碼器,用于語義分割和未連接的編碼器-解碼器層的缺點(diǎn)語義分割
是指為圖像的每個(gè)像素分配標(biāo)簽,從而將屬于同一對(duì)象的像素分組在一起,以下圖像將幫助你更好地理解這一點(diǎn)。
圖3:圖像及其語義分割輸出
以下代碼定義了用于此應(yīng)用程序的自動(dòng)編碼器體系結(jié)構(gòu):
myTransformer = tf.keras.models.Sequential([
## defining encoder
tf.keras.layers.Input(shape= (256, 256, 3)),
tf.keras.layers.Conv2D(filters = 16, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.MaxPool2D(pool_size = (2, 2)),
tf.keras.layers.Conv2D(filters = 32, kernel_size = (3,3), strides = (2,2), activation = 'relu',padding = 'valid'),
tf.keras.layers.Conv2D(filters = 64, kernel_size = (3,3), strides = (2,2), activation = 'relu',padding = 'same'),
tf.keras.layers.MaxPool2D(pool_size = (2, 2)),
tf.keras.layers.Conv2D(filters = 64, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 256, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 512, kernel_size = (3,3), activation = 'relu', padding = 'same'),
## defining decoder path
tf.keras.layers.UpSampling2D(size = (2,2)),
tf.keras.layers.Conv2D(filters = 256, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.UpSampling2D(size = (2,2)),
tf.keras.layers.Conv2D(filters = 64, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.UpSampling2D(size = (2,2)),
tf.keras.layers.Conv2D(filters = 32, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.UpSampling2D(size = (2,2)),
tf.keras.layers.Conv2D(filters = 16, kernel_size = (3,3), activation = 'relu', padding = 'same'),
tf.keras.layers.Conv2D(filters = 3, kernel_size = (3,3), activation = 'relu', padding = 'same'),
])
請(qǐng)參考本文的參考部分以獲取完整的訓(xùn)練渠道。以下是你使用此網(wǎng)絡(luò)可獲得的結(jié)果
圖4:用于語義分割的自動(dòng)編碼器結(jié)果
很好,看來我們的自動(dòng)編碼器可以很好地解決此問題,但是,你是否覺得所獲得的結(jié)果有點(diǎn)模糊,可能出了什么問題?
2.1 自動(dòng)編碼器中未連接的編碼器-解碼器層的缺點(diǎn)
這種模糊性的原因在于**,**即使我們可以實(shí)現(xiàn)目標(biāo),但輸出質(zhì)量還不夠好。因此,當(dāng)信息從編碼器傳遞到解碼器時(shí),功能映射就會(huì)丟失。因此,最合乎邏輯的方法是將解碼器層與編碼器層中的對(duì)應(yīng)層連接起來,從而補(bǔ)償重建圖像時(shí)丟失的特征,這就是像U-Net這樣的體系結(jié)構(gòu)。從下圖可以更好地理解這一點(diǎn):
圖5:Unet體系結(jié)構(gòu)
看一下解碼器和編碼器層之間的互連,它們使像U-Net這樣的體系結(jié)構(gòu)優(yōu)于原始自動(dòng)編碼器。如此說來,讓我們討論一些可以使用UNet構(gòu)建的實(shí)際應(yīng)用程序。
3. 自動(dòng)編碼器的一些實(shí)際應(yīng)用
3.1 通過預(yù)測相關(guān)掩碼進(jìn)行圖像分割
這是你遇到的另一個(gè)分割問題,與上述示例不同。給定一幅圖像,將要求你為圖像中的目標(biāo)物體預(yù)測一個(gè)二進(jìn)制掩碼,當(dāng)你將此預(yù)測掩碼與給定圖像相乘時(shí),你將獲得目標(biāo)圖像。此類預(yù)測模型可用于查找腎臟中癌細(xì)胞或結(jié)石的位置。因?yàn)橐粡垐D片的價(jià)值勝過千言萬語,這里有一張圖片可以說明我所說的:
圖6:實(shí)際的分割
這是定義所用模型架構(gòu)的代碼。
# defining Conv2d block for our u-net
# this block essentially performs 2 convolution
def Conv2dBlock(inputTensor, numFilters, kernelSize = 3, doBatchNorm = True):
#first Conv
x = tf.keras.layers.Conv2D(filters = numFilters, kernel_size = (kernelSize, kernelSize),
kernel_initializer = 'he_normal', padding = 'same') (inputTensor)
if doBatchNorm:
x = tf.keras.layers.BatchNormalization()(x)
x =tf.keras.layers.Activation('relu')(x)
#Second Conv
x = tf.keras.layers.Conv2D(filters = numFilters, kernel_size = (kernelSize, kernelSize),
kernel_initializer = 'he_normal', padding = 'same') (x)
if doBatchNorm:
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Activation('relu')(x)
return x
# Now defining Unet
def GiveMeUnet(inputImage, numFilters = 16, droupouts = 0.1, doBatchNorm = True):
# defining encoder Path
c1 = Conv2dBlock(inputImage, numFilters * 1, kernelSize = 3, doBatchNorm = doBatchNorm)
p1 = tf.keras.layers.MaxPooling2D((2,2))(c1)
p1 = tf.keras.layers.Dropout(droupouts)(p1)
c2 = Conv2dBlock(p1, numFilters * 2, kernelSize = 3, doBatchNorm = doBatchNorm)
p2 = tf.keras.layers.MaxPooling2D((2,2))(c2)
p2 = tf.keras.layers.Dropout(droupouts)(p2)
c3 = Conv2dBlock(p2, numFilters * 4, kernelSize = 3, doBatchNorm = doBatchNorm)
p3 = tf.keras.layers.MaxPooling2D((2,2))(c3)
p3 = tf.keras.layers.Dropout(droupouts)(p3)
c4 = Conv2dBlock(p3, numFilters * 8, kernelSize = 3, doBatchNorm = doBatchNorm)
p4 = tf.keras.layers.MaxPooling2D((2,2))(c4)
p4 = tf.keras.layers.Dropout(droupouts)(p4)
c5 = Conv2dBlock(p4, numFilters * 16, kernelSize = 3, doBatchNorm = doBatchNorm)
# defining decoder path
u6 = tf.keras.layers.Conv2DTranspose(numFilters*8, (3, 3), strides = (2, 2), padding = 'same')(c5)
u6 = tf.keras.layers.concatenate([u6, c4])
u6 = tf.keras.layers.Dropout(droupouts)(u6)
c6 = Conv2dBlock(u6, numFilters * 8, kernelSize = 3, doBatchNorm = doBatchNorm)
u7 = tf.keras.layers.Conv2DTranspose(numFilters*4, (3, 3), strides = (2, 2), padding = 'same')(c6)
u7 = tf.keras.layers.concatenate([u7, c3])
u7 = tf.keras.layers.Dropout(droupouts)(u7)
c7 = Conv2dBlock(u7, numFilters * 4, kernelSize = 3, doBatchNorm = doBatchNorm)
u8 = tf.keras.layers.Conv2DTranspose(numFilters*2, (3, 3), strides = (2, 2), padding = 'same')(c7)
u8 = tf.keras.layers.concatenate([u8, c2])
u8 = tf.keras.layers.Dropout(droupouts)(u8)
c8 = Conv2dBlock(u8, numFilters * 2, kernelSize = 3, doBatchNorm = doBatchNorm)
u9 = tf.keras.layers.Conv2DTranspose(numFilters*1, (3, 3), strides = (2, 2), padding = 'same')(c8)
u9 = tf.keras.layers.concatenate([u9, c1])
u9 = tf.keras.layers.Dropout(droupouts)(u9)
c9 = Conv2dBlock(u9, numFilters * 1, kernelSize = 3, doBatchNorm = doBatchNorm)
output = tf.keras.layers.Conv2D(1, (1, 1), activation = 'sigmoid')(c9)
model = tf.keras.Model(inputs = [inputImage], outputs = [output])
return model
請(qǐng)參考本文的參考部分以了解整個(gè)訓(xùn)練流程。
3.2 根據(jù)衛(wèi)星圖像預(yù)測路線圖
你可以將上述架構(gòu)應(yīng)用于在衛(wèi)星圖像中查找道路,因?yàn)槿绻阆氲竭@一點(diǎn),那么這又是一個(gè)分割問題,使用適當(dāng)?shù)臄?shù)據(jù)集就可以輕松實(shí)現(xiàn)此任務(wù)。與往常一樣,這是一個(gè)顯示此概念的圖像。
圖7:根據(jù)航拍圖像預(yù)測路線
與往常一樣,你可以在“參考”部分中找到代碼。
3.3 使用自動(dòng)編碼器實(shí)現(xiàn)超分辨率
你是否曾在放大低分辨率圖像時(shí)注意到發(fā)生的像素失真?超分辨率本質(zhì)上是指提高低分辨率圖像的分辨率,F(xiàn)在,也可以僅通過對(duì)圖像進(jìn)行上采樣并使用雙線性插值法來填充新的像素值來實(shí)現(xiàn)此目的,但是由于你無法增加圖像中的信息量,因此生成的圖像將變得模糊。為了解決這個(gè)問題,我們教了一個(gè)神經(jīng)網(wǎng)絡(luò)來預(yù)測高分辨率圖像的像素值(**本質(zhì)上是增加信息)。**你可以使用自動(dòng)編碼器來實(shí)現(xiàn)這一點(diǎn)(這就是本文標(biāo)題為“無限可能的世界”的原因!)。你只需在模型的輸出層中將通道數(shù)更改為3(而不是1),就可以對(duì)上述體系結(jié)構(gòu)進(jìn)行一些小的更改。這里有幾個(gè)結(jié)果:
結(jié)論
這些只是我設(shè)法使用自動(dòng)編碼器構(gòu)建的一些應(yīng)用程序,但可能性是無限的,因此,我建議讀者充分發(fā)揮自己的創(chuàng)造力,并找到更好的自動(dòng)編碼器用途。謝謝。
參考
1.) Vanilla AutoEncoder
2.) UNet Code and Binary Segmentation
3.) UNet for Road map generation from aerial Images.
4.) Super Resolution

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長度6~500個(gè)字
最新活動(dòng)更多
-
即日-9.1立即下載>> 【限時(shí)下載】ADI中國三十周年感恩回饋助力企業(yè)升級(jí)!
-
即日-9.16點(diǎn)擊進(jìn)入 >> 【限時(shí)福利】TE 2025國際物聯(lián)網(wǎng)展·深圳站
-
10月23日立即報(bào)名>> Works With 開發(fā)者大會(huì)深圳站
-
10月24日立即參評(píng)>> 【評(píng)選】維科杯·OFweek 2025(第十屆)物聯(lián)網(wǎng)行業(yè)年度評(píng)選
-
11月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
12月18日立即報(bào)名>> 【線下會(huì)議】OFweek 2025(第十屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
推薦專題
- 1 阿里首位程序員,“掃地僧”多隆已離職
- 2 先進(jìn)算力新選擇 | 2025華為算力場景發(fā)布會(huì)暨北京xPN伙伴大會(huì)成功舉辦
- 3 宇樹機(jī)器人撞人事件的深度剖析:六維力傳感器如何成為人機(jī)安全的關(guān)鍵屏障
- 4 清華跑出具身智能獨(dú)角獸:給機(jī)器人安上眼睛和大腦,融資近20億
- 5 特朗普要求英特爾首位華人 CEO 辭職
- 6 踢館大廠和微軟,剖析WPS靈犀的AI實(shí)用主義
- 7 騰訊 Q2 財(cái)報(bào)亮眼:AI 已成第二增長曲線
- 8 谷歌吹響AI沖鋒號(hào),AI還有哪些機(jī)會(huì)
- 9 蘋果把身家押在Siri上:一場輸不起的自我革命
- 10 共探合作新機(jī)遇!江門市新會(huì)區(qū)(深圳)“AI + 機(jī)器人” 產(chǎn)業(yè)對(duì)接會(huì)成功舉辦