高级实训任务二U-Net图像分割实验报告
1.任务描述
● 将卷积神经网络(CNN)应用在图像分割任务上,我们需要对网络结构进行设计。
● 需要提交博客报告以及GitHub代码仓库。
● 可选的任务:图像实例分割、语义分割、医疗图像分割。
● 可选的网络结构:YOLO v3、Mask R-CNN、U-Net。
● 可选的数据集:参考下文:
● https://zhuanlan.zhihu.com/p/50925449
● 可选深度学习框架:Tensorflow、PyTorch、Keras。
● 提交结果:项目报告、答辩幻灯片、相关代码和测试用例。
2.任务开始准备
U-Net原理:
1.Unet 介绍
Unet 发表于 2015 年,属于 FCN 的一种变体。Unet 的初衷是为了解决生物医学图像方面的问题,由于效果确实很好后来也被广泛的应用在语义分割的各个方向,比如卫星图像分割,工业瑕疵检测等。Unet 跟 FCN 都是 Encoder-Decoder 结构,结构简单但很有效。Encoder 负责特征提取,你可以将自己熟悉的各种特征提取网络放在这个位置。由于在医学方面,样本收集较为困难,作者为了解决这个问题,应用了图像增强的方法,在数据集有限的情况下获得了不错的精度。
2.Unet 网络结构
- Encoder

如上图,Unet 网络结构是对称的,形似英文字母 U 所以被称为 Unet。整张图都是由蓝/白色框与各种颜色的箭头组成,其中,蓝/白色框表示 feature map;蓝色箭头表示 3x3 卷积,用于特征提取;灰色箭头表示 skip-connection,用于特征融合;红色箭头表示池化 pooling,用于降低维度;绿色箭头表示上采样 upsample,用于恢复维度;青色箭头表示 1x1 卷积,用于输出结果。其中灰色箭头copy and crop中的copy就是concatenate而crop是为了让两者的长宽一致。Encoder 由卷积操作和下采样操作组成,文中所用的卷积结构统一为 3x3 的卷积核,padding 为 0 ,striding 为 1。没有 padding 所以每次卷积之后 feature map 的 H 和 W 变小了,在 skip-connection 时要注意 feature map 的维度(其实也可以将 padding 设置为 1 避免维度不对应问题)。
更多可以参考:Unet详解
常见的图像分割损失函数有交叉熵,dice系数,FocalLoss等。今天我将分享图像分割FocalLoss损失函数及Tensorflow版本的复现。
3.图像分割unet_Tensorflow入门
FocalLoss介绍
FocalLoss思想出自何凯明大神的论文《Focal Loss for Dense Object Detection》,主要是为了解决one-stage目标检测中正负样本比例严重失衡的问题。
FocalLoss是在交叉熵函数的基础上进行的改进,改进的地方主要在两个地方
(1)、改进第一点如下公式所示。

首先在原有交叉熵函数基础上加了一个权重因子,其中gamma>0,使得更关注于困难的、错分的样本。比如:若 gamma = 2,对于正类样本来说,如果预测结果为0.97,那么肯定是易分类的样本,权重值为0.0009,损失函数值就会很小了;对于正类样本来说,如果预测结果为0.3,那么肯定是难分类的样本,权重值为0.49,其损失函数值相对就会很大;对于负类样本来说,如果预测结果为0.8,那么肯定是难分类的样本,权重值为0.64,其损失函数值相对就会很大;对于负类样本来说,如果预测结果为0.1,那么肯定是易分类的样本,权重值为0.01,其损失函数值就会很小。而对于预测概率为0.5时,损失函数值只减少了0.25倍,所以FocalLoss减少了简单样本的影响从而更加关注于难以区分的样本。
(2)、改进第二点如下公式所示。

FocalLoss还引入了平衡因子alpha,用来平衡正负样本本身的比例不均匀。alpha取值范围0~1,当alpha>0.5时,可以相对增加y=1所占的比例,保证正负样本的平衡。
2、FocalLoss公式推导
在github上已经可以找到很多FocalLoss的实现,如下二分类的FocalLoss实现。实现其实不是很难,但是在实际训练时会出现NAN的现象。

3、FocalLoss代码实现
按照上面导出的表达式FocalLoss的伪代码可以表示为:

从这里可以看到1-y_pred项可能为0或1,这会导致log函数值出现NAN现象,所以好需要对y_pred项进行固定范围值的截断操作。最后在TensorFlow1.8下实现了该函数。
import tensorflow as tfdef focal_loss(y_true, y_pred, alpha=0.25, gamma=2): epsilon = 1e-5 y_pred =
tf.clip_by_value(y_pred, epsilon, 1 - epsilon) logits = tf.log(y_pred / (1 - y_pred)) weight_a = alpha * tf.pow((1
- y_pred), gamma) * y_true weight_b = (1 - alpha) * tf.pow(y_pred, gamma) * (1 - y_true) loss = tf.log1p(tf.exp(-
- logits)) * (weight_a + weight_b) + logits * weight_b return tf.reduce_mean(loss)
3.任务实现方法
工具选择
语言:python
框架选择:tensorflow,keras
此外还用了absl库函数。用absl库定义可重复的代码段,定义训练的各个参数(比如学习率,周期数,每个周期的训练轮数等)。
- tensorflow定义
'''
参数设定:eopch=4,step=100,batch_size=2,learning_rate=0.0002
'''
inputs = tf.keras.layers.Input((512, 512, 1))
# Contracting part
conv1 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
conv1 = tf.keras.layers.Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)
assert conv1.shape[1:] == (512, 512, 64)
pool1 = tf.keras.layers.MaxPooling2D(pool_size=

本文是高级实训任务二U-Net图像分割的实验报告,详细介绍了Unet网络结构、原理及其在图像分割任务中的应用。通过Tensorflow实现Unet模型,探讨了FocalLoss在解决正负样本不平衡问题中的作用,展示了实验过程和训练结果,加深了对深度学习在图像处理领域的理解。
最低0.47元/天 解锁文章
9021

被折叠的 条评论
为什么被折叠?



