代码:https://github.com/hezhangsprinter/DCPDN
目录
1. 摘要
本文提出了Densely Connected Pyramid Dehazing Network(DCPDN),该网络嵌入了大气散射模型。该网络包含两个生成器,分别用于生成传输率图和大气光,再通过大气散射模型产生去雾图。同时该网络还包含一个判别器,判别器输入为无雾图和传输率图的堆叠。本文还提出了一种新的损失函数,即边界感知损失函数。
2. 网络结构
DCPDN整体结构如图1所示。
该网络包含三个部分,分别为:金字塔稠密链接传输率图估计网络,大气光估计网络和连结判别器。前两个网络分别生成雾图的传输率图和大气光值,经由大气散射模型生成去雾图。将该去雾图和前面提到的传输率图进行堆叠,送入连结判别器。
2.1 Pyramid Densely Connected Transmission Map Estimation
该网络的框架如图2所示。
该网络是一个编码器-解码器结构的网络。第一个卷积层和前三个稠密块部分采用了预训练的dense-net121的相同部分。下面是根据forward()函数整理的,具体内容见源码。
结果 | 操作 |
---|---|
x0 | Conv2d(in_channels=3, out_channels=64, kernel_size=7, stride=2, padding=3, bias=False) BatchNorm2d(64) ReLU(inplace=True) MaxPool2d(kernel_size=3, stride=2, padding=1) |
x1 | trans_blocks1(dense_blocks(x0)) |
x2 | trans_blocks1(dense_blocks(x1)) |
x3 | trans_blocks1(dense_blocks(x2)) |
x4 | trans_blocks1(dense_blocks(x3)) |
x42 | cat([x4, x2], 1) |
x5 | trans_blocks1(dense_blocks(x42)) |
x52 | cat([x5, x1], 1) |
x6 | trans_blocks1(dense_blocks(x52)) |
x7 | trans_blocks1(dense_blocks(x6)) |
x8 | trans_blocks1(dense_blocks(x7)) |
x8 | cat([x8, x], 1) |
x9 | relu=LeakyReLU(0.2, inplace=True) relu(Conv2d(19, 20, 3, 1, 1)) |
shape_out | x9.data.size()[2:4] |
x101 x102 x103 x104 | F.avg_pool2d(x9, 32) F.avg_pool2d(x9, 16) F.avg_pool2d(x9, 8) F.avg_pool2d(x9, 4) |
x1010 x1020 x1030 x1040 | self.upsample(self.relu(self.conv1010(x101)), size=shape_out) self.upsample(self.relu(self.conv1020(x102)), size=shape_out) self.upsample(self.relu(self.conv1030(x103)), size=shape_out) self.upsample(self.relu(self.conv1040(x104)), size=shape_out) |
dehaze | cat([x1010, x1020, x1030, x1040, x9], 1) |
dehaze | self.tanh(self.refine3(dehaze)) |
2.2 Atmospheric Light Estimation Network
本文中假定大气光是一个全局常数,即 A A A是一个2D的图像,其中每一个像素 A ( z ) A(z) A(z)有相同的值。该网络采用了8个块的U-net结构网络。下表是通过整理forward()函数得到的:
结果 | 操作 |
---|---|
out1 | self.layer1(x) |
out2 | self.layer2(out1) |
out3 | self.layer3(out2) |
out4 | self.layer4(out3) |
out5 | self.layer5(out4) |
out6 | self.layer6(out5) |
out7 | self.layer7(out6) |
out8 | self.layer8(out7) |
dout8 | self.dlayer8(out8) |
dout8_out7 | torch.cat([dout8, out7], 1) |
dout7 | self.dlayer7(dout8_out7) |
dout7_out6 | torch.cat([dout7, out6], 1) |
dout6 | self.dlayer6(dout7_out6) |
dout6_out5 | torch.cat([dout6, out5], 1) |
dout5 | self.dlayer5(dout6_out5) |
dout5_out4 | torch.cat([dout5, out4], 1) |
dout4 | self.dlayer4(dout5_out4) |
dout4_out3 | torch.cat([dout4, out3], 1) |
dout3 | self.dlayer3(dout4_out3) |
dout3_out2 | torch.cat([dout3, out2], 1) |
dout2 | self.dlayer2(dout3_out2) |
dout2_out1 | torch.cat([dout2, out1], 1) |
dout1 | self.dlayer1(dout2_out1) |
2.3 Joint Discriminator
用 G t G_t Gt和 G d G_d Gd分别表示网络生成的传输率图和去雾图。连结判别器的输入为cat([G_t, G_d], 1)。
3. 损失函数
3.1 GAN优化目标
该损失函数为常规GAN网络的优化目标。对于判别器,最大化该函数;对于生成器,最小化该函数。详情看GAN网络的优化函数。
min
G
t
,
G
d
max
D
j
o
i
n
t
E
I
∼
p
d
a
t
a
(
I
)
[
log
(
1
−
D
j
o
i
n
t
(
G
t
(
I
)
)
)
]
+
E
I
∼
p
d
a
t
a
(
I
)
[
log
(
1
−
D
j
o
i
n
t
(
G
d
(
I
)
)
)
]
+
E
t
,
J
∼
p
d
a
t
a
(
t
,
J
)
[
log
D
joint
(
t
,
J
)
)
]
(1)
\begin{aligned} \min _{G_{t}, G_{d}} \max _{D_{joint}}&\ \mathbb{E}_{I \sim p_{{data}}(I)}\left[\log \left(1-D_{joint}\left(G_{t}(I)\right)\right)\right]+\\ &\ \mathbb{E}_{I \sim p_{{data}}(I)}\left[\log \left(1-D_{joint}\left(G_{d}(I)\right)\right)\right]+\\ & \left. \mathbb{E}_{\left.t, J \sim p_{{data}}(t, J\right)}\left[\log D_{\text {joint}}(t, J)\right)\right] \end{aligned} \tag{1}
Gt,GdminDjointmax EI∼pdata(I)[log(1−Djoint(Gt(I)))]+ EI∼pdata(I)[log(1−Djoint(Gd(I)))]+Et,J∼pdata(t,J)[logDjoint(t,J))](1)
这里应该是作者的失误。
3.2 边界感知损失
边界感知损失受如下两点观察的启发:1)边界通常和图像强度不连续相关联,因此可以通过图像梯度来特征化边界;2)神经网络浅层(最前面的几层)提取的特征图通常与边界和等高线有关,换句话说,深度神经网络的前几层可以作为边界检测器。
本文提出的边界感知损失结合了如下三部分:
L
2
L2
L2损失,两个方向的梯度损失以及特征边界损失,定义如下:
L
E
=
λ
E
,
l
2
L
E
,
l
2
+
λ
E
,
g
L
E
,
g
+
λ
E
,
f
L
E
,
f
(2)
L^{E}=\lambda_{E, l_{2}} L_{E, l_{2}}+\lambda_{E, g} L_{E, g}+\lambda_{E, f} L_{E, f} \tag{2}
LE=λE,l2LE,l2+λE,gLE,g+λE,fLE,f(2)
其中,
L
E
,
l
2
L_{E, l_{2}}
LE,l2表示
L
2
L2
L2损失,
L
E
,
g
L_{E, g}
LE,g表示两个方向(水平和垂直)的梯度损失,
L
E
,
f
L_{E, f}
LE,f表示特征损失。
λ
E
,
l
2
\lambda_{E,l_2}
λE,l2,
λ
E
,
g
\lambda_{E,g}
λE,g和
λ
E
,
f
\lambda_{E,f}
λE,f表示对应的权重系数。
L
E
,
l
2
L_{E, l_{2}}
LE,l2定义如下:
L
E
,
l
2
=
∥
G
t
(
I
)
−
t
∥
2
2
(3)
L_{E, l_{2}} = \| G_t(I) - t \|_2^2 \tag{3}
LE,l2=∥Gt(I)−t∥22(3)
L
E
,
g
L_{E, g}
LE,g定义如下:
L
E
,
g
=
∑
w
,
h
∥
(
H
x
(
G
t
(
I
)
)
)
w
,
h
−
(
H
x
(
t
)
)
w
,
h
∥
2
+
∥
(
H
y
(
G
t
(
I
)
)
)
w
,
h
−
(
H
y
(
t
)
)
w
,
h
∥
2
(4)
\begin{aligned} L_{E, g}=&\ \sum_{w, h}\left\|\left(H_{x}\left(G_{t}(I)\right)\right)_{w, h}-\left(H_{x}(t)\right)_{w, h}\right\|_{2} \\ &\ +\left\|\left(H_{y}\left(G_{t}(I)\right)\right)_{w, h}-\left(H_{y}(t)\right)_{w, h}\right\|_{2} \end{aligned} \tag{4}
LE,g= w,h∑∥∥∥(Hx(Gt(I)))w,h−(Hx(t))w,h∥∥∥2 +∥∥∥(Hy(Gt(I)))w,h−(Hy(t))w,h∥∥∥2(4)
其中,
H
x
H_x
Hx和
H
y
H_y
Hy分别表示计算水平和竖直梯度的操作。
w
,
h
w, h
w,h表示输出特征图的宽度和高度。
L
E
,
f
L_{E, f}
LE,f定义如下:
L
E
,
f
=
∑
c
1
,
w
1
,
h
1
∥
(
V
1
(
G
t
(
I
)
)
)
c
1
,
w
1
,
h
1
−
(
V
1
(
t
)
)
c
1
,
w
1
,
h
1
∥
2
+
∑
c
2
,
w
2
,
h
2
∥
(
V
2
(
G
t
(
I
)
)
)
c
2
,
w
2
,
h
2
−
(
V
2
(
t
)
)
c
2
,
w
2
,
h
2
∥
2
(5)
\begin{aligned} L_{E, f} &=\sum_{c_{1}, w_{1}, h_{1}}\left\|\left(V_{1}\left(G_{t}(I)\right)\right)_{c_{1}, w_{1}, h_{1}}-\left(V_{1}(t)\right)_{c_{1}, w_{1}, h_{1}}\right\|_{2} \\ &+\sum_{c_{2}, w_{2}, h_{2}}\left\|\left(V_{2}\left(G_{t}(I)\right)\right)_{c_{2}, w_{2}, h_{2}}-\left(V_{2}(t)\right)_{c_{2}, w_{2}, h_{2}}\right\|_{2} \end{aligned} \tag{5}
LE,f=c1,w1,h1∑∥∥∥(V1(Gt(I)))c1,w1,h1−(V1(t))c1,w1,h1∥∥∥2+c2,w2,h2∑∥∥∥(V2(Gt(I)))c2,w2,h2−(V2(t))c2,w2,h2∥∥∥2(5)
V 1 V_1 V1和 V 2 V_2 V2分别表示VGG-16中relu1_1和relu2_1层的边界提取器。 c 1 , w 2 , h 1 c_1, w_2, h_1 c1,w2,h1分别为对应特征图的通道数、宽和高。
3.3 总损失函数
DCPDN的总损失函数如下:
L
=
L
t
+
L
a
+
L
d
+
λ
j
L
j
(6)
L=L^{t}+L^{a}+L^{d}+\lambda_{j} L^{j} \tag{6}
L=Lt+La+Ld+λjLj(6)
其中,
L
t
L^t
Lt为
L
E
L^E
LE,表示传输率图的损失。
L
a
L^a
La为大气光损失,使用
L
2
L2
L2损失。
L
d
L^d
Ld为去雾结果损失,也是使用
L
2
L2
L2损失。
L
j
L^j
Lj为判别器损失,定义如下:
L
j
=
−
log
(
D
j
o
i
n
t
(
G
t
(
I
)
)
−
log
(
D
j
o
i
n
t
(
G
d
(
I
)
)
(7)
L^{j}=-\log \left(D_{ {joint}}\left(G_{t}(I)\right)-\log \left(D_{{joint}}\left(G_{d}(I)\right) \right.\right. \tag{7}
Lj=−log(Djoint(Gt(I))−log(Djoint(Gd(I))(7)
最小化 L j L^j Lj,即最大化 l o g ( D j o n i t ( G t ( I ) ) ) log(D_{jonit}(G_t(I))) log(Djonit(Gt(I))),表明要让判别器判别生成的传输率图是真实的(训练生成器)。同理后一项也是这么理解。
4. 读后感
网络很大,可以说是堆出来的性能。当时(2018)用GAN来去雾的文章可能比较少,所以当时来说应该是挺有创新的一篇文章。同时,本文提出的边界感知损失的思想还是值得学习的。