未验证 提交 4e361b18 编写于 作者: L LutaoChu 提交者: GitHub

Upgrade API to PaddlePaddle 1.7 version (#214)

* release change log

* update readme

* update readme

* upload fast-scnn image

* update readme

* update readme

* replace fluid.layers.data

* update api fluid.data and fluid.io.DataLoader
Co-authored-by: NLielinJiang <jianglielin@baidu.com>
Co-authored-by: NLielinJiang <50691816+LielinJiang@users.noreply.github.com>
上级 f71ef43f
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
## 简介 ## 简介
PaddleSeg是基于[PaddlePaddle](https://www.paddlepaddle.org.cn)开发的语义分割库,覆盖了DeepLabv3+, U-Net, ICNet, PSPNet, HRNet等主流分割模型。通过统一的配置,帮助用户更便捷地完成从训练到部署的全流程图像分割应用。 PaddleSeg是基于[PaddlePaddle](https://www.paddlepaddle.org.cn)开发的语义分割库,覆盖了DeepLabv3+, U-Net, ICNet, PSPNet, HRNet, Fast-SCNN等主流分割模型。通过统一的配置,帮助用户更便捷地完成从训练到部署的全流程图像分割应用。
</br> </br>
...@@ -33,7 +33,7 @@ PaddleSeg是基于[PaddlePaddle](https://www.paddlepaddle.org.cn)开发的语义 ...@@ -33,7 +33,7 @@ PaddleSeg是基于[PaddlePaddle](https://www.paddlepaddle.org.cn)开发的语义
- **模块化设计** - **模块化设计**
支持U-Net, DeepLabv3+, ICNet, PSPNet, HRNet种主流分割网络,结合预训练模型和可调节的骨干网络,满足不同性能和精度的要求;选择不同的损失函数如Dice Loss, BCE Loss等方式可以强化小目标和不均衡样本场景下的分割精度。 支持U-Net, DeepLabv3+, ICNet, PSPNet, HRNet, Fast-SCNN六种主流分割网络,结合预训练模型和可调节的骨干网络,满足不同性能和精度的要求;选择不同的损失函数如Dice Loss, BCE Loss等方式可以强化小目标和不均衡样本场景下的分割精度。
- **高性能** - **高性能**
...@@ -163,6 +163,14 @@ A: 请将PaddlePaddle升级至1.5.2版本或以上。 ...@@ -163,6 +163,14 @@ A: 请将PaddlePaddle升级至1.5.2版本或以上。
<p align="center"> &#8194;&#8194;&#8194;微信公众号&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;官方技术交流QQ群</p> <p align="center"> &#8194;&#8194;&#8194;微信公众号&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;官方技术交流QQ群</p>
## 更新日志 ## 更新日志
* 2020.02.25
**`v0.4.0`**
* 新增适用于实时场景且不需要预训练模型的分割网络Fast-SCNN,提供基于Cityscapes的[预训练模型](./docs/model_zoo.md)1个。
* 新增LaneNet车道线检测网络,提供[预训练模型](https://github.com/PaddlePaddle/PaddleSeg/tree/release/v0.4.0/contrib/LaneNet#%E4%B8%83-%E5%8F%AF%E8%A7%86%E5%8C%96)一个。
* 新增基于PaddleSlim的分割库压缩策略([量化](./slim/quantization/README.md), [蒸馏](./slim/distillation/README.md), [剪枝](./slim/prune/README.md), [搜索](./slim/nas/README.md))
* 2019.12.15 * 2019.12.15
**`v0.3.0`** **`v0.3.0`**
......
...@@ -108,7 +108,7 @@ SOLVER: ...@@ -108,7 +108,7 @@ SOLVER:
使用下述命令启动训练 使用下述命令启动训练
```shell ```shell
CUDA_VISIBLE_DEVICES=0 python -u train.py --cfg configs/lanenet.yaml --use_gpu --use_mpio --do_eval CUDA_VISIBLE_DEVICES=0 python -u train.py --cfg configs/lanenet.yaml --use_gpu --do_eval
``` ```
## 六. 进行评估 ## 六. 进行评估
......
...@@ -101,10 +101,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -101,10 +101,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
for b in data_gen: for b in data_gen:
yield b yield b
py_reader, pred, grts, masks, accuracy, fp, fn = build_model( data_loader, pred, grts, masks, accuracy, fp, fn = build_model(
test_prog, startup_prog, phase=ModelPhase.EVAL) test_prog, startup_prog, phase=ModelPhase.EVAL)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE) data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE)
# Get device environment # Get device environment
...@@ -127,7 +127,9 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -127,7 +127,9 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
# Use streaming confusion matrix to calculate mean_iou # Use streaming confusion matrix to calculate mean_iou
np.set_printoptions( np.set_printoptions(
precision=4, suppress=True, linewidth=160, floatmode="fixed") precision=4, suppress=True, linewidth=160, floatmode="fixed")
fetch_list = [pred.name, grts.name, masks.name, accuracy.name, fp.name, fn.name] fetch_list = [
pred.name, grts.name, masks.name, accuracy.name, fp.name, fn.name
]
num_images = 0 num_images = 0
step = 0 step = 0
avg_acc = 0.0 avg_acc = 0.0
...@@ -137,7 +139,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -137,7 +139,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1 all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1
timer = Timer() timer = Timer()
timer.start() timer.start()
py_reader.start() data_loader.start()
while True: while True:
try: try:
step += 1 step += 1
...@@ -153,7 +155,8 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -153,7 +155,8 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
print( print(
"[EVAL]step={} accuracy={:.4f} fp={:.4f} fn={:.4f} step/sec={:.2f} | ETA {}" "[EVAL]step={} accuracy={:.4f} fp={:.4f} fn={:.4f} step/sec={:.2f} | ETA {}"
.format(step, avg_acc / num_images, avg_fp / num_images, avg_fn / num_images, speed, .format(step, avg_acc / num_images, avg_fp / num_images,
avg_fn / num_images, speed,
calculate_eta(all_step - step, speed))) calculate_eta(all_step - step, speed)))
timer.restart() timer.restart()
...@@ -162,7 +165,8 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -162,7 +165,8 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
break break
print("[EVAL]#image={} accuracy={:.4f} fp={:.4f} fn={:.4f}".format( print("[EVAL]#image={} accuracy={:.4f} fp={:.4f} fn={:.4f}".format(
num_images, avg_acc / num_images, avg_fp / num_images, avg_fn / num_images)) num_images, avg_acc / num_images, avg_fp / num_images,
avg_fn / num_images))
return avg_acc / num_images, avg_fp / num_images, avg_fn / num_images return avg_acc / num_images, avg_fp / num_images, avg_fn / num_images
......
...@@ -25,6 +25,7 @@ from pdseg.loss import multi_softmax_with_loss ...@@ -25,6 +25,7 @@ from pdseg.loss import multi_softmax_with_loss
from loss import discriminative_loss from loss import discriminative_loss
from models.modeling import lanenet from models.modeling import lanenet
class ModelPhase(object): class ModelPhase(object):
""" """
Standard name for model phase in PaddleSeg Standard name for model phase in PaddleSeg
...@@ -107,35 +108,31 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -107,35 +108,31 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
width = cfg.EVAL_CROP_SIZE[0] width = cfg.EVAL_CROP_SIZE[0]
height = cfg.EVAL_CROP_SIZE[1] height = cfg.EVAL_CROP_SIZE[1]
image_shape = [cfg.DATASET.DATA_DIM, height, width] image_shape = [-1, cfg.DATASET.DATA_DIM, height, width]
grt_shape = [1, height, width] grt_shape = [-1, 1, height, width]
class_num = cfg.DATASET.NUM_CLASSES class_num = cfg.DATASET.NUM_CLASSES
with fluid.program_guard(main_prog, start_prog): with fluid.program_guard(main_prog, start_prog):
with fluid.unique_name.guard(): with fluid.unique_name.guard():
image = fluid.layers.data( image = fluid.data(name='image', shape=image_shape, dtype='float32')
name='image', shape=image_shape, dtype='float32') label = fluid.data(name='label', shape=grt_shape, dtype='int32')
label = fluid.layers.data(
name='label', shape=grt_shape, dtype='int32')
if cfg.MODEL.MODEL_NAME == 'lanenet': if cfg.MODEL.MODEL_NAME == 'lanenet':
label_instance = fluid.layers.data( label_instance = fluid.data(
name='label_instance', shape=grt_shape, dtype='int32') name='label_instance', shape=grt_shape, dtype='int32')
mask = fluid.layers.data( mask = fluid.data(name='mask', shape=grt_shape, dtype='int32')
name='mask', shape=grt_shape, dtype='int32')
# use PyReader when doing traning and evaluation # use DataLoader.from_generator when doing traning and evaluation
if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase): if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase):
py_reader = fluid.io.PyReader( data_loader = fluid.io.DataLoader.from_generator(
feed_list=[image, label, label_instance, mask], feed_list=[image, label, label_instance, mask],
capacity=cfg.DATALOADER.BUF_SIZE, capacity=cfg.DATALOADER.BUF_SIZE,
iterable=False, iterable=False,
use_double_buffer=True) use_double_buffer=True)
loss_type = cfg.SOLVER.LOSS loss_type = cfg.SOLVER.LOSS
if not isinstance(loss_type, list): if not isinstance(loss_type, list):
loss_type = list(loss_type) loss_type = list(loss_type)
logits = seg_model(image, class_num) logits = seg_model(image, class_num)
if ModelPhase.is_train(phase): if ModelPhase.is_train(phase):
...@@ -144,25 +141,30 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -144,25 +141,30 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
if cfg.MODEL.MODEL_NAME == 'lanenet': if cfg.MODEL.MODEL_NAME == 'lanenet':
embeding_logit = logits[1] embeding_logit = logits[1]
logits = logits[0] logits = logits[0]
disc_loss, _, _, l_reg = discriminative_loss(embeding_logit, label_instance, 4, disc_loss, _, _, l_reg = discriminative_loss(
image_shape[1:], 0.5, 3.0, 1.0, 1.0, 0.001) embeding_logit, label_instance, 4, image_shape[2:], 0.5,
3.0, 1.0, 1.0, 0.001)
if "softmax_loss" in loss_type: if "softmax_loss" in loss_type:
weight = None weight = None
if cfg.MODEL.MODEL_NAME == 'lanenet': if cfg.MODEL.MODEL_NAME == 'lanenet':
weight = get_dynamic_weight(label) weight = get_dynamic_weight(label)
seg_loss = multi_softmax_with_loss(logits, label, mask, class_num, weight) seg_loss = multi_softmax_with_loss(logits, label, mask,
class_num, weight)
loss_valid = True loss_valid = True
valid_loss.append("softmax_loss") valid_loss.append("softmax_loss")
if not loss_valid: if not loss_valid:
raise Exception("SOLVER.LOSS: {} is set wrong. it should " raise Exception(
"include one of (softmax_loss, bce_loss, dice_loss) at least" "SOLVER.LOSS: {} is set wrong. it should "
" example: ['softmax_loss']".format(cfg.SOLVER.LOSS)) "include one of (softmax_loss, bce_loss, dice_loss) at least"
" example: ['softmax_loss']".format(cfg.SOLVER.LOSS))
invalid_loss = [x for x in loss_type if x not in valid_loss] invalid_loss = [x for x in loss_type if x not in valid_loss]
if len(invalid_loss) > 0: if len(invalid_loss) > 0:
print("Warning: the loss {} you set is invalid. it will not be included in loss computed.".format(invalid_loss)) print(
"Warning: the loss {} you set is invalid. it will not be included in loss computed."
.format(invalid_loss))
avg_loss = disc_loss + 0.00001 * l_reg + seg_loss avg_loss = disc_loss + 0.00001 * l_reg + seg_loss
...@@ -202,12 +204,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -202,12 +204,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
accuracy, fp, fn = compute_metric(pred, label) accuracy, fp, fn = compute_metric(pred, label)
if ModelPhase.is_eval(phase): if ModelPhase.is_eval(phase):
return py_reader, pred, label, mask, accuracy, fp, fn return data_loader, pred, label, mask, accuracy, fp, fn
if ModelPhase.is_train(phase): if ModelPhase.is_train(phase):
optimizer = solver.Solver(main_prog, start_prog) optimizer = solver.Solver(main_prog, start_prog)
decayed_lr = optimizer.optimise(avg_loss) decayed_lr = optimizer.optimise(avg_loss)
return py_reader, avg_loss, decayed_lr, pred, label, mask, disc_loss, seg_loss, accuracy, fp, fn return data_loader, avg_loss, decayed_lr, pred, label, mask, disc_loss, seg_loss, accuracy, fp, fn
def compute_metric(pred, label): def compute_metric(pred, label):
...@@ -216,19 +218,27 @@ def compute_metric(pred, label): ...@@ -216,19 +218,27 @@ def compute_metric(pred, label):
idx = fluid.layers.where(pred == 1) idx = fluid.layers.where(pred == 1)
pix_cls_ret = fluid.layers.gather_nd(label, idx) pix_cls_ret = fluid.layers.gather_nd(label, idx)
correct_num = fluid.layers.reduce_sum(fluid.layers.cast(pix_cls_ret, 'float32')) correct_num = fluid.layers.reduce_sum(
fluid.layers.cast(pix_cls_ret, 'float32'))
gt_num = fluid.layers.cast(fluid.layers.shape(fluid.layers.gather_nd(label, gt_num = fluid.layers.cast(
fluid.layers.where(label == 1)))[0], 'int64') fluid.layers.shape(
pred_num = fluid.layers.cast(fluid.layers.shape(fluid.layers.gather_nd(pred, idx))[0], 'int64') fluid.layers.gather_nd(label, fluid.layers.where(label == 1)))[0],
'int64')
pred_num = fluid.layers.cast(
fluid.layers.shape(fluid.layers.gather_nd(pred, idx))[0], 'int64')
accuracy = correct_num / gt_num accuracy = correct_num / gt_num
false_pred = pred_num - correct_num false_pred = pred_num - correct_num
fp = fluid.layers.cast(false_pred, 'float32') / fluid.layers.cast(fluid.layers.shape(pix_cls_ret)[0], 'int64') fp = fluid.layers.cast(false_pred, 'float32') / fluid.layers.cast(
fluid.layers.shape(pix_cls_ret)[0], 'int64')
label_cls_ret = fluid.layers.gather_nd(label, fluid.layers.where(label == 1))
mis_pred = fluid.layers.cast(fluid.layers.shape(label_cls_ret)[0], 'int64') - correct_num label_cls_ret = fluid.layers.gather_nd(label,
fn = fluid.layers.cast(mis_pred, 'float32') / fluid.layers.cast(fluid.layers.shape(label_cls_ret)[0], 'int64') fluid.layers.where(label == 1))
mis_pred = fluid.layers.cast(fluid.layers.shape(label_cls_ret)[0],
'int64') - correct_num
fn = fluid.layers.cast(mis_pred, 'float32') / fluid.layers.cast(
fluid.layers.shape(label_cls_ret)[0], 'int64')
accuracy.stop_gradient = True accuracy.stop_gradient = True
fp.stop_gradient = True fp.stop_gradient = True
fn.stop_gradient = True fn.stop_gradient = True
...@@ -239,7 +249,8 @@ def get_dynamic_weight(label): ...@@ -239,7 +249,8 @@ def get_dynamic_weight(label):
label = fluid.layers.reshape(label, [-1]) label = fluid.layers.reshape(label, [-1])
unique_labels, unique_id, counts = fluid.layers.unique_with_counts(label) unique_labels, unique_id, counts = fluid.layers.unique_with_counts(label)
counts = fluid.layers.cast(counts, 'float32') counts = fluid.layers.cast(counts, 'float32')
weight = 1.0 / fluid.layers.log((counts / fluid.layers.reduce_sum(counts) + 1.02)) weight = 1.0 / fluid.layers.log(
(counts / fluid.layers.reduce_sum(counts) + 1.02))
return weight return weight
......
...@@ -232,9 +232,9 @@ def train(cfg): ...@@ -232,9 +232,9 @@ def train(cfg):
cfg.BATCH_SIZE_PER_DEV = batch_size_per_dev cfg.BATCH_SIZE_PER_DEV = batch_size_per_dev
print_info("batch_size_per_dev: {}".format(batch_size_per_dev)) print_info("batch_size_per_dev: {}".format(batch_size_per_dev))
py_reader, avg_loss, lr, pred, grts, masks, emb_loss, seg_loss, accuracy, fp, fn = build_model( data_loader, avg_loss, lr, pred, grts, masks, emb_loss, seg_loss, accuracy, fp, fn = build_model(
train_prog, startup_prog, phase=ModelPhase.TRAIN) train_prog, startup_prog, phase=ModelPhase.TRAIN)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -315,7 +315,10 @@ def train(cfg): ...@@ -315,7 +315,10 @@ def train(cfg):
format(cfg.TRAIN.PRETRAINED_MODEL_DIR)) format(cfg.TRAIN.PRETRAINED_MODEL_DIR))
# fetch_list = [avg_loss.name, lr.name, accuracy.name, precision.name, recall.name] # fetch_list = [avg_loss.name, lr.name, accuracy.name, precision.name, recall.name]
fetch_list = [avg_loss.name, lr.name, seg_loss.name, emb_loss.name, accuracy.name, fp.name, fn.name] fetch_list = [
avg_loss.name, lr.name, seg_loss.name, emb_loss.name, accuracy.name,
fp.name, fn.name
]
if args.debug: if args.debug:
# Fetch more variable info and use streaming confusion matrix to # Fetch more variable info and use streaming confusion matrix to
# calculate IoU results if in debug mode # calculate IoU results if in debug mode
...@@ -359,7 +362,7 @@ def train(cfg): ...@@ -359,7 +362,7 @@ def train(cfg):
print_info("Use multi-thread reader") print_info("Use multi-thread reader")
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
# If not in debug mode, avoid unnessary log and calculate # If not in debug mode, avoid unnessary log and calculate
...@@ -385,16 +388,15 @@ def train(cfg): ...@@ -385,16 +388,15 @@ def train(cfg):
avg_fn /= args.log_steps avg_fn /= args.log_steps
speed = args.log_steps / timer.elapsed_time() speed = args.log_steps / timer.elapsed_time()
print(( print((
"epoch={} step={} lr={:.5f} loss={:.4f} seg_loss={:.4f} emb_loss={:.4f} accuracy={:.4} fp={:.4} fn={:.4} step/sec={:.3f} | ETA {}" "epoch={} step={} lr={:.5f} loss={:.4f} seg_loss={:.4f} emb_loss={:.4f} accuracy={:.4} fp={:.4} fn={:.4} step/sec={:.3f} | ETA {}"
).format(epoch, global_step, lr[0], avg_loss, avg_seg_loss, avg_emb_loss, avg_acc, avg_fp, avg_fn, speed, ).format(epoch, global_step, lr[0], avg_loss, avg_seg_loss,
calculate_eta(all_step - global_step, speed))) avg_emb_loss, avg_acc, avg_fp, avg_fn, speed,
calculate_eta(all_step - global_step, speed)))
if args.use_tb: if args.use_tb:
log_writer.add_scalar('Train/loss', avg_loss, log_writer.add_scalar('Train/loss', avg_loss,
global_step) global_step)
log_writer.add_scalar('Train/lr', lr[0], log_writer.add_scalar('Train/lr', lr[0], global_step)
global_step) log_writer.add_scalar('Train/speed', speed, global_step)
log_writer.add_scalar('Train/speed', speed,
global_step)
sys.stdout.flush() sys.stdout.flush()
avg_loss = 0.0 avg_loss = 0.0
avg_seg_loss = 0.0 avg_seg_loss = 0.0
...@@ -405,7 +407,7 @@ def train(cfg): ...@@ -405,7 +407,7 @@ def train(cfg):
timer.restart() timer.restart()
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -423,10 +425,8 @@ def train(cfg): ...@@ -423,10 +425,8 @@ def train(cfg):
if args.use_tb: if args.use_tb:
log_writer.add_scalar('Evaluate/accuracy', accuracy, log_writer.add_scalar('Evaluate/accuracy', accuracy,
global_step) global_step)
log_writer.add_scalar('Evaluate/fp', fp, log_writer.add_scalar('Evaluate/fp', fp, global_step)
global_step) log_writer.add_scalar('Evaluate/fn', fn, global_step)
log_writer.add_scalar('Evaluate/fn', fn,
global_step)
# Use Tensorboard to visualize results # Use Tensorboard to visualize results
if args.use_tb and cfg.DATASET.VIS_FILE_LIST is not None: if args.use_tb and cfg.DATASET.VIS_FILE_LIST is not None:
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
- [PSPNet](#PSPNet) - [PSPNet](#PSPNet)
- [ICNet](#ICNet) - [ICNet](#ICNet)
- [HRNet](#HRNet) - [HRNet](#HRNet)
- [Fast-SCNN](#Fast-SCNN)
## U-Net ## U-Net
U-Net [1] 起源于医疗图像分割,整个网络是标准的encoder-decoder网络,特点是参数少,计算快,应用性强,对于一般场景适应度很高。U-Net最早于2015年提出,并在ISBI 2015 Cell Tracking Challenge取得了第一。经过发展,目前有多个变形和应用。 U-Net [1] 起源于医疗图像分割,整个网络是标准的encoder-decoder网络,特点是参数少,计算快,应用性强,对于一般场景适应度很高。U-Net最早于2015年提出,并在ISBI 2015 Cell Tracking Challenge取得了第一。经过发展,目前有多个变形和应用。
...@@ -58,6 +59,14 @@ HRNet在人体姿态估计、语义分割和目标检测领域都取得了显著 ...@@ -58,6 +59,14 @@ HRNet在人体姿态估计、语义分割和目标检测领域都取得了显著
![](./imgs/hrnet.png) ![](./imgs/hrnet.png)
### Fast-SCNN
Fast-SCNN [7] 是一个面向实时的语义分割网络。在双分支的结构基础上,大量使用了深度可分离卷积和逆残差(inverted-residual)模块,并且使用特征融合构造金字塔池化模块 (Pyramid Pooling Module)来融合上下文信息。这使得Fast-SCNN在保持高效的情况下能学习到丰富的细节信息。
整个网络结构如下:
![](./imgs/fast-scnn.png)
## 参考文献 ## 参考文献
[1] [U-Net: Convolutional Networks for Biomedical Image Segmentation](https://arxiv.org/abs/1505.04597) [1] [U-Net: Convolutional Networks for Biomedical Image Segmentation](https://arxiv.org/abs/1505.04597)
...@@ -72,3 +81,6 @@ HRNet在人体姿态估计、语义分割和目标检测领域都取得了显著 ...@@ -72,3 +81,6 @@ HRNet在人体姿态估计、语义分割和目标检测领域都取得了显著
[6] [Deep High-Resolution Representation Learning for Visual Recognition](https://arxiv.org/abs/1908.07919) [6] [Deep High-Resolution Representation Learning for Visual Recognition](https://arxiv.org/abs/1908.07919)
[7] [Fast-SCNN: Fast Semantic Segmentation Network](https://arxiv.org/abs/1902.04502)
...@@ -92,10 +92,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -92,10 +92,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
for b in data_gen: for b in data_gen:
yield b[0], b[1], b[2] yield b[0], b[1], b[2]
py_reader, avg_loss, pred, grts, masks = build_model( data_loader, avg_loss, pred, grts, masks = build_model(
test_prog, startup_prog, phase=ModelPhase.EVAL) test_prog, startup_prog, phase=ModelPhase.EVAL)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE) data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE)
# Get device environment # Get device environment
...@@ -128,7 +128,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -128,7 +128,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1 all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1
timer = Timer() timer = Timer()
timer.start() timer.start()
py_reader.start() data_loader.start()
while True: while True:
try: try:
step += 1 step += 1
......
...@@ -308,8 +308,8 @@ def MobileNetV2_scale(): ...@@ -308,8 +308,8 @@ def MobileNetV2_scale():
if __name__ == '__main__': if __name__ == '__main__':
image_shape = [3, 224, 224] image_shape = [-1, 3, 224, 224]
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32') image = fluid.data(name='image', shape=image_shape, dtype='float32')
model = MobileNetV2_x1_0() model = MobileNetV2_x1_0()
logit, decode_ends = model.net(image) logit, decode_ends = model.net(image)
#print("logit:", logit.shape) #print("logit:", logit.shape)
...@@ -311,7 +311,7 @@ def xception_71(): ...@@ -311,7 +311,7 @@ def xception_71():
if __name__ == '__main__': if __name__ == '__main__':
image_shape = [3, 224, 224] image_shape = [-1, 3, 224, 224]
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32') image = fluid.data(name='image', shape=image_shape, dtype='float32')
model = xception_65() model = xception_65()
logit = model.net(image) logit = model.net(image)
...@@ -166,8 +166,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -166,8 +166,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
width = cfg.EVAL_CROP_SIZE[0] width = cfg.EVAL_CROP_SIZE[0]
height = cfg.EVAL_CROP_SIZE[1] height = cfg.EVAL_CROP_SIZE[1]
image_shape = [cfg.DATASET.DATA_DIM, height, width] image_shape = [-1, cfg.DATASET.DATA_DIM, height, width]
grt_shape = [1, height, width] grt_shape = [-1, 1, height, width]
class_num = cfg.DATASET.NUM_CLASSES class_num = cfg.DATASET.NUM_CLASSES
with fluid.program_guard(main_prog, start_prog): with fluid.program_guard(main_prog, start_prog):
...@@ -175,25 +175,22 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -175,25 +175,22 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
# 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程 # 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程
# 预测部署时只须对输入图像增加batch_size维度即可 # 预测部署时只须对输入图像增加batch_size维度即可
if ModelPhase.is_predict(phase): if ModelPhase.is_predict(phase):
origin_image = fluid.layers.data( origin_image = fluid.data(
name='image', name='image',
shape=[-1, -1, -1, cfg.DATASET.DATA_DIM], shape=[-1, -1, -1, cfg.DATASET.DATA_DIM],
dtype='float32', dtype='float32')
append_batch_size=False)
image, valid_shape, origin_shape = export_preprocess( image, valid_shape, origin_shape = export_preprocess(
origin_image) origin_image)
else: else:
image = fluid.layers.data( image = fluid.data(
name='image', shape=image_shape, dtype='float32') name='image', shape=image_shape, dtype='float32')
label = fluid.layers.data( label = fluid.data(name='label', shape=grt_shape, dtype='int32')
name='label', shape=grt_shape, dtype='int32') mask = fluid.data(name='mask', shape=grt_shape, dtype='int32')
mask = fluid.layers.data(
name='mask', shape=grt_shape, dtype='int32')
# use PyReader when doing traning and evaluation # use DataLoader when doing traning and evaluation
if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase): if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase):
py_reader = fluid.io.PyReader( data_loader = fluid.io.DataLoader.from_generator(
feed_list=[image, label, mask], feed_list=[image, label, mask],
capacity=cfg.DATALOADER.BUF_SIZE, capacity=cfg.DATALOADER.BUF_SIZE,
iterable=False, iterable=False,
...@@ -227,7 +224,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -227,7 +224,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
if "softmax_loss" in loss_type: if "softmax_loss" in loss_type:
weight = cfg.SOLVER.CROSS_ENTROPY_WEIGHT weight = cfg.SOLVER.CROSS_ENTROPY_WEIGHT
avg_loss_list.append( avg_loss_list.append(
multi_softmax_with_loss(logits, label, mask, class_num, weight)) multi_softmax_with_loss(logits, label, mask, class_num,
weight))
loss_valid = True loss_valid = True
valid_loss.append("softmax_loss") valid_loss.append("softmax_loss")
if "dice_loss" in loss_type: if "dice_loss" in loss_type:
...@@ -300,12 +298,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN): ...@@ -300,12 +298,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN):
return pred, logit return pred, logit
if ModelPhase.is_eval(phase): if ModelPhase.is_eval(phase):
return py_reader, avg_loss, pred, label, mask return data_loader, avg_loss, pred, label, mask
if ModelPhase.is_train(phase): if ModelPhase.is_train(phase):
optimizer = solver.Solver(main_prog, start_prog) optimizer = solver.Solver(main_prog, start_prog)
decayed_lr = optimizer.optimise(avg_loss) decayed_lr = optimizer.optimise(avg_loss)
return py_reader, avg_loss, decayed_lr, pred, label, mask return data_loader, avg_loss, decayed_lr, pred, label, mask
def to_int(string, dest="I"): def to_int(string, dest="I"):
......
...@@ -202,7 +202,7 @@ def hrnet(input, num_classes): ...@@ -202,7 +202,7 @@ def hrnet(input, num_classes):
return logit return logit
if __name__ == '__main__': if __name__ == '__main__':
image_shape = [3, 769, 769] image_shape = [-1, 3, 769, 769]
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32') image = fluid.data(name='image', shape=image_shape, dtype='float32')
logit = hrnet(image, 4) logit = hrnet(image, 4)
print("logit:", logit.shape) print("logit:", logit.shape)
...@@ -191,7 +191,7 @@ def icnet(input, num_classes): ...@@ -191,7 +191,7 @@ def icnet(input, num_classes):
if __name__ == '__main__': if __name__ == '__main__':
image_shape = [3, 320, 320] image_shape = [-1, 3, 320, 320]
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32') image = fluid.data(name='image', shape=image_shape, dtype='float32')
logit = icnet(image, 4) logit = icnet(image, 4)
print("logit:", logit.shape) print("logit:", logit.shape)
...@@ -129,7 +129,7 @@ def unet(input, num_classes): ...@@ -129,7 +129,7 @@ def unet(input, num_classes):
if __name__ == '__main__': if __name__ == '__main__':
image_shape = [3, 320, 320] image_shape = [-1, 3, 320, 320]
image = fluid.layers.data(name='image', shape=image_shape, dtype='float32') image = fluid.data(name='image', shape=image_shape, dtype='float32')
logit = unet(image, 4) logit = unet(image, 4)
print("logit:", logit.shape) print("logit:", logit.shape)
...@@ -103,7 +103,7 @@ def parse_args(): ...@@ -103,7 +103,7 @@ def parse_args():
help='If set True, enable continuous evaluation job.' help='If set True, enable continuous evaluation job.'
'This flag is only used for internal test.', 'This flag is only used for internal test.',
action='store_true') action='store_true')
# NOTE: This for benchmark # NOTE: This for benchmark
parser.add_argument( parser.add_argument(
'--is_profiler', '--is_profiler',
...@@ -114,7 +114,7 @@ def parse_args(): ...@@ -114,7 +114,7 @@ def parse_args():
'--profiler_path', '--profiler_path',
help='the profiler output file path.(used for benchmark)', help='the profiler output file path.(used for benchmark)',
default='./seg.profiler', default='./seg.profiler',
type=str) type=str)
return parser.parse_args() return parser.parse_args()
...@@ -265,9 +265,9 @@ def train(cfg): ...@@ -265,9 +265,9 @@ def train(cfg):
batch_size_per_dev = cfg.BATCH_SIZE // dev_count batch_size_per_dev = cfg.BATCH_SIZE // dev_count
print_info("batch_size_per_dev: {}".format(batch_size_per_dev)) print_info("batch_size_per_dev: {}".format(batch_size_per_dev))
py_reader, avg_loss, lr, pred, grts, masks = build_model( data_loader, avg_loss, lr, pred, grts, masks = build_model(
train_prog, startup_prog, phase=ModelPhase.TRAIN) train_prog, startup_prog, phase=ModelPhase.TRAIN)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -386,7 +386,7 @@ def train(cfg): ...@@ -386,7 +386,7 @@ def train(cfg):
print_info("Use multi-thread reader") print_info("Use multi-thread reader")
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
if args.debug: if args.debug:
...@@ -454,16 +454,16 @@ def train(cfg): ...@@ -454,16 +454,16 @@ def train(cfg):
sys.stdout.flush() sys.stdout.flush()
avg_loss = 0.0 avg_loss = 0.0
timer.restart() timer.restart()
# NOTE : used for benchmark, profiler tools # NOTE : used for benchmark, profiler tools
if args.is_profiler and epoch == 1 and global_step == args.log_steps: if args.is_profiler and epoch == 1 and global_step == args.log_steps:
profiler.start_profiler("All") profiler.start_profiler("All")
elif args.is_profiler and epoch == 1 and global_step == args.log_steps + 5: elif args.is_profiler and epoch == 1 and global_step == args.log_steps + 5:
profiler.stop_profiler("total", args.profiler_path) profiler.stop_profiler("total", args.profiler_path)
return return
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
......
...@@ -89,7 +89,6 @@ python -m paddle.distributed.launch ./slim/distillation/train_distill.py \ ...@@ -89,7 +89,6 @@ python -m paddle.distributed.launch ./slim/distillation/train_distill.py \
--log_steps 10 --cfg ./slim/distillation/cityscape.yaml \ --log_steps 10 --cfg ./slim/distillation/cityscape.yaml \
--teacher_cfg ./slim/distillation/cityscape_teacher.yaml \ --teacher_cfg ./slim/distillation/cityscape_teacher.yaml \
--use_gpu \ --use_gpu \
--use_mpio \
--do_eval --do_eval
``` ```
......
...@@ -156,7 +156,10 @@ def export_preprocess(image): ...@@ -156,7 +156,10 @@ def export_preprocess(image):
return image, valid_shape, origin_shape return image, valid_shape, origin_shape
def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwargs): def build_model(main_prog=None,
start_prog=None,
phase=ModelPhase.TRAIN,
**kwargs):
if not ModelPhase.is_valid_phase(phase): if not ModelPhase.is_valid_phase(phase):
raise ValueError("ModelPhase {} is not valid!".format(phase)) raise ValueError("ModelPhase {} is not valid!".format(phase))
...@@ -167,8 +170,8 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -167,8 +170,8 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
width = cfg.EVAL_CROP_SIZE[0] width = cfg.EVAL_CROP_SIZE[0]
height = cfg.EVAL_CROP_SIZE[1] height = cfg.EVAL_CROP_SIZE[1]
image_shape = [cfg.DATASET.DATA_DIM, height, width] image_shape = [-1, cfg.DATASET.DATA_DIM, height, width]
grt_shape = [1, height, width] grt_shape = [-1, 1, height, width]
class_num = cfg.DATASET.NUM_CLASSES class_num = cfg.DATASET.NUM_CLASSES
#with fluid.program_guard(main_prog, start_prog): #with fluid.program_guard(main_prog, start_prog):
...@@ -176,36 +179,30 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -176,36 +179,30 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
# 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程 # 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程
# 预测部署时只须对输入图像增加batch_size维度即可 # 预测部署时只须对输入图像增加batch_size维度即可
if cfg.SLIM.KNOWLEDGE_DISTILL_IS_TEACHER: if cfg.SLIM.KNOWLEDGE_DISTILL_IS_TEACHER:
image = main_prog.global_block()._clone_variable(kwargs['image'], image = main_prog.global_block()._clone_variable(
force_persistable=False) kwargs['image'], force_persistable=False)
label = main_prog.global_block()._clone_variable(kwargs['label'], label = main_prog.global_block()._clone_variable(
force_persistable=False) kwargs['label'], force_persistable=False)
mask = main_prog.global_block()._clone_variable(kwargs['mask'], mask = main_prog.global_block()._clone_variable(
force_persistable=False) kwargs['mask'], force_persistable=False)
else: else:
if ModelPhase.is_predict(phase): if ModelPhase.is_predict(phase):
origin_image = fluid.layers.data( origin_image = fluid.data(
name='image', name='image',
shape=[-1, -1, -1, cfg.DATASET.DATA_DIM], shape=[-1, -1, -1, cfg.DATASET.DATA_DIM],
dtype='float32', dtype='float32')
append_batch_size=False) image, valid_shape, origin_shape = export_preprocess(origin_image)
image, valid_shape, origin_shape = export_preprocess(
origin_image)
else: else:
image = fluid.layers.data( image = fluid.data(name='image', shape=image_shape, dtype='float32')
name='image', shape=image_shape, dtype='float32') label = fluid.data(name='label', shape=grt_shape, dtype='int32')
label = fluid.layers.data( mask = fluid.data(name='mask', shape=grt_shape, dtype='int32')
name='label', shape=grt_shape, dtype='int32')
mask = fluid.layers.data(
name='mask', shape=grt_shape, dtype='int32')
# use DataLoader.from_generator when doing traning and evaluation
# use PyReader when doing traning and evaluation
if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase): if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase):
py_reader = None data_loader = None
if not cfg.SLIM.KNOWLEDGE_DISTILL_IS_TEACHER: if not cfg.SLIM.KNOWLEDGE_DISTILL_IS_TEACHER:
py_reader = fluid.io.PyReader( data_loader = fluid.io.DataLoader.from_generator(
feed_list=[image, label, mask], feed_list=[image, label, mask],
capacity=cfg.DATALOADER.BUF_SIZE, capacity=cfg.DATALOADER.BUF_SIZE,
iterable=False, iterable=False,
...@@ -219,16 +216,14 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -219,16 +216,14 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
if class_num > 2 and (("dice_loss" in loss_type) or if class_num > 2 and (("dice_loss" in loss_type) or
("bce_loss" in loss_type)): ("bce_loss" in loss_type)):
raise Exception( raise Exception(
"dice loss and bce loss is only applicable to binary classfication" "dice loss and bce loss is only applicable to binary classfication")
)
# 在两类分割情况下,当loss函数选择dice_loss或bce_loss的时候,最后logit输出通道数设置为1 # 在两类分割情况下,当loss函数选择dice_loss或bce_loss的时候,最后logit输出通道数设置为1
if ("dice_loss" in loss_type) or ("bce_loss" in loss_type): if ("dice_loss" in loss_type) or ("bce_loss" in loss_type):
class_num = 1 class_num = 1
if "softmax_loss" in loss_type: if "softmax_loss" in loss_type:
raise Exception( raise Exception(
"softmax loss can not combine with dice loss or bce loss" "softmax loss can not combine with dice loss or bce loss")
)
logits = seg_model(image, class_num) logits = seg_model(image, class_num)
# 根据选择的loss函数计算相应的损失函数 # 根据选择的loss函数计算相应的损失函数
...@@ -289,10 +284,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -289,10 +284,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
logit, axes=[2, 3], starts=[0, 0], ends=valid_shape) logit, axes=[2, 3], starts=[0, 0], ends=valid_shape)
logit = fluid.layers.resize_bilinear( logit = fluid.layers.resize_bilinear(
logit, logit, out_shape=origin_shape, align_corners=False, align_mode=0)
out_shape=origin_shape,
align_corners=False,
align_mode=0)
logit = fluid.layers.argmax(logit, axis=1) logit = fluid.layers.argmax(logit, axis=1)
return origin_image, logit return origin_image, logit
...@@ -312,7 +304,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -312,7 +304,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
return pred, logit return pred, logit
if ModelPhase.is_eval(phase): if ModelPhase.is_eval(phase):
return py_reader, avg_loss, pred, label, mask return data_loader, avg_loss, pred, label, mask
if ModelPhase.is_train(phase): if ModelPhase.is_train(phase):
decayed_lr = None decayed_lr = None
...@@ -321,7 +313,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg ...@@ -321,7 +313,7 @@ def build_model(main_prog=None, start_prog=None, phase=ModelPhase.TRAIN, **kwarg
decayed_lr = optimizer.optimise(avg_loss) decayed_lr = optimizer.optimise(avg_loss)
# optimizer = solver.Solver(main_prog, start_prog) # optimizer = solver.Solver(main_prog, start_prog)
# decayed_lr = optimizer.optimise(avg_loss) # decayed_lr = optimizer.optimise(avg_loss)
return py_reader, avg_loss, decayed_lr, pred, label, mask, image return data_loader, avg_loss, decayed_lr, pred, label, mask, image
def to_int(string, dest="I"): def to_int(string, dest="I"):
......
...@@ -48,6 +48,7 @@ from utils import dist_utils ...@@ -48,6 +48,7 @@ from utils import dist_utils
import solver import solver
from paddleslim.dist.single_distiller import merge, l2_loss from paddleslim.dist.single_distiller import merge, l2_loss
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='PaddleSeg training') parser = argparse.ArgumentParser(description='PaddleSeg training')
parser.add_argument( parser.add_argument(
...@@ -260,8 +261,9 @@ def train(cfg): ...@@ -260,8 +261,9 @@ def train(cfg):
batch_size_per_dev = cfg.BATCH_SIZE // dev_count batch_size_per_dev = cfg.BATCH_SIZE // dev_count
print_info("batch_size_per_dev: {}".format(batch_size_per_dev)) print_info("batch_size_per_dev: {}".format(batch_size_per_dev))
py_reader, loss, lr, pred, grts, masks, image = build_model(phase=ModelPhase.TRAIN) data_loader, loss, lr, pred, grts, masks, image = build_model(
py_reader.decorate_sample_generator( phase=ModelPhase.TRAIN)
data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -274,8 +276,12 @@ def train(cfg): ...@@ -274,8 +276,12 @@ def train(cfg):
with fluid.program_guard(teacher_program, teacher_startup_program): with fluid.program_guard(teacher_program, teacher_startup_program):
with fluid.unique_name.guard(): with fluid.unique_name.guard():
_, teacher_loss, _, _, _, _, _ = build_model( _, teacher_loss, _, _, _, _, _ = build_model(
teacher_program, teacher_startup_program, phase=ModelPhase.TRAIN, image=image, teacher_program,
label=grts, mask=masks) teacher_startup_program,
phase=ModelPhase.TRAIN,
image=image,
label=grts,
mask=masks)
exe.run(teacher_startup_program) exe.run(teacher_startup_program)
...@@ -293,7 +299,9 @@ def train(cfg): ...@@ -293,7 +299,9 @@ def train(cfg):
'mask': 'mask', 'mask': 'mask',
} }
merge(teacher_program, fluid.default_main_program(), data_name_map, place) merge(teacher_program, fluid.default_main_program(), data_name_map, place)
distill_pairs = [['teacher_bilinear_interp_2.tmp_0', 'bilinear_interp_0.tmp_0']] distill_pairs = [[
'teacher_bilinear_interp_2.tmp_0', 'bilinear_interp_0.tmp_0'
]]
def distill(pairs, weight): def distill(pairs, weight):
""" """
...@@ -322,7 +330,8 @@ def train(cfg): ...@@ -322,7 +330,8 @@ def train(cfg):
build_strategy.fuse_all_optimizer_ops = False build_strategy.fuse_all_optimizer_ops = False
build_strategy.fuse_elewise_add_act_ops = True build_strategy.fuse_elewise_add_act_ops = True
if cfg.NUM_TRAINERS > 1 and args.use_gpu: if cfg.NUM_TRAINERS > 1 and args.use_gpu:
dist_utils.prepare_for_multi_process(exe, build_strategy, fluid.default_main_program()) dist_utils.prepare_for_multi_process(exe, build_strategy,
fluid.default_main_program())
exec_strategy.num_threads = 1 exec_strategy.num_threads = 1
if cfg.TRAIN.SYNC_BATCH_NORM and args.use_gpu: if cfg.TRAIN.SYNC_BATCH_NORM and args.use_gpu:
...@@ -334,10 +343,11 @@ def train(cfg): ...@@ -334,10 +343,11 @@ def train(cfg):
print_info( print_info(
"Sync BatchNorm strategy will not be effective if GPU device" "Sync BatchNorm strategy will not be effective if GPU device"
" count <= 1") " count <= 1")
compiled_train_prog = fluid.CompiledProgram(fluid.default_main_program()).with_data_parallel( compiled_train_prog = fluid.CompiledProgram(
loss_name=all_loss.name, fluid.default_main_program()).with_data_parallel(
exec_strategy=exec_strategy, loss_name=all_loss.name,
build_strategy=build_strategy) exec_strategy=exec_strategy,
build_strategy=build_strategy)
# Resume training # Resume training
begin_epoch = cfg.SOLVER.BEGIN_EPOCH begin_epoch = cfg.SOLVER.BEGIN_EPOCH
...@@ -387,7 +397,9 @@ def train(cfg): ...@@ -387,7 +397,9 @@ def train(cfg):
format(cfg.TRAIN.PRETRAINED_MODEL_DIR)) format(cfg.TRAIN.PRETRAINED_MODEL_DIR))
#fetch_list = [avg_loss.name, lr.name] #fetch_list = [avg_loss.name, lr.name]
fetch_list = [loss.name, 'teacher_' + teacher_loss.name, distill_loss.name, lr.name] fetch_list = [
loss.name, 'teacher_' + teacher_loss.name, distill_loss.name, lr.name
]
if args.debug: if args.debug:
# Fetch more variable info and use streaming confusion matrix to # Fetch more variable info and use streaming confusion matrix to
...@@ -431,7 +443,7 @@ def train(cfg): ...@@ -431,7 +443,7 @@ def train(cfg):
print_info("Use multi-thread reader") print_info("Use multi-thread reader")
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
if args.debug: if args.debug:
...@@ -491,7 +503,8 @@ def train(cfg): ...@@ -491,7 +503,8 @@ def train(cfg):
speed = args.log_steps / timer.elapsed_time() speed = args.log_steps / timer.elapsed_time()
print(( print((
"epoch={} step={} lr={:.5f} loss={:.4f} teacher loss={:.4f} distill loss={:.4f} step/sec={:.3f} | ETA {}" "epoch={} step={} lr={:.5f} loss={:.4f} teacher loss={:.4f} distill loss={:.4f} step/sec={:.3f} | ETA {}"
).format(epoch, global_step, lr[0], avg_loss, avg_t_loss, avg_d_loss, speed, ).format(epoch, global_step, lr[0], avg_loss,
avg_t_loss, avg_d_loss, speed,
calculate_eta(all_step - global_step, speed))) calculate_eta(all_step - global_step, speed)))
if args.use_tb: if args.use_tb:
log_writer.add_scalar('Train/loss', avg_loss, log_writer.add_scalar('Train/loss', avg_loss,
...@@ -507,7 +520,7 @@ def train(cfg): ...@@ -507,7 +520,7 @@ def train(cfg):
timer.restart() timer.restart()
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
......
...@@ -46,7 +46,7 @@ SLIM: ...@@ -46,7 +46,7 @@ SLIM:
## 训练与评估 ## 训练与评估
执行以下命令,边训练边评估 执行以下命令,边训练边评估
```shell ```shell
CUDA_VISIBLE_DEVICES=0 python -u ./slim/nas/train_nas.py --log_steps 10 --cfg configs/deeplabv3p_mobilenetv2_cityscapes.yaml --use_gpu --use_mpio \ CUDA_VISIBLE_DEVICES=0 python -u ./slim/nas/train_nas.py --log_steps 10 --cfg configs/deeplabv3p_mobilenetv2_cityscapes.yaml --use_gpu \
SLIM.NAS_PORT 23333 \ SLIM.NAS_PORT 23333 \
SLIM.NAS_ADDRESS "" \ SLIM.NAS_ADDRESS "" \
SLIM.NAS_SEARCH_STEPS 2 \ SLIM.NAS_SEARCH_STEPS 2 \
......
...@@ -45,6 +45,7 @@ from metrics import ConfusionMatrix ...@@ -45,6 +45,7 @@ from metrics import ConfusionMatrix
from mobilenetv2_search_space import MobileNetV2SpaceSeg from mobilenetv2_search_space import MobileNetV2SpaceSeg
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='PaddleSeg model evalution') parser = argparse.ArgumentParser(description='PaddleSeg model evalution')
parser.add_argument( parser.add_argument(
...@@ -98,10 +99,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -98,10 +99,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
for b in data_gen: for b in data_gen:
yield b[0], b[1], b[2] yield b[0], b[1], b[2]
py_reader, avg_loss, pred, grts, masks = build_model( data_loader, avg_loss, pred, grts, masks = build_model(
test_prog, startup_prog, phase=ModelPhase.EVAL, arch=kwargs['arch']) test_prog, startup_prog, phase=ModelPhase.EVAL, arch=kwargs['arch'])
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE) data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE)
# Get device environment # Get device environment
...@@ -134,7 +135,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -134,7 +135,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1 all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1
timer = Timer() timer = Timer()
timer.start() timer.start()
py_reader.start() data_loader.start()
while True: while True:
try: try:
step += 1 step += 1
......
...@@ -74,9 +74,7 @@ def seg_model(image, class_num, arch): ...@@ -74,9 +74,7 @@ def seg_model(image, class_num, arch):
if model_name == 'deeplabv3p': if model_name == 'deeplabv3p':
logits = deeplab.deeplabv3p_nas(image, class_num, arch) logits = deeplab.deeplabv3p_nas(image, class_num, arch)
else: else:
raise Exception( raise Exception("unknow model name, only support deeplabv3p")
"unknow model name, only support deeplabv3p"
)
return logits return logits
...@@ -156,8 +154,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None): ...@@ -156,8 +154,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None):
width = cfg.EVAL_CROP_SIZE[0] width = cfg.EVAL_CROP_SIZE[0]
height = cfg.EVAL_CROP_SIZE[1] height = cfg.EVAL_CROP_SIZE[1]
image_shape = [cfg.DATASET.DATA_DIM, height, width] image_shape = [-1, cfg.DATASET.DATA_DIM, height, width]
grt_shape = [1, height, width] grt_shape = [-1, 1, height, width]
class_num = cfg.DATASET.NUM_CLASSES class_num = cfg.DATASET.NUM_CLASSES
with fluid.program_guard(main_prog, start_prog): with fluid.program_guard(main_prog, start_prog):
...@@ -165,25 +163,22 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None): ...@@ -165,25 +163,22 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None):
# 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程 # 在导出模型的时候,增加图像标准化预处理,减小预测部署时图像的处理流程
# 预测部署时只须对输入图像增加batch_size维度即可 # 预测部署时只须对输入图像增加batch_size维度即可
if ModelPhase.is_predict(phase): if ModelPhase.is_predict(phase):
origin_image = fluid.layers.data( origin_image = fluid.data(
name='image', name='image',
shape=[-1, -1, -1, cfg.DATASET.DATA_DIM], shape=[-1, -1, -1, cfg.DATASET.DATA_DIM],
dtype='float32', dtype='float32')
append_batch_size=False)
image, valid_shape, origin_shape = export_preprocess( image, valid_shape, origin_shape = export_preprocess(
origin_image) origin_image)
else: else:
image = fluid.layers.data( image = fluid.data(
name='image', shape=image_shape, dtype='float32') name='image', shape=image_shape, dtype='float32')
label = fluid.layers.data( label = fluid.data(name='label', shape=grt_shape, dtype='int32')
name='label', shape=grt_shape, dtype='int32') mask = fluid.data(name='mask', shape=grt_shape, dtype='int32')
mask = fluid.layers.data(
name='mask', shape=grt_shape, dtype='int32')
# use PyReader when doing traning and evaluation # use DataLoader.from_generator when doing traning and evaluation
if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase): if ModelPhase.is_train(phase) or ModelPhase.is_eval(phase):
py_reader = fluid.io.PyReader( data_loader = fluid.io.DataLoader.from_generator(
feed_list=[image, label, mask], feed_list=[image, label, mask],
capacity=cfg.DATALOADER.BUF_SIZE, capacity=cfg.DATALOADER.BUF_SIZE,
iterable=False, iterable=False,
...@@ -217,7 +212,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None): ...@@ -217,7 +212,8 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None):
if "softmax_loss" in loss_type: if "softmax_loss" in loss_type:
weight = cfg.SOLVER.CROSS_ENTROPY_WEIGHT weight = cfg.SOLVER.CROSS_ENTROPY_WEIGHT
avg_loss_list.append( avg_loss_list.append(
multi_softmax_with_loss(logits, label, mask, class_num, weight)) multi_softmax_with_loss(logits, label, mask, class_num,
weight))
loss_valid = True loss_valid = True
valid_loss.append("softmax_loss") valid_loss.append("softmax_loss")
if "dice_loss" in loss_type: if "dice_loss" in loss_type:
...@@ -290,12 +286,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None): ...@@ -290,12 +286,12 @@ def build_model(main_prog, start_prog, phase=ModelPhase.TRAIN, arch=None):
return pred, logit return pred, logit
if ModelPhase.is_eval(phase): if ModelPhase.is_eval(phase):
return py_reader, avg_loss, pred, label, mask return data_loader, avg_loss, pred, label, mask
if ModelPhase.is_train(phase): if ModelPhase.is_train(phase):
optimizer = solver.Solver(main_prog, start_prog) optimizer = solver.Solver(main_prog, start_prog)
decayed_lr = optimizer.optimise(avg_loss) decayed_lr = optimizer.optimise(avg_loss)
return py_reader, avg_loss, decayed_lr, pred, label, mask return data_loader, avg_loss, decayed_lr, pred, label, mask
def to_int(string, dest="I"): def to_int(string, dest="I"):
......
...@@ -54,6 +54,7 @@ from paddleslim.analysis import flops ...@@ -54,6 +54,7 @@ from paddleslim.analysis import flops
from paddleslim.nas.sa_nas import SANAS from paddleslim.nas.sa_nas import SANAS
from paddleslim.nas import search_space from paddleslim.nas import search_space
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='PaddleSeg training') parser = argparse.ArgumentParser(description='PaddleSeg training')
parser.add_argument( parser.add_argument(
...@@ -269,21 +270,24 @@ def train(cfg): ...@@ -269,21 +270,24 @@ def train(cfg):
port = cfg.SLIM.NAS_PORT port = cfg.SLIM.NAS_PORT
server_address = (cfg.SLIM.NAS_ADDRESS, port) server_address = (cfg.SLIM.NAS_ADDRESS, port)
sa_nas = SANAS(config, server_addr=server_address, search_steps=cfg.SLIM.NAS_SEARCH_STEPS, sa_nas = SANAS(
is_server=cfg.SLIM.NAS_IS_SERVER) config,
server_addr=server_address,
search_steps=cfg.SLIM.NAS_SEARCH_STEPS,
is_server=cfg.SLIM.NAS_IS_SERVER)
for step in range(cfg.SLIM.NAS_SEARCH_STEPS): for step in range(cfg.SLIM.NAS_SEARCH_STEPS):
arch = sa_nas.next_archs()[0] arch = sa_nas.next_archs()[0]
start_prog = fluid.Program() start_prog = fluid.Program()
train_prog = fluid.Program() train_prog = fluid.Program()
py_reader, avg_loss, lr, pred, grts, masks = build_model( data_loader, avg_loss, lr, pred, grts, masks = build_model(
train_prog, start_prog, arch=arch, phase=ModelPhase.TRAIN) train_prog, start_prog, arch=arch, phase=ModelPhase.TRAIN)
cur_flops = flops(train_prog) cur_flops = flops(train_prog)
print('current step:', step, 'flops:', cur_flops) print('current step:', step, 'flops:', cur_flops)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -297,7 +301,8 @@ def train(cfg): ...@@ -297,7 +301,8 @@ def train(cfg):
build_strategy = fluid.BuildStrategy() build_strategy = fluid.BuildStrategy()
if cfg.NUM_TRAINERS > 1 and args.use_gpu: if cfg.NUM_TRAINERS > 1 and args.use_gpu:
dist_utils.prepare_for_multi_process(exe, build_strategy, train_prog) dist_utils.prepare_for_multi_process(exe, build_strategy,
train_prog)
exec_strategy.num_threads = 1 exec_strategy.num_threads = 1
if cfg.TRAIN.SYNC_BATCH_NORM and args.use_gpu: if cfg.TRAIN.SYNC_BATCH_NORM and args.use_gpu:
...@@ -309,10 +314,11 @@ def train(cfg): ...@@ -309,10 +314,11 @@ def train(cfg):
print_info( print_info(
"Sync BatchNorm strategy will not be effective if GPU device" "Sync BatchNorm strategy will not be effective if GPU device"
" count <= 1") " count <= 1")
compiled_train_prog = fluid.CompiledProgram(train_prog).with_data_parallel( compiled_train_prog = fluid.CompiledProgram(
loss_name=avg_loss.name, train_prog).with_data_parallel(
exec_strategy=exec_strategy, loss_name=avg_loss.name,
build_strategy=build_strategy) exec_strategy=exec_strategy,
build_strategy=build_strategy)
# Resume training # Resume training
begin_epoch = cfg.SOLVER.BEGIN_EPOCH begin_epoch = cfg.SOLVER.BEGIN_EPOCH
...@@ -353,13 +359,14 @@ def train(cfg): ...@@ -353,13 +359,14 @@ def train(cfg):
print_info( print_info(
"Parameter[{}] don't exist or shape does not match current network, skip" "Parameter[{}] don't exist or shape does not match current network, skip"
" to load it.".format(var.name)) " to load it.".format(var.name))
print_info("{}/{} pretrained parameters loaded successfully!".format( print_info(
len(load_vars), "{}/{} pretrained parameters loaded successfully!".format(
len(load_vars) + len(load_fail_vars))) len(load_vars),
len(load_vars) + len(load_fail_vars)))
else: else:
print_info( print_info(
'Pretrained model dir {} not exists, training from scratch...'. 'Pretrained model dir {} not exists, training from scratch...'.
format(cfg.TRAIN.PRETRAINED_MODEL_DIR)) format(cfg.TRAIN.PRETRAINED_MODEL_DIR))
fetch_list = [avg_loss.name, lr.name] fetch_list = [avg_loss.name, lr.name]
...@@ -374,8 +381,8 @@ def train(cfg): ...@@ -374,8 +381,8 @@ def train(cfg):
timer.start() timer.start()
if begin_epoch > cfg.SOLVER.NUM_EPOCHS: if begin_epoch > cfg.SOLVER.NUM_EPOCHS:
raise ValueError( raise ValueError(
("begin epoch[{}] is larger than cfg.SOLVER.NUM_EPOCHS[{}]").format( ("begin epoch[{}] is larger than cfg.SOLVER.NUM_EPOCHS[{}]"
begin_epoch, cfg.SOLVER.NUM_EPOCHS)) ).format(begin_epoch, cfg.SOLVER.NUM_EPOCHS))
if args.use_mpio: if args.use_mpio:
print_info("Use multiprocess reader") print_info("Use multiprocess reader")
...@@ -384,7 +391,7 @@ def train(cfg): ...@@ -384,7 +391,7 @@ def train(cfg):
best_miou = 0.0 best_miou = 0.0
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
loss, lr = exe.run( loss, lr = exe.run(
...@@ -398,21 +405,22 @@ def train(cfg): ...@@ -398,21 +405,22 @@ def train(cfg):
avg_loss /= args.log_steps avg_loss /= args.log_steps
speed = args.log_steps / timer.elapsed_time() speed = args.log_steps / timer.elapsed_time()
print(( print((
"epoch={} step={} lr={:.5f} loss={:.4f} step/sec={:.3f} | ETA {}" "epoch={} step={} lr={:.5f} loss={:.4f} step/sec={:.3f} | ETA {}"
).format(epoch, global_step, lr[0], avg_loss, speed, ).format(epoch, global_step, lr[0], avg_loss, speed,
calculate_eta(all_step - global_step, speed))) calculate_eta(all_step - global_step, speed)))
sys.stdout.flush() sys.stdout.flush()
avg_loss = 0.0 avg_loss = 0.0
timer.restart() timer.restart()
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
if epoch > cfg.SLIM.NAS_START_EVAL_EPOCH: if epoch > cfg.SLIM.NAS_START_EVAL_EPOCH:
ckpt_dir = save_checkpoint(exe, train_prog, '{}_tmp'.format(port)) ckpt_dir = save_checkpoint(exe, train_prog,
'{}_tmp'.format(port))
_, mean_iou, _, mean_acc = evaluate( _, mean_iou, _, mean_acc = evaluate(
cfg=cfg, cfg=cfg,
arch=arch, arch=arch,
...@@ -420,7 +428,8 @@ def train(cfg): ...@@ -420,7 +428,8 @@ def train(cfg):
use_gpu=args.use_gpu, use_gpu=args.use_gpu,
use_mpio=args.use_mpio) use_mpio=args.use_mpio)
if best_miou < mean_iou: if best_miou < mean_iou:
print('search step {}, epoch {} best iou {}'.format(step, epoch, mean_iou)) print('search step {}, epoch {} best iou {}'.format(
step, epoch, mean_iou))
best_miou = mean_iou best_miou = mean_iou
sa_nas.reward(float(best_miou)) sa_nas.reward(float(best_miou))
......
...@@ -46,7 +46,7 @@ SLIM.PRUNE_RATIOS '[0.1,0.1,0.1]' ...@@ -46,7 +46,7 @@ SLIM.PRUNE_RATIOS '[0.1,0.1,0.1]'
```shell ```shell
CUDA_VISIBLE_DEVICES=0 CUDA_VISIBLE_DEVICES=0
python -u ./slim/prune/eval_prune.py --cfg configs/cityscape_fast_scnn.yaml --use_gpu --use_mpio \ python -u ./slim/prune/eval_prune.py --cfg configs/cityscape_fast_scnn.yaml --use_gpu \
TEST.TEST_MODEL your_trained_model \ TEST.TEST_MODEL your_trained_model \
``` ```
......
...@@ -45,6 +45,7 @@ from metrics import ConfusionMatrix ...@@ -45,6 +45,7 @@ from metrics import ConfusionMatrix
from paddleslim.prune import load_model from paddleslim.prune import load_model
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='PaddleSeg model evalution') parser = argparse.ArgumentParser(description='PaddleSeg model evalution')
parser.add_argument( parser.add_argument(
...@@ -98,10 +99,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -98,10 +99,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
for b in data_gen: for b in data_gen:
yield b[0], b[1], b[2] yield b[0], b[1], b[2]
py_reader, avg_loss, pred, grts, masks = build_model( data_loader, avg_loss, pred, grts, masks = build_model(
test_prog, startup_prog, phase=ModelPhase.EVAL) test_prog, startup_prog, phase=ModelPhase.EVAL)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE) data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE)
# Get device environment # Get device environment
...@@ -134,7 +135,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -134,7 +135,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1 all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1
timer = Timer() timer = Timer()
timer.start() timer.start()
py_reader.start() data_loader.start()
while True: while True:
try: try:
step += 1 step += 1
......
...@@ -50,6 +50,7 @@ from utils import dist_utils ...@@ -50,6 +50,7 @@ from utils import dist_utils
from paddleslim.prune import Pruner, save_model from paddleslim.prune import Pruner, save_model
from paddleslim.analysis import flops from paddleslim.analysis import flops
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='PaddleSeg training') parser = argparse.ArgumentParser(description='PaddleSeg training')
parser.add_argument( parser.add_argument(
...@@ -181,10 +182,12 @@ def load_checkpoint(exe, program): ...@@ -181,10 +182,12 @@ def load_checkpoint(exe, program):
return begin_epoch return begin_epoch
def print_info(*msg): def print_info(*msg):
if cfg.TRAINER_ID == 0: if cfg.TRAINER_ID == 0:
print(*msg) print(*msg)
def train(cfg): def train(cfg):
startup_prog = fluid.Program() startup_prog = fluid.Program()
train_prog = fluid.Program() train_prog = fluid.Program()
...@@ -236,9 +239,9 @@ def train(cfg): ...@@ -236,9 +239,9 @@ def train(cfg):
batch_size_per_dev = cfg.BATCH_SIZE // dev_count batch_size_per_dev = cfg.BATCH_SIZE // dev_count
print_info("batch_size_per_dev: {}".format(batch_size_per_dev)) print_info("batch_size_per_dev: {}".format(batch_size_per_dev))
py_reader, avg_loss, lr, pred, grts, masks = build_model( data_loader, avg_loss, lr, pred, grts, masks = build_model(
train_prog, startup_prog, phase=ModelPhase.TRAIN) train_prog, startup_prog, phase=ModelPhase.TRAIN)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -261,8 +264,9 @@ def train(cfg): ...@@ -261,8 +264,9 @@ def train(cfg):
print_info("Sync BatchNorm strategy is effective.") print_info("Sync BatchNorm strategy is effective.")
build_strategy.sync_batch_norm = True build_strategy.sync_batch_norm = True
else: else:
print_info("Sync BatchNorm strategy will not be effective if GPU device" print_info(
" count <= 1") "Sync BatchNorm strategy will not be effective if GPU device"
" count <= 1")
pruned_params = cfg.SLIM.PRUNE_PARAMS.strip().split(',') pruned_params = cfg.SLIM.PRUNE_PARAMS.strip().split(',')
pruned_ratios = cfg.SLIM.PRUNE_RATIOS pruned_ratios = cfg.SLIM.PRUNE_RATIOS
...@@ -311,14 +315,16 @@ def train(cfg): ...@@ -311,14 +315,16 @@ def train(cfg):
for var in load_vars: for var in load_vars:
print_info("Parameter[{}] loaded sucessfully!".format(var.name)) print_info("Parameter[{}] loaded sucessfully!".format(var.name))
for var in load_fail_vars: for var in load_fail_vars:
print_info("Parameter[{}] don't exist or shape does not match current network, skip" print_info(
" to load it.".format(var.name)) "Parameter[{}] don't exist or shape does not match current network, skip"
" to load it.".format(var.name))
print_info("{}/{} pretrained parameters loaded successfully!".format( print_info("{}/{} pretrained parameters loaded successfully!".format(
len(load_vars), len(load_vars),
len(load_vars) + len(load_fail_vars))) len(load_vars) + len(load_fail_vars)))
else: else:
print_info('Pretrained model dir {} not exists, training from scratch...'. print_info(
format(cfg.TRAIN.PRETRAINED_MODEL_DIR)) 'Pretrained model dir {} not exists, training from scratch...'.
format(cfg.TRAIN.PRETRAINED_MODEL_DIR))
fetch_list = [avg_loss.name, lr.name] fetch_list = [avg_loss.name, lr.name]
if args.debug: if args.debug:
...@@ -371,7 +377,7 @@ def train(cfg): ...@@ -371,7 +377,7 @@ def train(cfg):
print_info("Use multi-thread reader") print_info("Use multi-thread reader")
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
if args.debug: if args.debug:
...@@ -441,7 +447,7 @@ def train(cfg): ...@@ -441,7 +447,7 @@ def train(cfg):
timer.restart() timer.restart()
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -477,6 +483,7 @@ def train(cfg): ...@@ -477,6 +483,7 @@ def train(cfg):
if cfg.TRAINER_ID == 0: if cfg.TRAINER_ID == 0:
save_prune_checkpoint(exe, train_prog, 'final') save_prune_checkpoint(exe, train_prog, 'final')
def main(args): def main(args):
if args.cfg_file is not None: if args.cfg_file is not None:
cfg.update_from_file(args.cfg_file) cfg.update_from_file(args.cfg_file)
......
...@@ -105,10 +105,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -105,10 +105,10 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
for b in data_gen: for b in data_gen:
yield b[0], b[1], b[2] yield b[0], b[1], b[2]
py_reader, avg_loss, pred, grts, masks = build_model( data_loader, avg_loss, pred, grts, masks = build_model(
test_prog, startup_prog, phase=ModelPhase.EVAL) test_prog, startup_prog, phase=ModelPhase.EVAL)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE) data_generator, drop_last=False, batch_size=cfg.BATCH_SIZE)
# Get device environment # Get device environment
...@@ -152,7 +152,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs): ...@@ -152,7 +152,7 @@ def evaluate(cfg, ckpt_dir=None, use_gpu=False, use_mpio=False, **kwargs):
all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1 all_step = cfg.DATASET.TEST_TOTAL_IMAGES // cfg.BATCH_SIZE + 1
timer = Timer() timer = Timer()
timer.start() timer.start()
py_reader.start() data_loader.start()
while True: while True:
try: try:
step += 1 step += 1
......
...@@ -157,9 +157,9 @@ def train_quant(cfg): ...@@ -157,9 +157,9 @@ def train_quant(cfg):
batch_size_per_dev = cfg.BATCH_SIZE // dev_count batch_size_per_dev = cfg.BATCH_SIZE // dev_count
print_info("batch_size_per_dev: {}".format(batch_size_per_dev)) print_info("batch_size_per_dev: {}".format(batch_size_per_dev))
py_reader, avg_loss, lr, pred, grts, masks = build_model( data_loader, avg_loss, lr, pred, grts, masks = build_model(
train_prog, startup_prog, phase=ModelPhase.TRAIN) train_prog, startup_prog, phase=ModelPhase.TRAIN)
py_reader.decorate_sample_generator( data_loader.set_sample_generator(
data_generator, batch_size=batch_size_per_dev, drop_last=drop_last) data_generator, batch_size=batch_size_per_dev, drop_last=drop_last)
exe = fluid.Executor(place) exe = fluid.Executor(place)
...@@ -274,7 +274,7 @@ def train_quant(cfg): ...@@ -274,7 +274,7 @@ def train_quant(cfg):
print_info("Use multi-thread reader") print_info("Use multi-thread reader")
for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1): for epoch in range(begin_epoch, cfg.SOLVER.NUM_EPOCHS + 1):
py_reader.start() data_loader.start()
while True: while True:
try: try:
if args.debug: if args.debug:
...@@ -326,7 +326,7 @@ def train_quant(cfg): ...@@ -326,7 +326,7 @@ def train_quant(cfg):
timer.restart() timer.restart()
except fluid.core.EOFException: except fluid.core.EOFException:
py_reader.reset() data_loader.reset()
break break
except Exception as e: except Exception as e:
print(e) print(e)
......
...@@ -114,6 +114,6 @@ python pdseg/eval.py --use_gpu --cfg ./configs/fast_scnn_pet.yaml ...@@ -114,6 +114,6 @@ python pdseg/eval.py --use_gpu --cfg ./configs/fast_scnn_pet.yaml
| ICNet/bn |(1024, 2048) |8.76ms| 0.6831 | | ICNet/bn |(1024, 2048) |8.76ms| 0.6831 |
| Fast-SCNN/bn | (1024, 2048) |6.28ms| 0.6964 | | Fast-SCNN/bn | (1024, 2048) |6.28ms| 0.6964 |
上述测试环境为v100. 测试使用paddle的推理接口[zero_copy](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_usage/deploy/inference/python_infer_cn.html#id8)的方式,模型输出是类别,即argmax后的值。 上述测试环境为v100. 测试使用paddle的推理接口[zero_copy](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/python_infer_cn.html#id8)的方式,模型输出是类别,即argmax后的值。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册