def metrics(self, pred, label): shape = label.shape epe = self.epeloss( nd.slice(self.upsampler(pred[-1]), begin=(None, None, 0, 0), end=(None, None, shape[2], shape[3])) * self.scale, label) return epe
def test_slice(): a = nd.ones(shape=(LARGE_X, SMALL_Y)) res = nd.slice(a, begin=(LARGE_X-1000, 1), end=(LARGE_X, SMALL_Y)) assert np.sum(res[-1].asnumpy() == 1) == res.shape[1]
def test_slice(): a = nd.ones(LARGE_X) res = nd.slice(a, begin=(LARGE_X - MEDIUM_X), end=LARGE_X) assert res.shape[0] == MEDIUM_X assert res[0] == 1
def main(): """Test ShuffleNetCSBlock""" block_mode = 'ShuffleXception' dummy = nd.random.uniform(-1, 1, shape=(1, 4, 224, 224)) cs_block = ShuffleNetCSBlock(input_channel=4, output_channel=16, mid_channel=16, ksize=3, stride=1, block_mode=block_mode) cs_block.initialize() # generate channel mask channel_mask = nd.array([[1] * 10 + [0] * 6]) from mxnet import autograd as ag with ag.record(): rst = cs_block(dummy, channel_mask) rst.backward() params = cs_block.collect_params() not_selected_channels_grad_is_zero = True for param_name in params: if 'weight' in param_name: grad = params[param_name]._grad[0].asnumpy() print("{} shape: {}".format(param_name, grad.shape)) if 'conv0' in param_name and block_mode == 'ShuffleNetV2': zero_grad = grad[10:, :, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 elif 'conv1' in param_name: zero_grad = grad[10:, :, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 elif 'conv2' in param_name: if block_mode == 'ShuffleNetV2': zero_grad = grad[:, 10:, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 else: zero_grad = grad[10:, :, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 elif 'conv3' in param_name: zero_grad = grad[10:, 10:, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 elif 'conv4' in param_name: zero_grad = grad[10:, :, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 elif 'conv5' in param_name: zero_grad = grad[:, 10:, :, :] unique_grad = list(np.unique(zero_grad)) not_selected_channels_grad_is_zero = not_selected_channels_grad_is_zero and \ len(unique_grad) == 1 and unique_grad[0] == 0 print("Not selected channels grads are zero: {}".format( not_selected_channels_grad_is_zero)) print("Finished testing ShuffleNetCSBlock\n") """ Test ShuffleChannels """ channel_shuffle = ShuffleChannels(mid_channel=4, groups=2) s = nd.ones([1, 8, 3, 3]) s[:, 4:, :, :] *= 2 s_project, s_main = channel_shuffle(s) print(s) print(s_project) print(s_main) print("Finished testing ShuffleChannels\n") """ Test ShuffleBlock with "ShuffleNetV2" mode """ tensor = nd.ones([1, 4, 14, 14]) tensor[:, 2:, :, :] = 2 block0 = ShuffleNetBlock(input_channel=4, output_channel=16, mid_channel=int(16 // 2 * 1.4), ksize=3, stride=2, block_mode='ShuffleNetV2') block1 = ShuffleNetBlock(input_channel=16, output_channel=16, mid_channel=int(16 // 2 * 1.2), ksize=3, stride=1, block_mode='ShuffleNetV2') block0.initialize() block1.initialize() temp0 = block0(tensor) temp1 = block1(temp0) print(temp0.shape) print(temp1.shape) # print(block0) # print(block1) print("Finished testing ShuffleNetV2 mode\n") """ Test ShuffleBlock with "ShuffleXception" mode """ tensor = nd.ones([1, 4, 14, 14]) tensor[:, 2:, :, :] = 2 blockx0 = ShuffleNetBlock(input_channel=4, output_channel=16, mid_channel=int(16 // 2 * 1.4), ksize=3, stride=2, block_mode='ShuffleXception') blockx1 = ShuffleNetBlock(input_channel=16, output_channel=16, mid_channel=int(16 // 2 * 1.2), ksize=3, stride=1, block_mode='ShuffleXception') blockx0.initialize() blockx1.initialize() tempx0 = blockx0(tensor) tempx1 = blockx1(temp0) print(tempx0.shape) print(tempx1.shape) # print(blockx0) # print(blockx1) print("Finished testing ShuffleXception mode\n") """ Test ChannelSelection """ block_final_output_channel = 8 candidate_scales = [0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0] max_channel = int(block_final_output_channel // 2 * candidate_scales[-1]) tensor = nd.ones([1, max_channel, 14, 14]) for i in range(max_channel): tensor[:, i, :, :] = i channel_selector = ChannelSelector( channel_number=block_final_output_channel) print(channel_selector) for i in range(4): global_channel_mask = random_channel_mask( stage_out_channels=[8, 160, 320, 640]) local_channel_mask = nd.slice(global_channel_mask, begin=(i, None), end=(i + 1, None)) selected_tensor = channel_selector(tensor, local_channel_mask) print(selected_tensor.shape) print("Finished testing ChannelSelector\n") """ Test BN with inference statistic update """ bn = NasBatchNorm(inference_update_stat=True, in_channels=4) bn.initialize() bn.running_mean.set_data(bn.running_mean.data() + 1) mean, std = 5, 2 for i in range(100): dummy = nd.random.normal(mean, std, shape=(10, 4, 5, 5)) rst = bn(dummy) # print(dummy) # print(rst) print("Defined mean: {}, running mean: {}".format(mean, bn.running_mean.data())) print("Defined std: {}, running var: {}".format(std, bn.running_var.data())) print("Finished testing NasBatchNorm\n") """ Test Transpose Conv """ dummy = nd.ones((1, 6, 5, 5)) for i in range(6): dummy[:, i, :, :] = i transpose_conv = ShuffleChannelsConv(mid_channel=6 / 2) transpose_conv.initialize() transpose_conv.transpose_init() print(transpose_conv(dummy))
def forward(self, cls_targets, ctr_targets, box_targets, mask_targets, matches, cls_preds, ctr_preds, box_preds, mask_preds, maskcoe_preds): """Compute loss in entire batch across devices.""" scale = 4 # require results across different devices at this time cls_targets, ctr_targets, box_targets, mask_targets, matches, cls_preds, ctr_preds, box_preds, mask_preds, maskcoe_preds = \ [_as_list(x) for x in (cls_targets, ctr_targets, box_targets, mask_targets, matches, cls_preds, ctr_preds, box_preds, mask_preds, maskcoe_preds)] # compute element-wise cross entropy loss and sort, then perform negative mining cls_losses = [] ctr_losses = [] box_losses = [] mask_losses = [] sum_losses = [] for clst, ctrt, boxt, maskt, matche, clsp, ctrp, boxp, maskp, maskcoep in zip( *[ cls_targets, ctr_targets, box_targets, mask_targets, matches, cls_preds, ctr_preds, box_preds, mask_preds, maskcoe_preds ]): pos_gt_mask = clst > 0 # cls loss if not self._from_logits: clsp = nd.sigmoid(clsp) one_hot = nd.one_hot(clst, self._num_class) one_hot = nd.slice_axis(one_hot, begin=1, end=None, axis=-1) pt = nd.where(one_hot, clsp, 1 - clsp) t = nd.ones_like(one_hot) alpha = nd.where(one_hot, self._alpha * t, (1 - self._alpha) * t) cls_loss = -alpha * ( (1 - pt)**self._gamma) * nd.log(nd.minimum(pt + self._eps, 1)) cls_loss = nd.sum(cls_loss) / nd.maximum(nd.sum(pos_gt_mask), 1) cls_losses.append(cls_loss) # ctr loss ctrp = nd.squeeze(ctrp, axis=-1) pos_pred_mask = ctrp >= 0 ctr_loss = (ctrp * pos_pred_mask - ctrp * ctrt + nd.log(1 + nd.exp(-nd.abs(ctrp)))) * pos_gt_mask ctr_loss = nd.sum(ctr_loss) / nd.maximum(nd.sum(pos_gt_mask), 1) ctr_losses.append(ctr_loss) # box loss // iou loss px1, py1, px2, py2 = nd.split(boxp, num_outputs=4, axis=-1, squeeze_axis=True) gx1, gy1, gx2, gy2 = nd.split(boxt, num_outputs=4, axis=-1, squeeze_axis=True) apd = nd.abs(px2 - px1 + 1) * nd.abs(py2 - py1 + 1) agt = nd.abs(gx2 - gx1 + 1) * nd.abs(gy2 - gy1 + 1) iw = nd.maximum( nd.minimum(px2, gx2) - nd.maximum(px1, gx1) + 1., 0.) ih = nd.maximum( nd.minimum(py2, gy2) - nd.maximum(py1, gy1) + 1., 0.) ain = iw * ih + 1. union = apd + agt - ain + 1 ious = nd.maximum(ain / union, 0.) fg_mask = nd.where(clst > 0, nd.ones_like(clst), nd.zeros_like(clst)) box_loss = -nd.log(nd.minimum(ious + self._eps, 1.)) * fg_mask if self._return_iou: box_loss = nd.sum(box_loss) / nd.maximum(nd.sum(fg_mask), 1), ious else: box_loss = nd.sum(box_loss) / nd.maximum(nd.sum(fg_mask), 1) box_losses.append(box_loss) # mask loss rank = (-matche).argsort(axis=-1) rank = nd.split(rank, 2, axis=0, squeeze_axis=True) matche = nd.split(matche, 2, axis=0, squeeze_axis=True) maskp = nd.split(maskp, 2, axis=0, squeeze_axis=True) maskt = nd.split(maskt, 2, axis=0, squeeze_axis=True) boxt = nd.split(boxt, 2, axis=0, squeeze_axis=True) maskcoep = nd.split(maskcoep, 2, axis=0, squeeze_axis=True) agt = nd.split(agt, 2, axis=0, squeeze_axis=True) mask_loss = [] for ranki, matchei, maskpi, maskti, boxti, maskcoepi, agti in zip( rank, matche, maskp, maskt, boxt, maskcoep, agt): idx = nd.slice(ranki, 0, 200) pos_mask = nd.take(matchei >= 0, idx) pos_box = nd.take(boxti, idx) area = nd.take(agti, idx) weight = (self.gt_weidth * self.gt_height / (area + self._eps)) * pos_mask mask_idx = nd.take(matchei, idx) maskti = nd.take(maskti, mask_idx) maskpi = nd.dot(nd.take(maskcoepi, idx), maskpi) maskpi = nd.sigmoid(maskpi) with autograd.pause(): _h = nd.arange(186, ctx=maskpi.context) _w = nd.arange(186, ctx=maskpi.context) _h = nd.tile(_h, reps=(pos_box.shape[0], 1)) _w = nd.tile(_w, reps=(pos_box.shape[0], 1)) x1, y1, x2, y2 = nd.split(nd.round(pos_box / scale), num_outputs=4, axis=-1) _w = (_w >= x1) * (_w <= x2) _h = (_h >= y1) * (_h <= y2) _mask = nd.batch_dot(_h.expand_dims(axis=-1), _w.expand_dims(axis=-1), transpose_b=True) maskpi = maskpi * _mask mask_loss.append( nd.sum(self.SBCELoss(maskpi, maskti) * weight) / nd.sum(pos_mask + self._eps)) # if sum(pos_num)>1400: # print(sum(pos_num)) # print(pos_num) # pos_num = (matche >=0).sum(axis=-1).asnumpy() # rank = (-matche).argsort(axis=-1) # mask_loss = [] # for i in range(maskp.shape[0]): # if pos_num[i] == 0.: # # print(pos_num) # mask_loss.append(nd.zeros(shape=(1,), ctx=maskp.context)) # continue # idx = rank[i, :int(pos_num[i])] # pos_box = nd.take(boxt[i], idx) # area = (pos_box[:, 3] - pos_box[:, 1]) * (pos_box[:, 2] - pos_box[:, 0]) # weight = self.gt_weidth * self.gt_height / (area+self._eps) # maskti = maskt[i, matche[i, idx], :, :] # maskpi = nd.dot(nd.take(maskcoep[i], idx), maskp[i]) # _, h, w = maskpi.shape # maskpi = nd.sigmoid(maskpi) # with autograd.pause(): # _h = nd.arange(h, ctx=maskpi.context) # _w = nd.arange(w, ctx=maskpi.context) # _h = nd.tile(_h, reps=(pos_box.shape[0], 1)) # _w = nd.tile(_w, reps=(pos_box.shape[0], 1)) # x1, y1, x2, y2 = nd.split(nd.round(pos_box / scale), num_outputs=4, axis=-1) # _w = (_w >= x1) * (_w <= x2) # _h = (_h >= y1) * (_h <= y2) # _mask = nd.batch_dot(_h.expand_dims(axis=-1), _w.expand_dims(axis=-1), transpose_b=True) # maskpi = maskpi * _mask # mask_loss.append(nd.sum(self.SBCELoss(maskpi, maskti) * weight)/pos_num[i]) mask_loss = nd.mean(nd.concat(*mask_loss, dim=0)) mask_losses.append(mask_loss) sum_losses.append(self._cls_lambd * cls_losses[-1] + self._ctr_lambd * ctr_losses[-1] + self._box_lambd * box_losses[-1] + self._mask_lambd * mask_losses[-1]) return sum_losses, cls_losses, ctr_losses, box_losses, mask_losses
mod.init_optimizer(optimizer='sgd', optimizer_params={ 'learning_rate': 0.01, 'momentum': 0.9 }) for i in range(400): nd_iter.reset() for ibatch, batch in enumerate(nd_iter): t0 = time.time() label = batch.label[0] labels_2d = nd.expand_dims(label, axis=-1) pts_fts = batch.data[0] bs = pts_fts.shape[0] points2 = nd.slice(pts_fts, begin=(0, 0, 0), end=(None, None, 3)) #features2 = nd.slice(pts_fts, begin=(0,0,3), end= (None, None, None)) offset = int(random.gauss(0, setting.sample_num // 8)) offset = max(offset, -setting.sample_num // 4) offset = min(offset, setting.sample_num // 4) sample_num_train = setting.sample_num + offset indices = get_indices(batch_size_train, sample_num_train, point_num) indices_nd = nd.array(indices, dtype=np.int32) points_sampled = nd.gather_nd(points2, indices=indices_nd) #features_sampled = nd.gather_nd(features2, indices=nd.transpose(indices_nd, (2, 0, 1))) xforms_np, rotations_np = get_xforms( batch_size_train, rotation_range=setting.rotation_range,