如何在 keras 中正确使用 U-net 批量标准化?
Posted
技术标签:
【中文标题】如何在 keras 中正确使用 U-net 批量标准化?【英文标题】:How to correctly use batch normalization with U-net in keras? 【发布时间】:2019-10-07 05:39:34 【问题描述】:我正在尝试使用带有 U-net 的批量标准化层来执行分割任务。相同的层适用于 res-net、vgg、xception 等,我很好奇这是否是一个依赖于架构的问题?在训练期间一切都很好,指标会增加损失 dpor,但是一旦我尝试评估模型或预测掩码,它就会产生垃圾。即使在测试和预测期间,这些层的学习权重似乎也会不断更新。如何在keras中解决这个问题? keras 版本 = 2.2.2
我试图仅在编码器部分使用 Batch norm 层,但没有帮助。 我还尝试设置图层参数:trainable=False,没有帮助。
from keras.models import Input, Model
from keras.layers import Conv2D, Concatenate, MaxPooling2D
from keras.layers import UpSampling2D, Dropout, BatchNormalization
def conv_block(m, dim, res, do=0):
n = Conv2D(dim, 3, padding='same')(m)
n = BatchNormalization()(n)
n = keras.layers.LeakyReLU(0)(n)
n = Dropout(do)(n) if do else n
n = Conv2D(dim, 3, padding='same')(n)
n = BatchNormalization()(n)
n = keras.layers.LeakyReLU(0)(n)
return Concatenate()([m, n]) if res else n
def conv_block_bn(m, dim, res, do=0):
n = Conv2D(dim, 3, padding='same')(m)
n = BatchNormalization()(n)
n = keras.layers.LeakyReLU(0)(n)
n = Dropout(do)(n) if do else n
n = Conv2D(dim, 3, padding='same')(n)
n = BatchNormalization()(n)
n = keras.layers.LeakyReLU(0)(n)
return Concatenate()([m, n]) if res else n
def level_block(m, dim, depth, inc, do, mp, up, res):
if depth > 0:
n = conv_block_bn(m, dim, res)#(m, dim, acti, bn, res)
m = MaxPooling2D()(n) if mp else Conv2D(dim, 3, strides=2, padding='same')(n)
m = level_block(m, int(inc*dim), depth-1, inc, do, mp, up, res)
if up:
m = UpSampling2D()(m)
m = Conv2D(dim, 2, padding='same')(m)
m = BatchNormalization()(m)
m = keras.layers.LeakyReLU(0)(m)
else:
m = Conv2DTranspose(dim, 3, strides=2, activation='relu', padding='same')(m)
n = Concatenate()([n, m])
m = conv_block_bn(n, dim, res)#(n, dim, acti, bn, res)
else:
m = conv_block_bn(m, dim, res,do)#(m, dim, acti, bn, res, do)
return m
def UNet(img_shape, out_ch=1, start_ch=64, depth=4, inc_rate=2., activation='relu',
dropout=0.5, batchnorm=False, maxpool=True, upconv=True, residual=False):
i = Input(shape=img_shape)
o = level_block(i, start_ch, depth, inc_rate,dropout, maxpool, upconv, residual)
o = Conv2D(out_ch, 1, activation='sigmoid')(o)
return Model(inputs=i, outputs=o)
model1 = UNet((512,512,1), out_ch=1, start_ch=64, depth=4, inc_rate=2.,
dropout=0.5, maxpool=True, upconv=True, residual=False)
model1 = multi_gpu_model(model1,gpus=6)
model1.compile(Adam(lr = 3.5e-6), loss = custom_losses, metrics = [dice_coef]) ```
【问题讨论】:
检查this 以获得使用批量标准化的良好 Keras 实现 【参考方案1】:尝试对每一层进行 bach 归一化,并消除 dropout 层。看看你得到了什么。在预测中还要设置 training=False 的标志。
【讨论】:
以上是关于如何在 keras 中正确使用 U-net 批量标准化?的主要内容,如果未能解决你的问题,请参考以下文章
Keras深度学习实战(17)——使用U-Net架构进行图像分割
Tensorflow (Keras) U-Net 分割训练失败