Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleGAN
提交
e1963bbc
P
PaddleGAN
项目概览
PaddlePaddle
/
PaddleGAN
大约 1 年 前同步成功
通知
97
Star
7254
Fork
1210
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleGAN
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
e1963bbc
编写于
5月 31, 2021
作者:
F
FNRE
提交者:
GitHub
5月 31, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add FID (#327)
* add FID
上级
97c1d594
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
83 addition
and
60 deletion
+83
-60
ppgan/metrics/__init__.py
ppgan/metrics/__init__.py
+1
-0
ppgan/metrics/fid.py
ppgan/metrics/fid.py
+50
-27
ppgan/metrics/inception.py
ppgan/metrics/inception.py
+32
-33
未找到文件。
ppgan/metrics/__init__.py
浏览文件 @
e1963bbc
...
...
@@ -13,4 +13,5 @@
# limitations under the License.
from
.psnr_ssim
import
PSNR
,
SSIM
from
.fid
import
FID
from
.builder
import
build_metric
ppgan/metrics/
compute_
fid.py
→
ppgan/metrics/fid.py
浏览文件 @
e1963bbc
...
...
@@ -20,7 +20,9 @@ import paddle
from
PIL
import
Image
from
cv2
import
imread
from
scipy
import
linalg
from
inception
import
InceptionV3
from
.inception
import
InceptionV3
from
paddle.utils.download
import
get_weights_path_from_url
from
.builder
import
METRICS
try
:
from
tqdm
import
tqdm
...
...
@@ -35,6 +37,42 @@ except:
"""
inceptionV3 pretrain model is convert from pytorch, pretrain_model url is https://paddle-gan-models.bj.bcebos.com/params_inceptionV3.tar.gz
"""
INCEPTIONV3_WEIGHT_URL
=
"https://paddlegan.bj.bcebos.com/InceptionV3.pdparams"
@
METRICS
.
register
()
class
FID
(
paddle
.
metric
.
Metric
):
def
__init__
(
self
,
batch_size
=
1
,
use_GPU
=
True
,
dims
=
2048
,
premodel_path
=
None
,
model
=
None
):
self
.
batch_size
=
batch_size
self
.
use_GPU
=
use_GPU
self
.
dims
=
dims
self
.
premodel_path
=
premodel_path
if
model
is
None
:
block_idx
=
InceptionV3
.
BLOCK_INDEX_BY_DIM
[
dims
]
model
=
InceptionV3
([
block_idx
])
if
premodel_path
is
None
:
premodel_path
=
get_weights_path_from_url
(
INCEPTIONV3_WEIGHT_URL
)
self
.
model
=
model
param_dict
=
paddle
.
load
(
premodel_path
)
model
.
load_dict
(
param_dict
)
model
.
eval
()
self
.
reset
()
def
reset
(
self
):
self
.
results
=
[]
def
update
(
self
,
preds
,
gts
):
value
=
calculate_fid_given_img
(
preds
,
gts
,
self
.
batch_size
,
self
.
model
,
self
.
use_GPU
,
self
.
dims
)
self
.
results
.
append
(
value
)
def
accumulate
(
self
):
if
len
(
self
.
results
)
<=
0
:
return
0.
return
np
.
mean
(
self
.
results
)
def
name
(
self
):
return
'FID'
def
_calculate_frechet_distance
(
mu1
,
sigma1
,
mu2
,
sigma2
,
eps
=
1e-6
):
...
...
@@ -71,13 +109,12 @@ def _calculate_frechet_distance(mu1, sigma1, mu2, sigma2, eps=1e-6):
2
*
tr_covmean
)
def
_get_activations_from_ims
(
img
,
model
,
batch_size
,
dims
,
use_gpu
,
premodel_path
):
def
_get_activations_from_ims
(
img
,
model
,
batch_size
,
dims
,
use_gpu
):
n_batches
=
(
len
(
img
)
+
batch_size
-
1
)
//
batch_size
n_used_img
=
len
(
img
)
pred_arr
=
np
.
empty
((
n_used_img
,
dims
))
for
i
in
tqdm
(
range
(
n_batches
)):
start
=
i
*
batch_size
end
=
start
+
batch_size
...
...
@@ -89,19 +126,13 @@ def _get_activations_from_ims(img, model, batch_size, dims, use_gpu,
images
/=
255
images
=
paddle
.
to_tensor
(
images
)
param_dict
,
_
=
paddle
.
load
(
premodel_path
)
model
.
set_dict
(
param_dict
)
model
.
eval
()
pred
=
model
(
images
)[
0
][
0
]
pred_arr
[
start
:
end
]
=
pred
.
reshape
(
end
-
start
,
-
1
)
pred_arr
[
start
:
end
]
=
pred
.
reshape
([
end
-
start
,
-
1
]).
cpu
().
numpy
()
return
pred_arr
def
_compute_statistic_of_img
(
img
,
model
,
batch_size
,
dims
,
use_gpu
,
premodel_path
):
act
=
_get_activations_from_ims
(
img
,
model
,
batch_size
,
dims
,
use_gpu
,
premodel_path
)
def
_compute_statistic_of_img
(
img
,
model
,
batch_size
,
dims
,
use_gpu
):
act
=
_get_activations_from_ims
(
img
,
model
,
batch_size
,
dims
,
use_gpu
)
mu
=
np
.
mean
(
act
,
axis
=
0
)
sigma
=
np
.
cov
(
act
,
rowvar
=
False
)
return
mu
,
sigma
...
...
@@ -110,22 +141,14 @@ def _compute_statistic_of_img(img, model, batch_size, dims, use_gpu,
def
calculate_fid_given_img
(
img_fake
,
img_real
,
batch_size
,
use_gpu
,
dims
,
premodel_path
,
model
=
None
):
assert
os
.
path
.
exists
(
premodel_path
),
'pretrain_model path {} is not exists! Please download it first'
.
format
(
premodel_path
)
if
model
is
None
:
block_idx
=
InceptionV3
.
BLOCK_INDEX_BY_DIM
[
dims
]
model
=
InceptionV3
([
block_idx
])
model
,
use_gpu
=
True
,
dims
=
2048
):
m1
,
s1
=
_compute_statistic_of_img
(
img_fake
,
model
,
batch_size
,
dims
,
use_gpu
,
premodel_path
)
use_gpu
)
m2
,
s2
=
_compute_statistic_of_img
(
img_real
,
model
,
batch_size
,
dims
,
use_gpu
,
premodel_path
)
use_gpu
)
fid_value
=
_calculate_frechet_distance
(
m1
,
s1
,
m2
,
s2
)
return
fid_value
...
...
ppgan/metrics/inception.py
浏览文件 @
e1963bbc
...
...
@@ -15,7 +15,7 @@
import
math
import
paddle
import
paddle.nn
as
nn
from
paddle.nn
import
Conv2D
,
AvgPool2D
,
MaxPool2D
,
BatchNorm
,
Linear
from
paddle.nn
import
Conv2D
,
AvgPool2D
,
MaxPool2D
,
BatchNorm
,
Linear
,
AdaptiveAvgPool2D
__all__
=
[
'InceptionV3'
]
...
...
@@ -57,7 +57,7 @@ class InceptionV3(nn.Layer):
3
,
padding
=
1
,
name
=
'Conv2d_2b_3x3'
)
self
.
maxpool1
=
MaxPool2D
(
pool_size
=
3
,
pool_
stride
=
2
)
self
.
maxpool1
=
MaxPool2D
(
kernel_size
=
3
,
stride
=
2
)
block0
=
[
self
.
Conv2d_1a_3x3
,
self
.
Conv2d_2a_3x3
,
self
.
Conv2d_2b_3x3
,
...
...
@@ -69,7 +69,7 @@ class InceptionV3(nn.Layer):
if
self
.
last_needed_block
>=
1
:
self
.
Conv2d_3b_1x1
=
ConvBNLayer
(
64
,
80
,
1
,
name
=
'Conv2d_3b_1x1'
)
self
.
Conv2d_4a_3x3
=
ConvBNLayer
(
80
,
192
,
3
,
name
=
'Conv2d_4a_3x3'
)
self
.
maxpool2
=
MaxPool2D
(
pool_size
=
3
,
pool_
stride
=
2
)
self
.
maxpool2
=
MaxPool2D
(
kernel_size
=
3
,
stride
=
2
)
block1
=
[
self
.
Conv2d_3b_1x1
,
self
.
Conv2d_4a_3x3
,
self
.
maxpool2
]
self
.
blocks
.
append
(
nn
.
Sequential
(
*
block1
))
...
...
@@ -107,7 +107,7 @@ class InceptionV3(nn.Layer):
self
.
Mixed_7a
=
InceptionD
(
768
,
name
=
'Mixed_7a'
)
self
.
Mixed_7b
=
Fid_inceptionE_1
(
1280
,
name
=
'Mixed_7b'
)
self
.
Mixed_7c
=
Fid_inceptionE_2
(
2048
,
name
=
'Mixed_7c'
)
self
.
avgpool
=
A
vgPool2D
(
global_pooling
=
True
)
self
.
avgpool
=
A
daptiveAvgPool2D
(
output_size
=
1
)
block3
=
[
self
.
Mixed_7a
,
self
.
Mixed_7b
,
self
.
Mixed_7c
,
self
.
avgpool
]
self
.
blocks
.
append
(
nn
.
Sequential
(
*
block3
))
...
...
@@ -170,9 +170,9 @@ class InceptionA(nn.Layer):
padding
=
1
,
name
=
name
+
'.branch3x3dbl_3'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
pool_features
,
...
...
@@ -219,7 +219,7 @@ class InceptionB(nn.Layer):
stride
=
2
,
name
=
name
+
'.branch3x3dbl_3'
)
self
.
branch_pool
=
MaxPool2D
(
pool_size
=
3
,
pool_
stride
=
2
)
self
.
branch_pool
=
MaxPool2D
(
kernel_size
=
3
,
stride
=
2
)
def
forward
(
self
,
x
):
branch3x3
=
self
.
branch3x3
(
x
)
...
...
@@ -275,9 +275,9 @@ class InceptionC(nn.Layer):
padding
=
(
0
,
3
),
name
=
name
+
'.branch7x7dbl_5'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
192
,
...
...
@@ -335,7 +335,7 @@ class InceptionD(nn.Layer):
stride
=
2
,
name
=
name
+
'.branch7x7x3_4'
)
self
.
branch_pool
=
MaxPool2D
(
pool_size
=
3
,
pool_
stride
=
2
)
self
.
branch_pool
=
MaxPool2D
(
kernel_size
=
3
,
stride
=
2
)
def
forward
(
self
,
x
):
branch3x3
=
self
.
branch3x3_1
(
x
)
...
...
@@ -391,9 +391,9 @@ class InceptionE(nn.Layer):
padding
=
(
1
,
0
),
name
=
name
+
'.branch3x3dbl_3b'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
192
,
...
...
@@ -425,7 +425,7 @@ class InceptionAux(nn.Layer):
def
__init__
(
self
,
in_channels
,
num_classes
,
name
=
None
):
super
(
InceptionAux
,
self
).
__init__
()
self
.
num_classes
=
num_classes
self
.
pool0
=
AvgPool2D
(
pool_size
=
5
,
pool_
stride
=
3
)
self
.
pool0
=
AvgPool2D
(
kernel_size
=
5
,
stride
=
3
)
self
.
conv0
=
ConvBNLayer
(
in_channels
,
128
,
1
,
name
=
name
+
'.conv0'
)
self
.
conv1
=
ConvBNLayer
(
128
,
768
,
5
,
name
=
name
+
'.conv1'
)
self
.
pool1
=
AvgPool2D
(
global_pooling
=
True
)
...
...
@@ -475,9 +475,9 @@ class Fid_inceptionA(nn.Layer):
padding
=
1
,
name
=
name
+
'.branch3x3dbl_3'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
pool_features
,
...
...
@@ -544,9 +544,9 @@ class Fid_inceptionC(nn.Layer):
padding
=
(
0
,
3
),
name
=
name
+
'.branch7x7dbl_5'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
192
,
...
...
@@ -614,9 +614,9 @@ class Fid_inceptionE_1(nn.Layer):
padding
=
(
1
,
0
),
name
=
name
+
'.branch3x3dbl_3b'
)
self
.
branch_pool0
=
AvgPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
,
self
.
branch_pool0
=
AvgPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
,
exclusive
=
True
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
192
,
...
...
@@ -685,9 +685,9 @@ class Fid_inceptionE_2(nn.Layer):
padding
=
(
1
,
0
),
name
=
name
+
'.branch3x3dbl_3b'
)
### same with paper
self
.
branch_pool0
=
MaxPool2D
(
poo
l_size
=
3
,
pool_
stride
=
1
,
p
ool_p
adding
=
1
)
self
.
branch_pool0
=
MaxPool2D
(
kerne
l_size
=
3
,
stride
=
1
,
padding
=
1
)
self
.
branch_pool
=
ConvBNLayer
(
in_channels
,
192
,
1
,
...
...
@@ -725,14 +725,13 @@ class ConvBNLayer(nn.Layer):
act
=
'relu'
,
name
=
None
):
super
(
ConvBNLayer
,
self
).
__init__
()
self
.
conv
=
Conv2D
(
num
_channels
=
in_channels
,
num_filter
s
=
num_filters
,
filter
_size
=
filter_size
,
self
.
conv
=
Conv2D
(
in
_channels
=
in_channels
,
out_channel
s
=
num_filters
,
kernel
_size
=
filter_size
,
stride
=
stride
,
padding
=
padding
,
groups
=
groups
,
act
=
None
,
param_attr
=
paddle
.
ParamAttr
(
name
=
name
+
".conv.weight"
),
weight_attr
=
paddle
.
ParamAttr
(
name
=
name
+
".conv.weight"
),
bias_attr
=
False
)
self
.
bn
=
BatchNorm
(
num_filters
,
act
=
act
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录