提交 dc110e31 编写于 作者: C ceci3

update

上级 2d7b7a88
# gan compression
[GAN Compression: Efficient Architectures for Interactive Conditional GANs](https://arxiv.org/abs/2003.08936) based on PaddlePaddle.
including follow six steps:
1. replace resnet block with mobile resnet block in generator.
2. cut off the channels of generator from step 1 as student generator, distill the student generator with the teacher generator get from step 1.
3. student generator get from step2 as [Once-For-All](https://arxiv.org/abs/1908.09791) supernet to finetune different generator architectures.
4. search to get FLOPs and evaluation value of different generator architectures.
5. (optional) finetune the generator architectures get from steps 4, only suit for some model and some dataset.
6. export final model.
## quick start
1. prepare data cyclegan used, the format is like:
```
├── trainA dictionary of trainA data
│ ├── img1.jpg
│ ├── ...
├── trainB dictionary of trainB data
│ ├── img1.jpg
│ ├── ...
├── trainA.txt list file of trainA, every line represent a image in trainA
├── trainB.txt list file of trainB, every line represent a image in trainB
```
2. start to get a compressed model, incluing steps(1~3)
```python
sh run.sh
```
3. search for suitable architectures.
```python
python search.py
```
4. (optional)finetune the model.
```python
python finetune.sh
```
5. export final model
```python
python export.py --h
```
# GAN压缩
基于paddle版本的 [GAN Compression: Efficient Architectures for Interactive Conditional GANs](https://arxiv.org/abs/2003.08936)
包含以下步骤:
1. 替换生成网络里的resnet block 为mobile resnnet block.
2. 裁剪掉第一步得到的生成器中的一些通道作为学生网络,第一步得到的生成器作为教师网络,蒸馏学生网络。
3. 第二步中的学生网络作为[Once-For-ALL](https://arxiv.org/abs/1908.09791)这个网络中的超网络进行训练,优化不同的子结构的效果。
4. 在第三步得到的超网络中进行搜索,得到不同子结构的FLOPs和具体评价指标。
5. (可选)微调第4步中的生成网络,这一步只对某些模型的某些数据集有效,需要具体实验得到finetune收益。
6. 导出最终模型。
## 快速开始
1. 准备cyclegan所需要的数据,数据类型:
```
├── trainA 训练数据A的目录
│ ├── img1.jpg
│ ├── ...
├── trainB 训练数据B的目录
│ ├── img1.jpg
│ ├── ...
├── trainA.txt 包含训练数据A名称的文件,每行代表训练数据A中的一张图片
├── trainB.txt 包含训练数据B名称的文件,每行代表训练数据B中的一张图片
```
2. 开始得到压缩模型,包含步骤1~3。
```python
sh run.sh
```
3. 搜索合适的子结构。
```python
python search.py
```
4. (可选)微调第三步选出的子结构
```python
python finetune.sh
```
5. 导出最终模型。
```python
python export.py --h
```
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle.fluid as fluid
from data_reader import data_reader
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import numpy as np
import itertools
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import numpy as np
import paddle.fluid as fluid
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import InstanceNorm, Conv2D, Conv2DTranspose
from configs import decode_config
from utils.util import load_network
def transfer_conv(m1, m2):
param_w = m1.parameters()[0]
c1, c2, kh, kw = m2.parameters()[0].shape
m2.parameters()[0].set_value(param_w.numpy()[:c1, :c2, :kh, :kw])
if len(m2.parameters()) == 2:
c = m2.parameters()[1].shape[0]
m2.parameters()[1].set_value(m1.parameters()[1].numpy()[:c])
def transfer_weight(netA, netB):
assert len(netA.sublayers()) == len(netB.sublayers())
for (nameA, sublayerA), (nameB, sublayerB) in zip(netA.named_sublayers(),
netB.named_sublayers()):
assert type(sublayerA) == type(sublayerB)
assert nameA == nameB
if isinstance(sublayerA, (Conv2D, Conv2DTranspose)):
transfer_conv(sublayerA, sublayerB)
def main(cfgs):
fluid.enable_imperative()
config = decode_config(cfgs.config_str)
if cfgs.model == 'mobile_resnet':
from model.mobile_generator import MobileResnetGenerator as SuperModel
from model.sub_mobile_generator import SubMobileResnetGenerator as SubModel
input_nc, output_nc = cfgs.input_nc, cfgs.output_nc
super_model = SuperModel(
input_nc,
output_nc,
ngf=cfgs.ngf,
norm_layer=InstanceNorm,
n_blocks=9)
sub_model = SubModel(
input_nc,
output_nc,
config=config,
norm_layer=InstanceNorm,
n_blocks=9)
else:
raise NotImplementedError
load_network(super_model, cfgs.input_path)
transfer_weight(super_model, sub_model)
if not os.path.exists(cfgs.save_dir):
os.makedirs(cfgs.save_dir)
save_path = os.path.join(cfgs.save_dir, 'final_net')
fluid.save_dygraph(sub_model.state_dict(), save_path)
print('Successfully export the subnet at [%s].' % save_path)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--model',
type=str,
default='mobile_resnet',
choices=['mobile_resnet'],
help='specify the model type you want to export')
parser.add_argument(
'--ngf',
type=int,
default=48,
help='the base number of filters of the generator')
parser.add_argument(
'--input_path', type=str, required=True, help='the input model path')
parser.add_argument(
'--save_dir',
type=str,
required=True,
help='the path to the exported model')
parser.add_argument(
'--config_str',
type=str,
default=None,
help='the configuration string for a specific subnet in the supernet')
parser.add_argument(
'--input_nc',
type=int,
default=3,
help='# of input image channels: 3 for RGB and 1 for grayscale')
parser.add_argument(
'--output_nc',
type=int,
default=3,
help='# of output image channels: 3 for RGB and 1 for grayscale')
cfgs = parser.parse_args()
main(cfgs)
python gan_compression.py --task 'supernet'
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import time
import logging
......
import numpy as np
import argparse
from metric.inception import InceptionV3
from utils import util
def read_data(dataroot, filename):
lines = open(os.path.join(dataroot, filename)).readlines()
imgs = []
for line in lines:
img = Image.open(os.path.join(dataroot, line)).convert('RGB')
img = (np.array(img).astype('float32') / 255.0 - 0.5) / 0.5
img = img.transpose([2, 0, 1])
imgs.append(img)
def main(cfgs):
images = read_data(cfgs.dataroot, cfgs.filename)
block_idx = InceptionV3.BLOCK_INDEX_BY_DIM[2048]
inception_model = InceptionV3([block_idx])
images = np.concatenate(images, axis=0)
images = util.tensor2img(images).astype('float32')
m2, s2 = _compute_statistic_of_img(images, inception_model, 32, 2048,
cfgs.use_gpu, cfgs.inception_model_path)
np.savez(cfgs.save_dir, mu=m2, sigma=s2)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--dataroot',
type=str,
default='./data',
help="the dictionary of data")
parser.add_argument(
'--filename',
type=str,
default='trainA.txt',
help="the name of list file")
parser.add_argument(
'--use_gpu',
type=ast.literal_eval,
default=True,
help='Whether to use GPU')
parser.add_argument(
'--inception_model_path',
type=str,
default='metric/params_inceptionV3',
help="The directory of inception pretrain model")
cfgs = parser.parse_args()
main(cfgs)
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import paddle.fluid as fluid
......@@ -5,10 +19,10 @@ import paddle.fluid as fluid
class BaseModel(fluid.dygraph.Layer):
@staticmethod
def add_special_cfgs(parser):
pass
raise NotImplementedError
def set_input(self, inputs):
pass
raise NotImplementedError
def setup(self):
self.load_network()
......@@ -29,10 +43,10 @@ class BaseModel(fluid.dygraph.Layer):
fluid.save_dygraph(net.state_dict(), save_path)
def forward(self):
pass
raise NotImplementedError
def optimize_parameter(self):
pass
raise NotImplementedError
def get_current_loss(self):
loss_dict = {}
......@@ -55,7 +69,7 @@ class BaseModel(fluid.dygraph.Layer):
param.stop_gradient = stop_grad
def evaluate_model(self):
pass
raise NotImplementedError
def profile(self):
pass
raise NotImplementedError
import itertools
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import numpy as np
import paddle.fluid as fluid
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import functools
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import InstanceNorm, Conv2D, Conv2DTranspose, BatchNorm
......
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import division
import paddle.fluid as fluid
import numpy as np
from paddle.fluid.dygraph.nn import Conv2D, Conv2DTranspose, BatchNorm, InstanceNorm
from paddle.nn.layer import Leaky_ReLU, ReLU, Pad2D
import os
import functools
# cudnn is not better when batch size is 1.
use_cudnn = False
class conv2d(fluid.dygraph.Layer):
"""docstring for Conv2D"""
def __init__(self,
num_channels,
num_filters=64,
filter_size=7,
stride=1,
stddev=0.02,
padding=0,
norm=True,
norm_layer=InstanceNorm,
relu=True,
relufactor=0.0,
use_bias=False):
super(conv2d, self).__init__()
if use_bias == False:
con_bias_attr = False
else:
con_bias_attr = fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0))
self.conv = Conv2D(
num_channels=num_channels,
num_filters=int(num_filters),
filter_size=int(filter_size),
stride=stride,
padding=padding,
use_cudnn=use_cudnn,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev)),
bias_attr=con_bias_attr)
if norm_layer == InstanceNorm:
self.bn = InstanceNorm(
num_channels=num_filters,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(1.0),
trainable=False),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0),
trainable=False), )
elif norm_layer == BatchNorm:
self.bn = BatchNorm(
num_channels=num_filters,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(1.0,
0.02)),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0)), )
else:
raise NotImplementedError
self.relufactor = relufactor
self.use_bias = use_bias
self.norm = norm
if relu:
if relufactor == 0.0:
self.lrelu = ReLU()
else:
self.lrelu = Leaky_ReLU(self.relufactor)
self.relu = relu
def forward(self, inputs):
conv = self.conv(inputs)
if self.norm:
conv = self.bn(conv)
if self.relu:
conv = self.lrelu(conv)
#conv = fluid.layers.leaky_relu(conv,alpha=self.relufactor)
return conv
class SeparableConv2D(fluid.dygraph.Layer):
def __init__(self,
num_channels,
num_filters,
filter_size,
stride=1,
padding=0,
norm_layer='instance',
use_bias=True,
scale_factor=1,
stddev=0.02):
super(SeparableConv2D, self).__init__()
if use_bias == False:
con_bias_attr = False
else:
con_bias_attr = fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0))
self.conv_sep = Conv2D(
num_channels=num_channels,
num_filters=num_channels * scale_factor,
filter_size=filter_size,
stride=stride,
padding=padding,
use_cudnn=use_cudnn,
groups=num_channels,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev)),
bias_attr=con_bias_attr)
self.norm = InstanceNorm(
num_channels=num_filters,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(1.0)),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0)), )
self.conv_out = Conv2D(
num_channels=num_channels * scale_factor,
num_filters=num_filters,
filter_size=1,
stride=1,
use_cudnn=use_cudnn,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev)),
bias_attr=con_bias_attr)
def forward(self, inputs):
conv = self.conv_sep(inputs)
conv = self.norm(conv)
conv = self.conv_out(conv)
return conv
class DeConv2D(fluid.dygraph.Layer):
def __init__(self,
num_channels,
num_filters=64,
filter_size=7,
stride=1,
stddev=0.02,
padding=[0, 0],
outpadding=[0, 0, 0, 0],
relu=True,
norm=True,
norm_layer=InstanceNorm,
relufactor=0.0,
use_bias=False):
super(DeConv2D, self).__init__()
if use_bias == False:
de_bias_attr = False
else:
de_bias_attr = fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0))
self._deconv = Conv2DTranspose(
num_channels,
num_filters,
filter_size=filter_size,
stride=stride,
padding=padding,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev)),
bias_attr=de_bias_attr)
self.pad = Pad2D(paddings=outpadding, mode='constant', pad_value=0.0)
if norm_layer == InstanceNorm:
self.bn = InstanceNorm(
num_channels=num_filters,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(1.0),
trainable=False),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0),
trainable=False), )
elif norm_layer == BatchNorm:
self.bn = BatchNorm(
num_channels=num_filters,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.NormalInitializer(1.0,
0.02)),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.Constant(0.0)), )
else:
raise NotImplementedError
self.outpadding = outpadding
self.relufactor = relufactor
self.use_bias = use_bias
self.norm = norm
self.relu = relu
if relu:
if relufactor == 0.0:
self.lrelu = ReLU()
else:
self.lrelu = Leaky_ReLU(self.relufactor)
def forward(self, inputs):
#todo: add use_bias
#if self.use_bias==False:
conv = self._deconv(inputs)
#else:
# conv = self._deconv(inputs)
#conv = fluid.layers.pad2d(conv, paddings=self.outpadding, mode='constant', pad_value=0.0)
conv = self.pad(conv)
if self.norm:
conv = self.bn(conv)
if self.relu:
#conv = fluid.layers.leaky_relu(conv,alpha=self.relufactor)
conv = self.lrelu(conv)
return conv
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle.fluid as fluid
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import Conv2D, Conv2DTranspose, BatchNorm, InstanceNorm, Dropout
from paddle.nn.layer import Leaky_ReLU, ReLU, Pad2D
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import functools
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import BatchNorm, InstanceNorm
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle.fluid as fluid
import paddle.fluid.dygraph_utils as dygraph_utils
from paddle.fluid.data_feeder import check_variable_and_dtype, check_type
......@@ -7,8 +21,6 @@ from paddle.fluid.dygraph.nn import InstanceNorm, Conv2D, Conv2DTranspose
import paddle.fluid.core as core
import numpy as np
use_cudnn = False
class SuperInstanceNorm(fluid.dygraph.InstanceNorm):
def __init__(self,
......@@ -249,7 +261,6 @@ class SuperSeparableConv2D(fluid.dygraph.Layer):
bias_attr=bias_attr)
])
if norm_layer == InstanceNorm:
#self.conv.extend([SuperInstanceNorm(num_channels * scale_factor)])
self.conv.extend([
SuperInstanceNorm(
num_channels * scale_factor,
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import reduce
import paddle.fluid as fluid
import network
from utils import util
#from utils.profile import profile_flops
from paddleslim.analysis.flops import dygraph_flops
......
python gan_compression.py --config_set 'channels-32'
import os
import pickle
import random
import argparse
import ast
import sys
import time
import numpy as np
import paddle.fluid as fluid
from configs import encode_config
from data_loader import create_eval_data
from metric.inception import InceptionV3
from metric import get_fid
from model.test_model import TestModel
from utils import util
def main(cfgs):
fluid.enable_imperative()
if 'resnet' in cfgs.netG:
from configs.resnet_configs import get_configs
else:
raise NotImplementedError
configs = get_configs(config_name=cfgs.config_set)
configs = list(configs.all_configs())
data_loader, id2name = create_eval_data(cfgs, direction=cfgs.direction)
model = TestModel(cfgs)
model.setup() ### load_network
### this input used in compute model flops and params
for data in data_loader:
model.set_input(data)
break
npz = np.load(cfgs.real_stat_path)
results = []
for config in configs:
fakes, names = [], []
flops, _ = model.profile(config=config)
s_time = time.time()
for i, data in enumerate(data_loader()):
model.set_input(data)
model.test(config)
generated = model.fake_B
fakes.append(generated.detach().numpy())
name = id2name[i]
save_path = os.path.join(cfgs.save_dir, 'test' + str(config))
if not os.path.exists(save_path):
os.makedirs(save_path)
save_path = os.path.join(save_path, name)
names.append(name)
if i < cfgs.num_test:
image = util.tensor2img(generated)
util.save_image(image, save_path)
result = {
'config_str': encode_config(config),
'flops': flops
} ### compute FLOPs
fluid.disable_imperative()
if not cfgs.no_fid:
block_idx = InceptionV3.BLOCK_INDEX_BY_DIM[2048]
inception_model = InceptionV3([block_idx])
fid = get_fid(
fakes,
inception_model,
npz,
cfgs.inception_model_path,
batch_size=cfgs.batch_size,
use_gpu=cfgs.use_gpu)
result['fid'] = fid
fluid.enable_imperative()
e_time = (time.time() - s_time) / 60
result['time'] = e_time
print(result)
results.append(result)
if not os.path.exists(cfgs.save_dir):
os.makedirs(os.path.dirname(cfgs.save_dir))
save_file = os.path.join(cfgs.save_dir, 'search_result.pkl')
with open(save_file, 'wb') as f:
pickle.dump(results, f)
print('Successfully finish searching!!!')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--use_gpu',
type=ast.literal_eval,
default=True,
help='Whether to use GPU in train/test model.')
parser.add_argument(
'--no_fid',
type=ast.literal_eval,
default=False,
help='Whether to get fid.')
parser.add_argument(
'--batch_size', type=int, default=32, help="Minbatch size")
parser.add_argument(
'--shuffle',
type=ast.literal_eval,
default=False,
help="Whether to shuffle data")
parser.add_argument(
'--dataset',
type=str,
default='horse2zebra',
help="The name of dataset")
parser.add_argument(
'--dataroot',
type=str,
default='./data',
help="The dictionary of data")
parser.add_argument(
'--model', type=str, default='cycle_gan', help="model name")
parser.add_argument(
'--image_size',
type=int,
default=286,
help="The image size when load image")
parser.add_argument(
'--crop_size',
type=int,
default=256,
help="The crop size used to crop image")
parser.add_argument(
'--num_test',
type=int,
default=np.inf,
help="the number of fake images to save")
parser.add_argument(
'--real_stat_path',
type=str,
default='real_stat/horse2zebra_B.npz',
help="")
parser.add_argument(
'--ngf', type=int, default=32, help="Base channels in generator")
parser.add_argument(
'--netG',
type=str,
default='super_mobile_resnet_9blocks',
help="Which generator network to choose")
parser.add_argument(
'--dropout_rate', type=float, default=0, help="dropout rate")
parser.add_argument(
'--restore_G_path',
type=str,
default='./output/supernet/last_stu_netG',
help="the pretrain model path of generator")
parser.add_argument(
'--input_nc', type=int, default=3, help="input channel")
parser.add_argument(
'--output_nc', type=int, default=3, help="output channel")
parser.add_argument(
'--norm_type',
type=str,
default='instance',
help="The type of normalization")
parser.add_argument(
'--save_dir',
type=str,
default='./search_result',
help="The directory the model and the test result to save")
parser.add_argument(
'--inception_model_path',
type=str,
default='metric/params_inceptionV3',
help="the directory of inception model, used in computing fid")
parser.add_argument(
'--direction', type=str, default='AtoB', help="direction of generator")
parser.add_argument(
'--config_set',
type=str,
default='channels-32',
help="a set of configuration to get subnets of supernet")
parser.add_argument(
'--config_str',
type=str,
default=None,
help="the configuration string used to get specific subnet of supernet")
cfgs = parser.parse_args()
main(cfgs)
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import numpy as np
import paddle.fluid as fluid
......@@ -45,7 +58,7 @@ class ResnetSupernet(BaseResnetDistiller):
parser.add_argument(
'--config_set',
type=str,
default='channels-32',
default=None,
help="a set of configuration to get subnets of supernet")
parser.add_argument(
'--config_str',
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import argparse
import ast
import numpy as np
import paddle.fluid as fluid
from dataset.data_loader import create_eval_data
from metric.inception import InceptionV3
from metric import get_fid
from model.test_model import TestModel
from utils import util
def main(cfgs):
fluid.enable_imperative()
if cfgs.config_str is not None:
assert 'super' in cfgs.netG or 'sub' in cfgs.netG
config = decode_config(cfgs.config_str)
else:
assert 'super' not in cfgs.model
config = None
data_loader, id2name = create_eval_data(cfgs, direction=cfgs.direction)
model = TestModel(cfgs)
model.setup() ### load_network
fakes, names = [], []
for i, data in enumerate(data_loader()):
model.set_input(data)
if i == 0 and cfgs.need_profile:
flops, params = model.profile(config)
print('FLOPs: %.3fG, params: %.3fM' % (flops / 1e9, params / 1e6))
sys.exit(0)
model.test(config)
generated = model.fake_B
fakes.append(generated.detach().numpy())
name = id2name[i]
print(name)
save_path = os.path.join(cfgs.save_dir, 'test')
if not os.path.exists(save_path):
os.makedirs(save_path)
save_path = os.path.join(save_path, name)
names.append(name)
if i < cfgs.num_test:
image = util.tensor2img(generated)
util.save_image(image, save_path)
fluid.disable_imperative()
if not cfgs.no_fid:
print('Calculating FID...')
block_idx = InceptionV3.BLOCK_INDEX_BY_DIM[2048]
inception_model = InceptionV3([block_idx])
npz = np.load(cfgs.real_stat_path)
fid = get_fid(fakes, inception_model, npz, cfgs.inception_model_path)
print('fid score: %#.2f' % fid)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--use_gpu',
type=ast.literal_eval,
default=True,
help='Whether to use GPU in train/test model.')
parser.add_argument(
'--need_profile',
type=ast.literal_eval,
default=True,
help='Whether to profile model.')
parser.add_argument(
'--no_fid',
type=ast.literal_eval,
default=False,
help='Whether to get fid.')
parser.add_argument(
'--batch_size', type=int, default=1, help="Minbatch size")
parser.add_argument(
'--shuffle',
type=ast.literal_eval,
default=False,
help="Whether to shuffle data")
parser.add_argument(
'--dataset',
type=str,
default='horse2zebra',
help="The name of dataset")
parser.add_argument(
'--dataroot',
type=str,
default='./data',
help="The dictionary of data")
parser.add_argument(
'--model', type=str, default='cycle_gan', help="model name")
parser.add_argument(
'--image_size',
type=int,
default=286,
help="The image size when load image")
parser.add_argument(
'--crop_size',
type=int,
default=256,
help="The crop size used to crop image")
parser.add_argument(
'--num_test',
type=int,
default=np.inf,
help="the number of fake images to save")
parser.add_argument(
'--real_stat_path',
type=str,
default='real_stat/horse2zebra_B.npz',
help="path of real stat")
parser.add_argument(
'--ngf', type=int, default=None, help="Base channels in generator")
parser.add_argument(
'--netG',
type=str,
default='mobile_resnet_9blocks',
help="Which generator network to choose")
parser.add_argument(
'--dropout_rate', type=float, default=0, help="dropout rate")
parser.add_argument(
'--restore_G_path',
type=str,
default=None,
help="the pretrain model path of generator")
parser.add_argument(
'--input_nc', type=int, default=3, help="input channel")
parser.add_argument(
'--output_nc', type=int, default=3, help="output channel")
parser.add_argument(
'--norm_type',
type=str,
default='instance',
help="The type of normalization")
parser.add_argument(
'--save_dir',
type=str,
default='./test_mobile_pth',
help="The directory the model and the test result to save")
parser.add_argument(
'--inception_model_path',
type=str,
default='metric/params_inceptionV3',
help="the directory of inception model, used in computing fid")
parser.add_argument(
'--direction', type=str, default='AtoB', help="direction of generator")
parser.add_argument(
'--config_set',
type=str,
default=None,
help="a set of configuration to get subnets of supernet")
parser.add_argument(
'--config_str',
type=str,
default=None,
help="the configuration string used to get specific subnet of supernet")
cfgs = parser.parse_args()
main(cfgs)
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import ast
......@@ -37,20 +50,17 @@ class configs:
help='Whether to use GPU in train/test model.')
### data
parser.add_argument(
'--batch_size',
type=int,
default=1,
help="Minbatch size in all training")
'--batch_size', type=int, default=1, help="Minbatch size")
parser.add_argument(
'--shuffle',
type=ast.literal_eval,
default=True,
help="Whether to shuffle data in training")
help="Whether to shuffle data")
parser.add_argument(
'--flip',
type=ast.literal_eval,
default=True,
help="Whether to flip data randomly in training")
help="Whether to flip data randomly")
parser.add_argument(
'--dataset',
type=str,
......@@ -108,7 +118,7 @@ class configs:
'--save_dir',
type=str,
default='./output',
help="The directory the model and the test result to saved")
help="The directory the model and the test result to save")
parser.add_argument(
'--netD',
type=str,
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import paddle.fluid as fluid
from paddle.fluid.dygraph.learning_rate_scheduler import LearningRateDecay
#step_per_epoch = 1334
class LinearDecay(LearningRateDecay):
def __init__(self, learning_rate, step_per_epoch, nepochs, nepochs_decay):
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import numpy as np
import pickle
......@@ -6,8 +19,7 @@ import paddle.fluid as fluid
def load_network(model, model_path):
if model_path.split('.')[-1] == 'pkl' or model_path.split('.')[
-1] == 'pth':
if model_path.split('.')[-1] == 'pkl':
model_weight = pickle.load(open(model_path, 'rb'))
for key, value in model_weight.items():
model_weight[key] = np.array(value)
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import Conv2D, Conv2DTranspose, InstanceNorm
from models.modules import SeparableConv2D, MobileResnetBlock, ResnetBlock
......@@ -151,25 +165,3 @@ def load_pretrained_weight(model1, model2, netA, netB, ngf1, ngf2):
index = transfer(m1, m2, index)
else:
raise NotImplementedError('Unknown model [%s]!' % model1)
class Test(fluid.dygraph.Layer):
def __init__(self):
super(Test, self).__init__()
self.net1 = SeparableConv2D(
num_channels=4, num_filters=6, filter_size=3)
def forward(self, x):
out = self.net1(x)
return out
if __name__ == '__main__':
data = np.random.random((1, 4, 6, 6)).astype('float32')
with fluid.dygraph.guard():
net1 = Test()
net2 = Test()
net_1 = net1(to_variable(data))
net_2 = net2(to_variable(data))
model1 = model2 = 'mobile_resnet_9blocks'
load_pretrained_weight(model1, model2, net1, net2, 4, 4)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册