兩種方式處理上下取樣維度不匹配的問題

2021-10-02 09:04:28 字數 2578 閱讀 1680

本人做深度學習影象分割,想把任意大小的三維影象不crop直接輸入神經網路中,我採用的是3d-unet,這裡以512*512*295為例,只有第三維為奇數,若其它維度出現奇數,同理。

在下取樣時,295/2 = 142 ,上取樣回去時若不進行處理,則142*2 = 294 不能復原,有以下兩種方法可解決這個問題。

一、反卷積(transpose)

# 在contact之前需要判斷兩個向量的維度是否一致

if(deconv1_1.get_shape() != conv4_2.get_shape()):

print("解卷積...")

filter = deconv1_1.get_shape()[4]

deconv1_1 = conv3d_transpose(input=deconv1_1, filter=filter, kernel_size=[1, 1, 2], stride=1,

name='deconv1_1_1')

concat_1 = tf.concat([deconv1_1, conv4_2], axis=concat_dim, name='concat_1')

print("concat " ,concat_1)

其中conv3d_transpose函式如下:

def conv3d_transpose(input,filter,kernel_size,stride, name):

with tf.variable_scope(name):

conv = tf.layers.conv3d_transpose(inputs=input,filters=filter,

kernel_size=kernel_size,

strides=stride,padding='valid',data_format='channels_last')

return conv

關於 tf.layers.conv3d_transpose的具體用法可以去查tensorflow的官方api,這裡不再詳細解釋。

至此,問題完美解決!

but...在計算損失函式的時候,我用的是邊緣聯合損失函式,也就是輔助損失函式,如下所示:

# *****==== dice loss

self.main_dice_loss = self.dice_loss_fun(self.pred_prob, self.input_gt)

# auxiliary loss

self.aux0_dice_loss = self.dice_loss_fun(self.aux0_prob, self.input_gt)

self.aux1_dice_loss = self.dice_loss_fun(self.aux1_prob, self.input_gt)

self.aux2_dice_loss = self.dice_loss_fun(self.aux2_prob, self.input_gt)

self.total_dice_loss = self.main_dice_loss + 0.2 * self.aux0_dice_loss + 0.4 * self.aux1_dice_loss + 0.8 * self.aux2_dice_loss

# *****==== class-weighted cross-entropy loss

self.main_wght_loss = self.softmax_weighted_loss(self.pred_prob, self.input_gt)

self.aux0_wght_loss = self.softmax_weighted_loss(self.aux0_prob, self.input_gt)

self.aux1_wght_loss = self.softmax_weighted_loss(self.aux1_prob, self.input_gt)

self.aux2_wght_loss = self.softmax_weighted_loss(self.aux2_prob, self.input_gt)

self.total_wght_loss = self.main_wght_loss + 0.3 * self.aux0_wght_loss + 0.6 * self.aux1_wght_loss + 0.9 * self.aux2_wght_loss

這樣一來就要求 self.aux0_prob這些解卷積後需要完全與輸入維度匹配,這時,難道要再用一次解卷積嗎?內心崩潰,於是乾脆換了一種思路——在一開始下取樣時就將奇數維度padding成偶數,就不存在這個問題了。

二、padding

這個思路**於fcn的原始碼,github:

# 在一開始就把奇數處理成偶數

height, width, depth = inputi.shape

inputi_padded = tf.pad(inputi, [[0, 0], [0, 0], [0, 0], [depth, depth], [0, 0]], 'constant')

上述兩種方法親測有效,解決了我的問題,望對讀者也有所幫助! 

上下文管理的兩種方式

比較簡單,只是簡單的筆記,感謝那個不知道叫什麼名字的老師 一般的應用場景 需要頻繁連線和釋放資源,或者某個 塊前後的固定執行語句 coding utf 8 time 2019 1 27 3 21 author meta qq 239036082 from contextlib import cont...

異常處理的兩種方式

處理異常的兩種方式 1.繼續上拋 相當於推卸責任,把異常傳遞給呼叫者。2.自己捕捉 捕捉相當於自己攔下異常,把異常給解決了,呼叫者是不知道的。如果希望呼叫者處理異常,選擇throws上報異常。不希望呼叫者處理異常,選擇try catch捕捉。如果有乙個類,它的構造方法可能出現異常,我們選擇上報異常,...

異常處理的兩種方式

1.繼續上拋 相當於推卸責任,把異常傳遞給呼叫者。2.自己捕捉 捕捉相當於自己攔下異常,把異常給解決了,呼叫者是不知道的。如果希望呼叫者處理異常,選擇throws上報異常。不希望呼叫者處理異常,選擇try catch捕捉。如果有乙個類,它的構造方法可能出現異常,我們選擇上報異常,因為構造方法是上級呼...