两种方式处理上下采样维度不匹配的问题

本人做深度学习图像分割,想把任意大小的三维图像不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:https://github.com/luogongning/acdc_segmenter/blob/master/model_zoo.py

# 在一开始就把奇数处理成偶数
height, width, depth = inputI.shape
inputI_padded = tf.pad(inputI, [[0, 0], [0, 0], [0, 0], [depth, depth], [0, 0]], 'CONSTANT')

 

上述两种方法亲测有效,解决了我的问题,望对读者也有所帮助! 

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
在PyTorch维度匹配(dimension matching)是非常关键的概念,特别是在处理张量操作和网络层时。当两个或多个张量进行算数运算、函数应用或连接(如矩阵相乘、卷积等)时,张量的尺寸必须一致,以便计算能够正确执行。 以下是维度匹配的一些要点: 1. **形状(Shape)**:每个张量都有一个形状,它是各维度大小的列表。例如,一个一维张量形状为(5,),而二维张量可能是(3, 4)。 2. **广播(Broadcasting)**:当两个张量的维度不完全相同但可以通过添加额外的1来匹配时,可以使用广播规则进行操作。这允许较小的张量“扩展”到较大的张量的尺寸。 3. **相加(Addition)**:在相加时,两个张量必须在所有维度上具有相同的长度或其一个具有长度1。 4. **乘法(Multiplication)**:对于点积(元素-wise),张量的维度必须至少有一个是一维的;对于矩阵乘法(matmul)或卷积(convolution),它们通常需要特定的维度布局(例如,输入通道-高度-宽度对深度通道-高度-宽度)。 5. **函数应用(Function Application)**:当将函数应用于张量时,如果函数期望的输入和给定张量的维度不符,可能需要调整形状或使用视图(view)功能。 6. **层的输入/输出**:神经网络层通常要求输入和输出具有特定的维度结构,例如,全连接层需要输入为(批量大小, 输入通道数)和输出为(批量大小, 输出通道数)。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值