本人做深度學習影象分割,想把任意大小的三維影象不crop直接輸入神經網路中,我採用的是3d-unet,這裡以512*512*295為例,只有第三維為奇數,若其它維度出現奇數,同理。
在下取樣時,295/2 = 142 ,上取樣回去時若不進行處理,則142*2 = 294 不能復原,有以下兩種方法可解決這個問題。
一、反卷積(transpose)
其中conv3d_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)
關於 tf.layers.conv3d_transpose的具體用法可以去查tensorflow的官方api,這裡不再詳細解釋。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
至此,問題完美解決!
but...在計算損失函式的時候,我用的是邊緣聯合損失函式,也就是輔助損失函式,如下所示:
這樣一來就要求 self.aux0_prob這些解卷積後需要完全與輸入維度匹配,這時,難道要再用一次解卷積嗎?內心崩潰,於是乾脆換了一種思路——在一開始下取樣時就將奇數維度padding成偶數,就不存在這個問題了。# *****==== dice lossself.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
二、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捕捉。如果有乙個類,它的構造方法可能出現異常,我們選擇上報異常,因為構造方法是上級呼...