U-net实现(keras)

毕设老师给的题目是基于深度学习的肝脏肿瘤分割,而unet则是深度网络实现图像分割的benchmark。本人小白一名,没有机器学习与深度学习的基础,但因为毕设紧迫。来不及系统学习,博客里记录学习过程,可能有很多地方理解并不正确,但会一边学习一边更正之前的内容。

unet结构说明
其实unet就是encoder-decoderencoder部分是重复conv-conv-maxpooling的过程,用来获取图像的高层抽象信息(此时的feature size(height & width),就会小于原输入图像,但通道数(feature maps number)会变多,通道数越多,提取到的特征越多),decoder部分则需要还原分辨率(feature size),是通过transpose convolution实现的,同时与上层的feature map进行concatenate(更新:这可以理解为long skip connection,unet的三维实现:vnet,它对unet进行的改进之一就是加入了short skip connection,就是我们熟悉的residual block),重复transconv-concate-conv-conv的过程,最后得到与原输入一样大小的分割结果图。

函数比较
下面两个用keras实现的代码(均来自github上的开源项目),可以发现其一使用了Conv2DTranspose,这与keras里的Deconvolution2D效果一样,也与tf.nn.conv2d_transpose效果一样。另一个则使用了UpSampling2D,虽然这两个都可以增加分辨率,但实现原理是不同的,并且,Conv2DTranspose在增加分辨率的同时,可以自定义输出通道数,在unet中,这儿的输出通道一般是减半,而UpSampling2D仅能增加分辨率,不能改变输出通道数。(第一个实现与原unet论文提出的结构更符合)

keras对比tensorflow
不知道自己的理解是否正确,但是经过比较发现,对于tensorflow建立的model,一般只到activation,模型的lossoptimizer都是另外定义的(有时候封装成一个函数)。而keras的模型,一般直接建立到底,即在activation后,会跟着model.compile(optimizer,loss,metrics,...),猜测,应该是tensorflow需要sess.run([需要的结果],feed_dict),对于训练和测试,两个的feed_dict不同,有时需要的结果也不同,因此模型的结构、损失与优化最好分模块写,而keras封装了model.fit用于训练,model.predict用于预测,所以直接把整个模型结构、损失与优化写在一起。
更新:其实,两者都是类似的,都需要单独的几个东西:
一是原始的y_pred值,这个值在本案例中进行了sigmoid,有些网络中没有进行激活,若没有激活的话,那么后期选择的损失函数与评价函数,就得加上激活的那一部分。
二是损失函数,即优化器优化的对象
三是评价函数,这个可以直接由损失函数取反,也可以定义不同的评价标准
keras与tensorflow只是在实现的细节上有区别。
比如keras的
model.compile(optimizer=Adam(lr=1e-5), loss=dice_coef_loss, metrics=[dice_coef])
就类似于tensorflow的

loss,  acc, _ = sess.run([dice_coef_loss, dice_coef, optimizer], feed_dict={#训练数据集
}

keras的model.predict
就类似于tensorflow的

loss,  acc = sess.run([dice_coef_loss, dice_coef], feed_dict={# 测试数据集
}

学习感想
很多时候,感觉学习的难点不在于如何建立网络。而是整个的步骤,数据获取,预处理,损失函数和metrics怎么根据自己的数据定义等等。特别是学习完别人的例子后,换一个数据来源就不知道怎么处理了,也不知道如何检测自己实现的正确性,网络上完整的例子,进阶式的教学很少,数据集的获取也是个小问题,翻墙下载太慢等等。日后会继续更新博客,争取实现从零到完整的项目。

keras 实现

# from kaggle nerve segmentation competition 
def dice_coef(y_true, y_pred):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


def dice_coef_loss(y_true, y_pred):
    return -dice_coef(y_true, y_pred)


def get_unet():
    inputs = Input((img_rows, img_cols, 1))
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(pool1)
    conv2 = Conv2D(64, (3, 3), activation='relu'
评论 14
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值