提交 50978b77 编写于 作者: H huangjun12

update bmn dygraph to paddle 2.0

上级 4d1187d5
...@@ -12,10 +12,11 @@ MODEL: ...@@ -12,10 +12,11 @@ MODEL:
TRAIN: TRAIN:
subset: "train" subset: "train"
epoch: 9 epoch: 9
batch_size: 4
num_threads: 8
use_gpu: True use_gpu: True
num_gpus: 4 num_gpus: 4
batch_size: 16
num_workers: 4
use_shuffle: True
learning_rate: 0.001 learning_rate: 0.001
learning_rate_decay: 0.1 learning_rate_decay: 0.1
lr_decay_iter: 4200 lr_decay_iter: 4200
...@@ -23,15 +24,14 @@ TRAIN: ...@@ -23,15 +24,14 @@ TRAIN:
VALID: VALID:
subset: "validation" subset: "validation"
batch_size: 4
num_threads: 8
use_gpu: True
num_gpus: 4 num_gpus: 4
batch_size: 16
num_workers: 4
TEST: TEST:
subset: "validation" subset: "validation"
batch_size: 1 batch_size: 1
num_threads: 1 num_workers: 4
snms_alpha: 0.001 snms_alpha: 0.001
snms_t1: 0.5 snms_t1: 0.5
snms_t2: 0.9 snms_t2: 0.9
...@@ -41,7 +41,7 @@ TEST: ...@@ -41,7 +41,7 @@ TEST:
INFER: INFER:
subset: "test" subset: "test"
batch_size: 1 batch_size: 1
num_threads: 1 num_workers: 4
snms_alpha: 0.4 snms_alpha: 0.4
snms_t1: 0.5 snms_t1: 0.5
snms_t2: 0.9 snms_t2: 0.9
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#limitations under the License. #limitations under the License.
import paddle import paddle
import paddle.fluid as fluid from paddle.io import DataLoader, DistributedBatchSampler
import numpy as np import numpy as np
import argparse import argparse
import pandas as pd import pandas as pd
...@@ -23,7 +23,7 @@ import ast ...@@ -23,7 +23,7 @@ import ast
import json import json
import logging import logging
from reader import BMNReader from reader import BmnDataset
from model import BMN, bmn_loss_func from model import BMN, bmn_loss_func
from bmn_utils import boundary_choose, bmn_post_processing from bmn_utils import boundary_choose, bmn_post_processing
from config_utils import * from config_utils import *
...@@ -129,25 +129,32 @@ def test_bmn(args): ...@@ -129,25 +129,32 @@ def test_bmn(args):
os.makedirs(test_config.TEST.result_path) os.makedirs(test_config.TEST.result_path)
if not args.use_gpu: if not args.use_gpu:
place = fluid.CPUPlace() place = paddle.CPUPlace()
else: else:
place = fluid.CUDAPlace(0) place = paddle.CUDAPlace(0)
with fluid.dygraph.guard(place): paddle.disable_static(place)
bmn = BMN(test_config) bmn = BMN(test_config)
# load checkpoint # load checkpoint
if args.weights: if args.weights:
assert os.path.exists(args.weights + '.pdparams' assert os.path.exists(
), "Given weight dir {} not exist.".format( args.weights +
args.weights) '.pdparams'), "Given weight dir {} not exist.".format(args.weights)
logger.info('load test weights from {}'.format(args.weights)) logger.info('load test weights from {}'.format(args.weights))
model_dict, _ = fluid.load_dygraph(args.weights) model_dict, _ = paddle.load(args.weights)
bmn.set_dict(model_dict) bmn.set_dict(model_dict)
reader = BMNReader(mode="test", cfg=test_config) eval_dataset = BmnDataset(test_config, 'test')
test_reader = reader.create_reader() eval_sampler = DistributedBatchSampler(
eval_dataset, batch_size=test_config.TEST.batch_size)
eval_loader = DataLoader(
eval_dataset,
batch_sampler=eval_sampler,
places=place,
num_workers=test_config.TEST.num_workers,
return_list=True)
aggr_loss = 0.0 aggr_loss = 0.0
aggr_tem_loss = 0.0 aggr_tem_loss = 0.0
...@@ -157,17 +164,12 @@ def test_bmn(args): ...@@ -157,17 +164,12 @@ def test_bmn(args):
video_dict, video_list = get_dataset_dict(test_config) video_dict, video_list = get_dataset_dict(test_config)
bmn.eval() bmn.eval()
for batch_id, data in enumerate(test_reader()): for batch_id, data in enumerate(eval_loader):
video_feat = np.array([item[0] for item in data]).astype(DATATYPE) x_data = paddle.to_tensor(data[0])
gt_iou_map = np.array([item[1] for item in data]).astype(DATATYPE) gt_iou_map = paddle.to_tensor(data[1])
gt_start = np.array([item[2] for item in data]).astype(DATATYPE) gt_start = paddle.to_tensor(data[2])
gt_end = np.array([item[3] for item in data]).astype(DATATYPE) gt_end = paddle.to_tensor(data[3])
video_idx = [item[4] for item in data][0] #batch_size=1 by default video_idx = data[4] #batch_size=1 by default
x_data = fluid.dygraph.base.to_variable(video_feat)
gt_iou_map = fluid.dygraph.base.to_variable(gt_iou_map)
gt_start = fluid.dygraph.base.to_variable(gt_start)
gt_end = fluid.dygraph.base.to_variable(gt_end)
gt_iou_map.stop_gradient = True gt_iou_map.stop_gradient = True
gt_start.stop_gradient = True gt_start.stop_gradient = True
gt_end.stop_gradient = True gt_end.stop_gradient = True
...@@ -187,8 +189,7 @@ def test_bmn(args): ...@@ -187,8 +189,7 @@ def test_bmn(args):
aggr_batch_size += 1 aggr_batch_size += 1
if batch_id % args.log_interval == 0: if batch_id % args.log_interval == 0:
logger.info("Processing................ batch {}".format( logger.info("Processing................ batch {}".format(batch_id))
batch_id))
gen_props( gen_props(
pred_bm, pred_bm,
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#limitations under the License. #limitations under the License.
import paddle import paddle
import paddle.fluid as fluid import paddle.nn.functional as F
from paddle.fluid import ParamAttr from paddle import ParamAttr
import numpy as np import numpy as np
import math import math
...@@ -24,7 +24,7 @@ DATATYPE = 'float32' ...@@ -24,7 +24,7 @@ DATATYPE = 'float32'
# Net # Net
class Conv1D(fluid.dygraph.Layer): class Conv1D(paddle.nn.Layer):
def __init__(self, def __init__(self,
prefix, prefix,
num_channels=256, num_channels=256,
...@@ -38,32 +38,36 @@ class Conv1D(fluid.dygraph.Layer): ...@@ -38,32 +38,36 @@ class Conv1D(fluid.dygraph.Layer):
k = 1. / math.sqrt(fan_in) k = 1. / math.sqrt(fan_in)
param_attr = ParamAttr( param_attr = ParamAttr(
name=prefix + "_w", name=prefix + "_w",
initializer=fluid.initializer.Uniform( initializer=paddle.nn.initializer.Uniform(
low=-k, high=k)) low=-k, high=k))
bias_attr = ParamAttr( bias_attr = ParamAttr(
name=prefix + "_b", name=prefix + "_b",
initializer=fluid.initializer.Uniform( initializer=paddle.nn.initializer.Uniform(
low=-k, high=k)) low=-k, high=k))
self._conv2d = fluid.dygraph.Conv2D( self._conv2d = paddle.nn.Conv2d(
num_channels=num_channels, in_channels=num_channels,
num_filters=num_filters, out_channels=num_filters,
filter_size=(1, size_k), kernel_size=(1, size_k),
stride=1, stride=1,
padding=(0, padding), padding=(0, padding),
groups=groups, groups=groups,
act=act, weight_attr=param_attr,
param_attr=param_attr,
bias_attr=bias_attr) bias_attr=bias_attr)
if act == "relu":
self._act = paddle.nn.ReLU()
elif act == "sigmoid":
self._act = paddle.nn.Sigmoid()
def forward(self, x): def forward(self, x):
x = fluid.layers.unsqueeze(input=x, axes=[2]) x = paddle.unsqueeze(x, axis=[2])
x = self._conv2d(x) x = self._conv2d(x)
x = fluid.layers.squeeze(input=x, axes=[2]) x = self._act(x)
x = paddle.squeeze(x, axis=[2])
return x return x
class BMN(fluid.dygraph.Layer): class BMN(paddle.nn.Layer):
def __init__(self, cfg): def __init__(self, cfg):
super(BMN, self).__init__() super(BMN, self).__init__()
...@@ -127,55 +131,58 @@ class BMN(fluid.dygraph.Layer): ...@@ -127,55 +131,58 @@ class BMN(fluid.dygraph.Layer):
sample_mask = get_interp1d_mask(self.tscale, self.dscale, sample_mask = get_interp1d_mask(self.tscale, self.dscale,
self.prop_boundary_ratio, self.prop_boundary_ratio,
self.num_sample, self.num_sample_perbin) self.num_sample, self.num_sample_perbin)
self.sample_mask = fluid.dygraph.base.to_variable(sample_mask) self.sample_mask = paddle.to_tensor(sample_mask)
self.sample_mask.stop_gradient = True self.sample_mask.stop_gradient = True
self.p_conv3d1 = fluid.dygraph.Conv3D( self.p_conv3d1 = paddle.nn.Conv3d(
num_channels=128, in_channels=128,
num_filters=self.hidden_dim_3d, out_channels=self.hidden_dim_3d,
filter_size=(self.num_sample, 1, 1), kernel_size=(self.num_sample, 1, 1),
stride=(self.num_sample, 1, 1), stride=(self.num_sample, 1, 1),
padding=0, padding=0,
act="relu", weight_attr=ParamAttr(name="PEM_3d1_w"),
param_attr=ParamAttr(name="PEM_3d1_w"),
bias_attr=ParamAttr(name="PEM_3d1_b")) bias_attr=ParamAttr(name="PEM_3d1_b"))
self.p_conv3d1_act = paddle.nn.ReLU()
self.p_conv2d1 = fluid.dygraph.Conv2D( self.p_conv2d1 = paddle.nn.Conv2d(
num_channels=512, in_channels=512,
num_filters=self.hidden_dim_2d, out_channels=self.hidden_dim_2d,
filter_size=1, kernel_size=1,
stride=1, stride=1,
padding=0, padding=0,
act="relu", weight_attr=ParamAttr(name="PEM_2d1_w"),
param_attr=ParamAttr(name="PEM_2d1_w"),
bias_attr=ParamAttr(name="PEM_2d1_b")) bias_attr=ParamAttr(name="PEM_2d1_b"))
self.p_conv2d2 = fluid.dygraph.Conv2D( self.p_conv2d1_act = paddle.nn.ReLU()
num_channels=128,
num_filters=self.hidden_dim_2d, self.p_conv2d2 = paddle.nn.Conv2d(
filter_size=3, in_channels=128,
out_channels=self.hidden_dim_2d,
kernel_size=3,
stride=1, stride=1,
padding=1, padding=1,
act="relu", weight_attr=ParamAttr(name="PEM_2d2_w"),
param_attr=ParamAttr(name="PEM_2d2_w"),
bias_attr=ParamAttr(name="PEM_2d2_b")) bias_attr=ParamAttr(name="PEM_2d2_b"))
self.p_conv2d3 = fluid.dygraph.Conv2D( self.p_conv2d2_act = paddle.nn.ReLU()
num_channels=128,
num_filters=self.hidden_dim_2d, self.p_conv2d3 = paddle.nn.Conv2d(
filter_size=3, in_channels=128,
out_channels=self.hidden_dim_2d,
kernel_size=3,
stride=1, stride=1,
padding=1, padding=1,
act="relu", weight_attr=ParamAttr(name="PEM_2d3_w"),
param_attr=ParamAttr(name="PEM_2d3_w"),
bias_attr=ParamAttr(name="PEM_2d3_b")) bias_attr=ParamAttr(name="PEM_2d3_b"))
self.p_conv2d4 = fluid.dygraph.Conv2D( self.p_conv2d3_act = paddle.nn.ReLU()
num_channels=128,
num_filters=2, self.p_conv2d4 = paddle.nn.Conv2d(
filter_size=1, in_channels=128,
out_channels=2,
kernel_size=1,
stride=1, stride=1,
padding=0, padding=0,
act="sigmoid", weight_attr=ParamAttr(name="PEM_2d4_w"),
param_attr=ParamAttr(name="PEM_2d4_w"),
bias_attr=ParamAttr(name="PEM_2d4_b")) bias_attr=ParamAttr(name="PEM_2d4_b"))
self.p_conv2d4_act = paddle.nn.Sigmoid()
def forward(self, x): def forward(self, x):
#Base Module #Base Module
...@@ -185,24 +192,28 @@ class BMN(fluid.dygraph.Layer): ...@@ -185,24 +192,28 @@ class BMN(fluid.dygraph.Layer):
#TEM #TEM
xs = self.ts_conv1(x) xs = self.ts_conv1(x)
xs = self.ts_conv2(xs) xs = self.ts_conv2(xs)
xs = fluid.layers.squeeze(xs, axes=[1]) xs = paddle.squeeze(xs, axis=[1])
xe = self.te_conv1(x) xe = self.te_conv1(x)
xe = self.te_conv2(xe) xe = self.te_conv2(xe)
xe = fluid.layers.squeeze(xe, axes=[1]) xe = paddle.squeeze(xe, axis=[1])
#PEM #PEM
xp = self.p_conv1(x) xp = self.p_conv1(x)
#BM layer #BM layer
xp = fluid.layers.matmul(xp, self.sample_mask) xp = paddle.matmul(xp, self.sample_mask)
xp = fluid.layers.reshape( xp = paddle.reshape(xp, shape=[0, 0, -1, self.dscale, self.tscale])
xp, shape=[0, 0, -1, self.dscale, self.tscale])
xp = self.p_conv3d1(xp) xp = self.p_conv3d1(xp)
xp = fluid.layers.squeeze(xp, axes=[2]) xp = self.p_conv3d1_act(xp)
xp = paddle.squeeze(xp, axis=[2])
xp = self.p_conv2d1(xp) xp = self.p_conv2d1(xp)
xp = self.p_conv2d1_act(xp)
xp = self.p_conv2d2(xp) xp = self.p_conv2d2(xp)
xp = self.p_conv2d2_act(xp)
xp = self.p_conv2d3(xp) xp = self.p_conv2d3(xp)
xp = self.p_conv2d3_act(xp)
xp = self.p_conv2d4(xp) xp = self.p_conv2d4(xp)
xp = self.p_conv2d4_act(xp)
return xp, xs, xe return xp, xs, xe
...@@ -217,35 +228,28 @@ def bmn_loss_func(pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end, ...@@ -217,35 +228,28 @@ def bmn_loss_func(pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end,
] + [0 for i in range(idx)] ] + [0 for i in range(idx)]
bm_mask.append(mask_vector) bm_mask.append(mask_vector)
bm_mask = np.array(bm_mask, dtype=np.float32) bm_mask = np.array(bm_mask, dtype=np.float32)
self_bm_mask = fluid.layers.create_global_var( bm_mask = paddle.to_tensor(bm_mask)
shape=[dscale, tscale], value=0, dtype=DATATYPE, persistable=True) bm_mask.stop_gradient = True
fluid.layers.assign(bm_mask, self_bm_mask) return bm_mask
self_bm_mask.stop_gradient = True
return self_bm_mask
def tem_loss_func(pred_start, pred_end, gt_start, gt_end): def tem_loss_func(pred_start, pred_end, gt_start, gt_end):
def bi_loss(pred_score, gt_label): def bi_loss(pred_score, gt_label):
pred_score = fluid.layers.reshape( pred_score = paddle.reshape(x=pred_score, shape=[-1])
x=pred_score, shape=[-1], inplace=False) gt_label = paddle.reshape(x=gt_label, shape=[-1])
gt_label = fluid.layers.reshape(
x=gt_label, shape=[-1], inplace=False)
gt_label.stop_gradient = True gt_label.stop_gradient = True
pmask = fluid.layers.cast(x=(gt_label > 0.5), dtype=DATATYPE) pmask = paddle.cast(x=(gt_label > 0.5), dtype=DATATYPE)
num_entries = fluid.layers.cast( num_entries = paddle.cast(paddle.shape(pmask), dtype=DATATYPE)
fluid.layers.shape(pmask), dtype=DATATYPE) num_positive = paddle.cast(paddle.reduce_sum(pmask), dtype=DATATYPE)
num_positive = fluid.layers.cast(
fluid.layers.reduce_sum(pmask), dtype=DATATYPE)
ratio = num_entries / num_positive ratio = num_entries / num_positive
coef_0 = 0.5 * ratio / (ratio - 1) coef_0 = 0.5 * ratio / (ratio - 1)
coef_1 = 0.5 * ratio coef_1 = 0.5 * ratio
epsilon = 0.000001 epsilon = 0.000001
temp = fluid.layers.log(pred_score + epsilon) temp = paddle.log(pred_score + epsilon)
loss_pos = fluid.layers.elementwise_mul( loss_pos = paddle.multiply(paddle.log(pred_score + epsilon), pmask)
fluid.layers.log(pred_score + epsilon), pmask) loss_pos = coef_1 * paddle.reduce_mean(loss_pos)
loss_pos = coef_1 * fluid.layers.reduce_mean(loss_pos) loss_neg = paddle.multiply(
loss_neg = fluid.layers.elementwise_mul( paddle.log(1.0 - pred_score + epsilon), (1.0 - pmask))
fluid.layers.log(1.0 - pred_score + epsilon), (1.0 - pmask)) loss_neg = coef_0 * paddle.reduce_mean(loss_neg)
loss_neg = coef_0 * fluid.layers.reduce_mean(loss_neg)
loss = -1 * (loss_pos + loss_neg) loss = -1 * (loss_pos + loss_neg)
return loss return loss
...@@ -256,77 +260,72 @@ def bmn_loss_func(pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end, ...@@ -256,77 +260,72 @@ def bmn_loss_func(pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end,
def pem_reg_loss_func(pred_score, gt_iou_map, mask): def pem_reg_loss_func(pred_score, gt_iou_map, mask):
gt_iou_map = fluid.layers.elementwise_mul(gt_iou_map, mask) gt_iou_map = paddle.multiply(gt_iou_map, mask)
u_hmask = fluid.layers.cast(x=gt_iou_map > 0.7, dtype=DATATYPE) u_hmask = paddle.cast(x=gt_iou_map > 0.7, dtype=DATATYPE)
u_mmask = fluid.layers.logical_and(gt_iou_map <= 0.7, gt_iou_map > 0.3) u_mmask = paddle.logical_and(gt_iou_map <= 0.7, gt_iou_map > 0.3)
u_mmask = fluid.layers.cast(x=u_mmask, dtype=DATATYPE) u_mmask = paddle.cast(x=u_mmask, dtype=DATATYPE)
u_lmask = fluid.layers.logical_and(gt_iou_map <= 0.3, gt_iou_map >= 0.) u_lmask = paddle.logical_and(gt_iou_map <= 0.3, gt_iou_map >= 0.)
u_lmask = fluid.layers.cast(x=u_lmask, dtype=DATATYPE) u_lmask = paddle.cast(x=u_lmask, dtype=DATATYPE)
u_lmask = fluid.layers.elementwise_mul(u_lmask, mask) u_lmask = paddle.multiply(u_lmask, mask)
num_h = fluid.layers.cast( num_h = paddle.cast(paddle.reduce_sum(u_hmask), dtype=DATATYPE)
fluid.layers.reduce_sum(u_hmask), dtype=DATATYPE) num_m = paddle.cast(paddle.reduce_sum(u_mmask), dtype=DATATYPE)
num_m = fluid.layers.cast( num_l = paddle.cast(paddle.reduce_sum(u_lmask), dtype=DATATYPE)
fluid.layers.reduce_sum(u_mmask), dtype=DATATYPE)
num_l = fluid.layers.cast(
fluid.layers.reduce_sum(u_lmask), dtype=DATATYPE)
r_m = num_h / num_m r_m = num_h / num_m
u_smmask = fluid.layers.uniform_random( u_smmask = paddle.uniform(
shape=[gt_iou_map.shape[1], gt_iou_map.shape[2]], shape=[gt_iou_map.shape[1], gt_iou_map.shape[2]],
dtype=DATATYPE, dtype=DATATYPE,
min=0.0, min=0.0,
max=1.0) max=1.0)
u_smmask = fluid.layers.elementwise_mul(u_mmask, u_smmask) u_smmask = paddle.multiply(u_mmask, u_smmask)
u_smmask = fluid.layers.cast(x=(u_smmask > (1. - r_m)), dtype=DATATYPE) u_smmask = paddle.cast(x=(u_smmask > (1. - r_m)), dtype=DATATYPE)
r_l = num_h / num_l r_l = num_h / num_l
u_slmask = fluid.layers.uniform_random( u_slmask = paddle.uniform(
shape=[gt_iou_map.shape[1], gt_iou_map.shape[2]], shape=[gt_iou_map.shape[1], gt_iou_map.shape[2]],
dtype=DATATYPE, dtype=DATATYPE,
min=0.0, min=0.0,
max=1.0) max=1.0)
u_slmask = fluid.layers.elementwise_mul(u_lmask, u_slmask) u_slmask = paddle.multiply(u_lmask, u_slmask)
u_slmask = fluid.layers.cast(x=(u_slmask > (1. - r_l)), dtype=DATATYPE) u_slmask = paddle.cast(x=(u_slmask > (1. - r_l)), dtype=DATATYPE)
weights = u_hmask + u_smmask + u_slmask weights = u_hmask + u_smmask + u_slmask
weights.stop_gradient = True weights.stop_gradient = True
loss = fluid.layers.square_error_cost(pred_score, gt_iou_map) loss = F.square_error_cost(pred_score, gt_iou_map)
loss = fluid.layers.elementwise_mul(loss, weights) loss = paddle.multiply(loss, weights)
loss = 0.5 * fluid.layers.reduce_sum(loss) / fluid.layers.reduce_sum( loss = 0.5 * paddle.reduce_sum(loss) / paddle.reduce_sum(weights)
weights)
return loss return loss
def pem_cls_loss_func(pred_score, gt_iou_map, mask): def pem_cls_loss_func(pred_score, gt_iou_map, mask):
gt_iou_map = fluid.layers.elementwise_mul(gt_iou_map, mask) gt_iou_map = paddle.multiply(gt_iou_map, mask)
gt_iou_map.stop_gradient = True gt_iou_map.stop_gradient = True
pmask = fluid.layers.cast(x=(gt_iou_map > 0.9), dtype=DATATYPE) pmask = paddle.cast(x=(gt_iou_map > 0.9), dtype=DATATYPE)
nmask = fluid.layers.cast(x=(gt_iou_map <= 0.9), dtype=DATATYPE) nmask = paddle.cast(x=(gt_iou_map <= 0.9), dtype=DATATYPE)
nmask = fluid.layers.elementwise_mul(nmask, mask) nmask = paddle.multiply(nmask, mask)
num_positive = fluid.layers.reduce_sum(pmask) num_positive = paddle.reduce_sum(pmask)
num_entries = num_positive + fluid.layers.reduce_sum(nmask) num_entries = num_positive + paddle.reduce_sum(nmask)
ratio = num_entries / num_positive ratio = num_entries / num_positive
coef_0 = 0.5 * ratio / (ratio - 1) coef_0 = 0.5 * ratio / (ratio - 1)
coef_1 = 0.5 * ratio coef_1 = 0.5 * ratio
epsilon = 0.000001 epsilon = 0.000001
loss_pos = fluid.layers.elementwise_mul( loss_pos = paddle.multiply(paddle.log(pred_score + epsilon), pmask)
fluid.layers.log(pred_score + epsilon), pmask) loss_pos = coef_1 * paddle.reduce_sum(loss_pos)
loss_pos = coef_1 * fluid.layers.reduce_sum(loss_pos) loss_neg = paddle.multiply(
loss_neg = fluid.layers.elementwise_mul( paddle.log(1.0 - pred_score + epsilon), nmask)
fluid.layers.log(1.0 - pred_score + epsilon), nmask) loss_neg = coef_0 * paddle.reduce_sum(loss_neg)
loss_neg = coef_0 * fluid.layers.reduce_sum(loss_neg)
loss = -1 * (loss_pos + loss_neg) / num_entries loss = -1 * (loss_pos + loss_neg) / num_entries
return loss return loss
pred_bm_reg = fluid.layers.squeeze( pred_bm_reg = paddle.squeeze(
fluid.layers.slice( paddle.slice(
pred_bm, axes=[1], starts=[0], ends=[1]), axes=[1]) pred_bm, axes=[1], starts=[0], ends=[1]), axis=[1])
pred_bm_cls = fluid.layers.squeeze( pred_bm_cls = paddle.squeeze(
fluid.layers.slice( paddle.slice(
pred_bm, axes=[1], starts=[1], ends=[2]), axes=[1]) pred_bm, axes=[1], starts=[1], ends=[2]), axis=[1])
bm_mask = _get_mask(cfg) bm_mask = _get_mask(cfg)
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#limitations under the License. #limitations under the License.
import paddle import paddle
import paddle.fluid as fluid from paddle.io import DataLoader, DistributedBatchSampler
import numpy as np import numpy as np
import argparse import argparse
import sys import sys
...@@ -23,7 +23,7 @@ import json ...@@ -23,7 +23,7 @@ import json
from model import BMN from model import BMN
from eval import gen_props from eval import gen_props
from reader import BMNReader from reader import BmnDataset
from bmn_utils import bmn_post_processing from bmn_utils import bmn_post_processing
from config_utils import * from config_utils import *
...@@ -93,30 +93,37 @@ def infer_bmn(args): ...@@ -93,30 +93,37 @@ def infer_bmn(args):
os.makedirs(infer_config.INFER.output_path) os.makedirs(infer_config.INFER.output_path)
if not os.path.isdir(infer_config.INFER.result_path): if not os.path.isdir(infer_config.INFER.result_path):
os.makedirs(infer_config.INFER.result_path) os.makedirs(infer_config.INFER.result_path)
place = fluid.CUDAPlace(0)
with fluid.dygraph.guard(place): place = paddle.CUDAPlace(0)
paddle.disable_static(place)
bmn = BMN(infer_config) bmn = BMN(infer_config)
# load checkpoint # load checkpoint
if args.weights: if args.weights:
assert os.path.exists(args.weights + ".pdparams" assert os.path.exists(
), "Given weight dir {} not exist.".format( args.weights +
args.weights) ".pdparams"), "Given weight dir {} not exist.".format(args.weights)
logger.info('load test weights from {}'.format(args.weights)) logger.info('load test weights from {}'.format(args.weights))
model_dict, _ = fluid.load_dygraph(args.weights) model_dict, _ = paddle.load(args.weights)
bmn.set_dict(model_dict) bmn.set_dict(model_dict)
reader = BMNReader(mode="infer", cfg=infer_config) infer_dataset = BmnDataset(infer_config, 'infer')
infer_reader = reader.create_reader() infer_sampler = DistributedBatchSampler(
infer_dataset, batch_size=infer_config.INFER.batch_size)
infer_loader = DataLoader(
infer_dataset,
batch_sampler=infer_sampler,
places=place,
num_workers=infer_config.INFER.num_workers,
return_list=True)
video_dict, video_list = get_dataset_dict(infer_config) video_dict, video_list = get_dataset_dict(infer_config)
bmn.eval() bmn.eval()
for batch_id, data in enumerate(infer_reader()): for batch_id, data in enumerate(infer_loader):
video_feat = np.array([item[0] for item in data]).astype(DATATYPE) x_data = paddle.to_tensor(data[0])
video_idx = [item[1] for item in data][0] #batch_size=1 by default video_idx = data[1] #batch_size=1 by default
x_data = fluid.dygraph.base.to_variable(video_feat)
pred_bm, pred_start, pred_end = bmn(x_data) pred_bm, pred_start, pred_end = bmn(x_data)
......
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
# #
#Licensed under the Apache License, Version 2.0 (the "License"); #Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License. #you may not use this file except in compliance with the License.
...@@ -14,37 +14,50 @@ ...@@ -14,37 +14,50 @@
import paddle import paddle
import numpy as np import numpy as np
import random
import json import json
import multiprocessing
import functools
import logging import logging
import platform
import os import os
import sys
from paddle.io import Dataset, DataLoader, DistributedBatchSampler
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from config_utils import *
from bmn_utils import iou_with_anchors, ioa_with_anchors from bmn_utils import iou_with_anchors, ioa_with_anchors
DATATYPE = "float32"
class BMNReader(): class BmnDataset(Dataset):
def __init__(self, mode, cfg): def __init__(self, cfg, mode):
self.mode = mode self.mode = mode
self.tscale = cfg.MODEL.tscale # 100 self.tscale = cfg.MODEL.tscale # 100
self.dscale = cfg.MODEL.dscale # 100 self.dscale = cfg.MODEL.dscale # 100
self.anno_file = cfg.MODEL.anno_file self.anno_file = cfg.MODEL.anno_file
self.feat_path = cfg.MODEL.feat_path
self.file_list = cfg.INFER.filelist self.file_list = cfg.INFER.filelist
self.subset = cfg[mode.upper()]['subset'] self.subset = cfg[mode.upper()]['subset']
self.tgap = 1. / self.tscale self.tgap = 1. / self.tscale
self.feat_path = cfg.MODEL.feat_path
self.get_dataset_dict() self.get_dataset_dict()
self.get_match_map() self.get_match_map()
self.batch_size = cfg[mode.upper()]['batch_size'] def __getitem__(self, index):
self.num_threads = cfg[mode.upper()]['num_threads'] video_name = self.video_list[index]
if (mode == 'test') or (mode == 'infer'): video_idx = np.array(self.video_list.index(video_name)).astype('int64')
self.num_threads = 1 # set num_threads as 1 for test and infer video_feat = self.load_file(video_name)
if self.mode == 'infer':
return video_feat, video_idx
else:
gt_iou_map, gt_start, gt_end = self.get_video_label(video_name)
if self.mode == 'train' or self.mode == 'valid':
return video_feat, gt_iou_map, gt_start, gt_end
elif self.mode == 'test':
return video_feat, gt_iou_map, gt_start, gt_end, video_idx
def __len__(self):
return len(self.video_list)
def get_dataset_dict(self): def get_dataset_dict(self):
assert (os.path.exists(self.feat_path)), "Input feature path not exists" assert (os.path.exists(self.feat_path)), "Input feature path not exists"
...@@ -128,7 +141,8 @@ class BMNReader(): ...@@ -128,7 +141,8 @@ class BMNReader():
gt_start = np.array(match_score_start) gt_start = np.array(match_score_start)
gt_end = np.array(match_score_end) gt_end = np.array(match_score_end)
return gt_iou_map, gt_start, gt_end return gt_iou_map.astype(DATATYPE), gt_start.astype(
DATATYPE), gt_end.astype(DATATYPE)
def load_file(self, video_name): def load_file(self, video_name):
file_name = video_name + ".npy" file_name = video_name + ".npy"
...@@ -137,158 +151,3 @@ class BMNReader(): ...@@ -137,158 +151,3 @@ class BMNReader():
video_feat = video_feat.T video_feat = video_feat.T
video_feat = video_feat.astype("float32") video_feat = video_feat.astype("float32")
return video_feat return video_feat
def create_reader(self):
"""reader creator for bmn model"""
if self.mode == 'infer':
return self.make_infer_reader()
if self.num_threads == 1:
return self.make_reader()
else:
sysstr = platform.system()
if sysstr == 'Windows':
return self.make_multithread_reader()
else:
return self.make_multiprocess_reader()
def make_infer_reader(self):
"""reader for inference"""
def reader():
batch_out = []
for video_name in self.video_list:
video_idx = self.video_list.index(video_name)
video_feat = self.load_file(video_name)
batch_out.append((video_feat, video_idx))
if len(batch_out) == self.batch_size:
yield batch_out
batch_out = []
return reader
def make_reader(self):
"""single process reader"""
def reader():
video_list = self.video_list
if self.mode == 'train':
random.shuffle(video_list)
batch_out = []
for video_name in video_list:
video_idx = video_list.index(video_name)
video_feat = self.load_file(video_name)
gt_iou_map, gt_start, gt_end = self.get_video_label(video_name)
if self.mode == 'train' or self.mode == 'valid':
batch_out.append((video_feat, gt_iou_map, gt_start, gt_end))
elif self.mode == 'test':
batch_out.append(
(video_feat, gt_iou_map, gt_start, gt_end, video_idx))
else:
raise NotImplementedError('mode {} not implemented'.format(
self.mode))
if len(batch_out) == self.batch_size:
yield batch_out
batch_out = []
return reader
def make_multithread_reader(self):
def reader():
if self.mode == 'train':
random.shuffle(self.video_list)
for video_name in self.video_list:
video_idx = self.video_list.index(video_name)
yield [video_name, video_idx]
def process_data(sample, mode):
video_name = sample[0]
video_idx = sample[1]
video_feat = self.load_file(video_name)
gt_iou_map, gt_start, gt_end = self.get_video_label(video_name)
if mode == 'train' or mode == 'valid':
return (video_feat, gt_iou_map, gt_start, gt_end)
elif mode == 'test':
return (video_feat, gt_iou_map, gt_start, gt_end, video_idx)
else:
raise NotImplementedError('mode {} not implemented'.format(
mode))
mapper = functools.partial(process_data, mode=self.mode)
def batch_reader():
xreader = paddle.reader.xmap_readers(mapper, reader,
self.num_threads, 1024)
batch = []
for item in xreader():
batch.append(item)
if len(batch) == self.batch_size:
yield batch
batch = []
return batch_reader
def make_multiprocess_reader(self):
"""multiprocess reader"""
def read_into_queue(video_list, queue):
batch_out = []
for video_name in video_list:
video_idx = video_list.index(video_name)
video_feat = self.load_file(video_name)
gt_iou_map, gt_start, gt_end = self.get_video_label(video_name)
if self.mode == 'train' or self.mode == 'valid':
batch_out.append((video_feat, gt_iou_map, gt_start, gt_end))
elif self.mode == 'test':
batch_out.append(
(video_feat, gt_iou_map, gt_start, gt_end, video_idx))
else:
raise NotImplementedError('mode {} not implemented'.format(
self.mode))
if len(batch_out) == self.batch_size:
queue.put(batch_out)
batch_out = []
queue.put(None)
def queue_reader():
video_list = self.video_list
if self.mode == 'train':
random.shuffle(video_list)
n = self.num_threads
queue_size = 20
reader_lists = [None] * n
file_num = int(len(video_list) // n)
for i in range(n):
if i < len(reader_lists) - 1:
tmp_list = video_list[i * file_num:(i + 1) * file_num]
else:
tmp_list = video_list[i * file_num:]
reader_lists[i] = tmp_list
manager = multiprocessing.Manager()
queue = manager.Queue(queue_size)
p_list = [None] * len(reader_lists)
for i in range(len(reader_lists)):
reader_list = reader_lists[i]
p_list[i] = multiprocessing.Process(
target=read_into_queue, args=(reader_list, queue))
p_list[i].start()
reader_num = len(reader_lists)
finish_num = 0
while finish_num < reader_num:
sample = queue.get()
if sample is None:
finish_num += 1
else:
yield sample
for i in range(len(p_list)):
if p_list[i].is_alive():
p_list[i].join()
return queue_reader
export CUDA_VISIBLE_DEVICES=0,1,2,3 export CUDA_VISIBLE_DEVICES=0,1,2,3
python -m paddle.distributed.launch \
--selected_gpus=0,1,2,3 \ start_time=$(date +%s)
--log_dir ./mylog \
train.py --use_data_parallel True python3 train.py --use_data_parallel=1
end_time=$(date +%s)
cost_time=$[ $end_time-$start_time ]
echo "4 card bs=16 9 epoch training time is $(($cost_time/60))min $(($cost_time%60))s"
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
#limitations under the License. #limitations under the License.
import paddle import paddle
import paddle.fluid as fluid from paddle.io import DataLoader, DistributedBatchSampler
import paddle.distributed as dist
import numpy as np import numpy as np
import argparse import argparse
import ast import ast
...@@ -22,7 +23,7 @@ import sys ...@@ -22,7 +23,7 @@ import sys
import os import os
from model import BMN, bmn_loss_func from model import BMN, bmn_loss_func
from reader import BMNReader from reader import BmnDataset
from config_utils import * from config_utils import *
DATATYPE = 'float32' DATATYPE = 'float32'
...@@ -98,29 +99,22 @@ def optimizer(cfg, parameter_list): ...@@ -98,29 +99,22 @@ def optimizer(cfg, parameter_list):
lr_decay = cfg.TRAIN.learning_rate_decay lr_decay = cfg.TRAIN.learning_rate_decay
l2_weight_decay = cfg.TRAIN.l2_weight_decay l2_weight_decay = cfg.TRAIN.l2_weight_decay
lr = [base_lr, base_lr * lr_decay] lr = [base_lr, base_lr * lr_decay]
optimizer = fluid.optimizer.Adam( scheduler = paddle.optimizer.lr_scheduler.PiecewiseLR(
fluid.layers.piecewise_decay( boundaries=bd, values=lr)
boundaries=bd, values=lr), optimizer = paddle.optimizer.Adam(
parameter_list=parameter_list, learning_rate=scheduler,
regularization=fluid.regularizer.L2DecayRegularizer( parameters=parameter_list,
regularization_coeff=l2_weight_decay)) weight_decay=l2_weight_decay)
return optimizer return optimizer
# Validation # Validation
def val_bmn(model, config, args): def val_bmn(model, val_loader, config, args):
reader = BMNReader(mode="valid", cfg=config) for batch_id, data in enumerate(val_loader):
val_reader = reader.create_reader() x_data = paddle.to_tensor(data[0])
for batch_id, data in enumerate(val_reader()): gt_iou_map = paddle.to_tensor(data[1])
video_feat = np.array([item[0] for item in data]).astype(DATATYPE) gt_start = paddle.to_tensor(data[2])
gt_iou_map = np.array([item[1] for item in data]).astype(DATATYPE) gt_end = paddle.to_tensor(data[3])
gt_start = np.array([item[2] for item in data]).astype(DATATYPE)
gt_end = np.array([item[3] for item in data]).astype(DATATYPE)
x_data = fluid.dygraph.base.to_variable(video_feat)
gt_iou_map = fluid.dygraph.base.to_variable(gt_iou_map)
gt_start = fluid.dygraph.base.to_variable(gt_start)
gt_end = fluid.dygraph.base.to_variable(gt_end)
gt_iou_map.stop_gradient = True gt_iou_map.stop_gradient = True
gt_start.stop_gradient = True gt_start.stop_gradient = True
gt_end.stop_gradient = True gt_end.stop_gradient = True
...@@ -129,7 +123,7 @@ def val_bmn(model, config, args): ...@@ -129,7 +123,7 @@ def val_bmn(model, config, args):
loss, tem_loss, pem_reg_loss, pem_cls_loss = bmn_loss_func( loss, tem_loss, pem_reg_loss, pem_cls_loss = bmn_loss_func(
pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end, config) pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end, config)
avg_loss = fluid.layers.mean(loss) avg_loss = paddle.mean(loss)
if args.log_interval > 0 and (batch_id % args.log_interval == 0): if args.log_interval > 0 and (batch_id % args.log_interval == 0):
logger.info('[VALID] iter {} '.format(batch_id) logger.info('[VALID] iter {} '.format(batch_id)
...@@ -145,48 +139,75 @@ def train_bmn(args): ...@@ -145,48 +139,75 @@ def train_bmn(args):
valid_config = merge_configs(config, 'valid', vars(args)) valid_config = merge_configs(config, 'valid', vars(args))
if not args.use_gpu: if not args.use_gpu:
place = fluid.CPUPlace() place = paddle.CPUPlace()
elif not args.use_data_parallel: elif not args.use_data_parallel:
place = fluid.CUDAPlace(0) place = paddle.CUDAPlace(0)
else: else:
place = fluid.CUDAPlace(fluid.dygraph.parallel.Env().dev_id) place = paddle.CUDAPlace(dist.ParallelEnv().dev_id)
with fluid.dygraph.guard(place): paddle.disable_static(place)
if args.use_data_parallel: if args.use_data_parallel:
strategy = fluid.dygraph.parallel.prepare_context() dist.init_parallel_env()
bmn = BMN(train_config) bmn = BMN(train_config)
adam = optimizer(train_config, parameter_list=bmn.parameters()) adam = optimizer(train_config, parameter_list=bmn.parameters())
if args.use_data_parallel: if args.use_data_parallel:
bmn = fluid.dygraph.parallel.DataParallel(bmn, strategy) bmn = paddle.DataParallel(bmn)
if args.resume: if args.resume:
# if resume weights is given, load resume weights directly # if resume weights is given, load resume weights directly
assert os.path.exists(args.resume + ".pdparams"), \ assert os.path.exists(args.resume + ".pdparams"), \
"Given resume weight dir {} not exist.".format(args.resume) "Given resume weight dir {} not exist.".format(args.resume)
model, _ = fluid.dygraph.load_dygraph(args.resume) model, _ = paddle.load(args.resume)
bmn.set_dict(model) bmn.set_dict(model)
reader = BMNReader(mode="train", cfg=train_config) #Reader
train_reader = reader.create_reader() bs_denominator = 1
if args.use_data_parallel: if args.use_gpu:
train_reader = fluid.contrib.reader.distributed_batch_reader( gpus = os.getenv("CUDA_VISIBLE_DEVICES", "")
train_reader) if gpus == "":
pass
else:
gpus = gpus.split(",")
num_gpus = len(gpus)
assert num_gpus == train_config.TRAIN.num_gpus, \
"num_gpus({}) set by CUDA_VISIBLE_DEVICES" \
"shoud be the same as that" \
"set in {}({})".format(
num_gpus, args.config, train_config.TRAIN.num_gpus)
bs_denominator = train_config.TRAIN.num_gpus
bs_train_single = int(train_config.TRAIN.batch_size / bs_denominator)
bs_val_single = int(valid_config.VALID.batch_size / bs_denominator)
train_dataset = BmnDataset(train_config, 'train')
val_dataset = BmnDataset(valid_config, 'valid')
train_sampler = DistributedBatchSampler(
train_dataset,
batch_size=bs_train_single,
shuffle=train_config.TRAIN.use_shuffle,
drop_last=True)
train_loader = DataLoader(
train_dataset,
batch_sampler=train_sampler,
places=place,
num_workers=train_config.TRAIN.num_workers,
return_list=True)
val_sampler = DistributedBatchSampler(val_dataset, batch_size=bs_val_single)
val_loader = DataLoader(
val_dataset,
batch_sampler=val_sampler,
places=place,
num_workers=valid_config.VALID.num_workers,
return_list=True)
for epoch in range(args.epoch): for epoch in range(args.epoch):
for batch_id, data in enumerate(train_reader()): for batch_id, data in enumerate(train_loader):
video_feat = np.array( x_data = paddle.to_tensor(data[0])
[item[0] for item in data]).astype(DATATYPE) gt_iou_map = paddle.to_tensor(data[1])
gt_iou_map = np.array( gt_start = paddle.to_tensor(data[2])
[item[1] for item in data]).astype(DATATYPE) gt_end = paddle.to_tensor(data[3])
gt_start = np.array([item[2] for item in data]).astype(DATATYPE)
gt_end = np.array([item[3] for item in data]).astype(DATATYPE)
x_data = fluid.dygraph.base.to_variable(video_feat)
gt_iou_map = fluid.dygraph.base.to_variable(gt_iou_map)
gt_start = fluid.dygraph.base.to_variable(gt_start)
gt_end = fluid.dygraph.base.to_variable(gt_end)
gt_iou_map.stop_gradient = True gt_iou_map.stop_gradient = True
gt_start.stop_gradient = True gt_start.stop_gradient = True
gt_end.stop_gradient = True gt_end.stop_gradient = True
...@@ -196,7 +217,7 @@ def train_bmn(args): ...@@ -196,7 +217,7 @@ def train_bmn(args):
loss, tem_loss, pem_reg_loss, pem_cls_loss = bmn_loss_func( loss, tem_loss, pem_reg_loss, pem_cls_loss = bmn_loss_func(
pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end, pred_bm, pred_start, pred_end, gt_iou_map, gt_start, gt_end,
train_config) train_config)
avg_loss = fluid.layers.mean(loss) avg_loss = paddle.mean(loss)
if args.use_data_parallel: if args.use_data_parallel:
avg_loss = bmn.scale_loss(avg_loss) avg_loss = bmn.scale_loss(avg_loss)
...@@ -205,39 +226,40 @@ def train_bmn(args): ...@@ -205,39 +226,40 @@ def train_bmn(args):
else: else:
avg_loss.backward() avg_loss.backward()
adam.minimize(avg_loss) adam.step()
adam.clear_grad()
bmn.clear_gradients()
if args.log_interval > 0 and ( if args.log_interval > 0 and (batch_id % args.log_interval == 0):
batch_id % args.log_interval == 0):
logger.info('[TRAIN] Epoch {}, iter {} '.format(epoch, batch_id) logger.info('[TRAIN] Epoch {}, iter {} '.format(epoch, batch_id)
+ '\tLoss = {}, \ttem_loss = {}, \tpem_reg_loss = {}, \tpem_cls_loss = {}'.format( + '\tLoss = {}, \ttem_loss = {}, \tpem_reg_loss = {}, \tpem_cls_loss = {}'.format(
'%.04f' % avg_loss.numpy()[0], '%.04f' % tem_loss.numpy()[0], \ '%.04f' % avg_loss.numpy()[0], '%.04f' % tem_loss.numpy()[0], \
'%.04f' % pem_reg_loss.numpy()[0], '%.04f' % pem_cls_loss.numpy()[0])) '%.04f' % pem_reg_loss.numpy()[0], '%.04f' % pem_cls_loss.numpy()[0]))
logger.info('[TRAIN] Epoch {} training finished'.format(epoch)) logger.info('[TRAIN] Epoch {} training finished'.format(epoch))
#save
if not os.path.isdir(args.save_dir): if not os.path.isdir(args.save_dir):
os.makedirs(args.save_dir) os.makedirs(args.save_dir)
if dist.get_rank() == 0:
save_model_name = os.path.join( save_model_name = os.path.join(
args.save_dir, "bmn_paddle_dy" + "_epoch{}".format(epoch)) args.save_dir, "bmn_paddle_dy" + "_epoch{}".format(epoch))
fluid.dygraph.save_dygraph(bmn.state_dict(), save_model_name) paddle.save(bmn.state_dict(), save_model_name)
# validation # validation
if args.valid_interval > 0 and (epoch + 1 if args.valid_interval > 0 and (epoch + 1) % args.valid_interval == 0:
) % args.valid_interval == 0:
bmn.eval() bmn.eval()
val_bmn(bmn, valid_config, args) val_bmn(bmn, val_loader, valid_config, args)
bmn.train() bmn.train()
#save final results #save final results
if fluid.dygraph.parallel.Env().local_rank == 0: if dist.get_rank() == 0:
save_model_name = os.path.join(args.save_dir, save_model_name = os.path.join(args.save_dir,
"bmn_paddle_dy" + "_final") "bmn_paddle_dy" + "_final")
fluid.dygraph.save_dygraph(bmn.state_dict(), save_model_name) paddle.save(bmn.state_dict(), save_model_name)
logger.info('[TRAIN] training finished') logger.info('[TRAIN] training finished')
if __name__ == "__main__": if __name__ == "__main__":
args = parse_args() args = parse_args()
train_bmn(args) dist.spawn(train_bmn, args=(args, ), nprocs=4)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册