def validate(epoch, val_loader, generator, opt, ctx, gen_shape=False): """ evaluate program generator, in terms of IoU """ generated_shapes = [] original_shapes = [] for idx, data in enumerate(val_loader): start = time.time() shapes = data.as_in_context(ctx) shapes = nd.expand_dims(shapes, axis=1) with autograd.train_mode(): out = generator.decode(shapes) end = time.time() if gen_shape: out_1 = nd.round(out[0]).astype('int64') out_2 = nd.round(out[1]).astype('int64') generated_shapes.append( decode_multiple_block(out_1, out_2).astype("float32")) original_shapes.append(data.asnumpy()) if idx % opt.info_interval == 0: print("Test: epoch {} batch {}/{}, time={:.3f}".format( epoch, idx, len(val_loader), end - start)) if gen_shape: generated_shapes = np.concatenate(generated_shapes, axis=0) original_shapes = np.concatenate(original_shapes, axis=0) return generated_shapes, original_shapes
def train(self,epochs): for i in range(epochs): efficiency = 0 cumuLoss = 0 for j in range(self.nbIter): z = nd.round(nd.random.uniform(0,1,(self.batchSize,self.code.k),ctx=self.ctx)) x = nd.dot(z,self.code.G)%2 noiseBSC = nd.random.uniform(0.01,0.99,(self.batchSize,self.code.n),ctx=self.ctx) noiseBSC = nd.floor(noiseBSC/nd.max(noiseBSC,axis=(1,)).reshape((self.batchSize,1))) y = (x + noiseBSC)%2 with autograd.record(): zHat = self.net(y) loss = self.SE(zHat,z) loss.backward() self.adam(self.params,self.vs,self.sqrs, self.lr, self.batchSize, self.t) self.t+=1 cumuLoss += loss.asscalar() zHat = nd.round(zHat) efficiency += nd.sum(nd.equal(zHat,z)).asscalar() Pc = efficiency/(self.batchSize*self.nbIter*self.code.k) Pe = 1 - Pc normCumuLoss = cumuLoss/(self.batchSize*self.nbIter*self.code.k) print("Epochs %d: Pe = %lf , loss = %lf" % (i,Pe,normCumuLoss))
def validate(epoch, val_loader, model, crit_cls, crit_reg, opt, ctx, gen_shape=False): """ One validation """ generated_shapes = [] original_shapes = [] sample_prob = opt.inner_sample_prob loss_cls_sum, loss_reg_sum, n = 0.0, 0.0, 0 for idx, data in enumerate(val_loader): start = time.time() shapes, labels, masks, params, param_masks = data[0], data[1], data[ 2], data[3], data[4] gt = shapes shapes = nd.expand_dims(shapes, axis=1) shapes = shapes.as_in_context(ctx) labels = labels.as_in_context(ctx) masks = masks.as_in_context(ctx) params = params.as_in_context(ctx) param_masks = param_masks.as_in_context(ctx) with autograd.train_mode(): out = model.decode(shapes) #out = model(shapes, labels, sample_prob) bsz, n_block, n_step = labels.shape labels = labels.reshape(bsz, n_block * n_step) masks = masks.reshape(bsz, n_block * n_step) out_pgm = out[0].reshape(bsz, n_block * n_step, opt.program_size + 1) bsz, n_block, n_step, n_param = params.shape params = params.reshape(bsz, n_block * n_step, n_param) param_masks = param_masks.reshape(bsz, n_block * n_step, n_param) out_param = out[1].reshape(bsz, n_block * n_step, n_param) loss_cls, acc = crit_cls(out_pgm, labels, masks) loss_reg = crit_reg(out_param, params, param_masks) end = time.time() loss_cls = loss_cls.mean().asscalar() loss_reg = loss_reg.mean().asscalar() if idx % opt.info_interval == 0: out_1 = nd.round(out[0]).astype('int64') out_2 = nd.round(out[1]).astype('int64') pred = nd.from_numpy(decode_multiple_block( out_1, out_2)).astype("float32").as_in_context(mx.cpu()) IoU = BatchIoU(pred, gt) print( "Test: epoch {} batch {}/{}, loss_cls = {:.3f}, loss_reg = {:.3f}, acc = {:.3f}, IoU = {:.3f} time = {:.3f}" .format(epoch, idx, len(val_loader), loss_cls, loss_reg, acc[0].asscalar(), IoU.mean(), end - start)) sys.stdout.flush()
def _inv_normalize(self, data, mean=None, std=None, clip=True): std, mean = std.as_in_context(data.context), mean.as_in_context( data.context) images = data.transpose((0, 2, 3, 1)) images = images * std + mean if clip: images = images.clip(0, 1) images = nd.round(images * 255) / 255 images = (images - mean) / std data[:, :, :, :] = images.transpose((0, 3, 1, 2))
def crop(self, bboxes, h, w, masks): scale = 4 b = bboxes.shape[0] ctx = bboxes.context with autograd.pause(): _h = nd.arange(h, ctx=ctx) _w = nd.arange(w, ctx=ctx) _h = nd.tile(_h, reps=(b, 1)) _w = nd.tile(_w, reps=(b, 1)) x1, y1 = nd.round(bboxes[:, 0] / scale), nd.round(bboxes[:, 1] / scale) x2, y2 = nd.round((bboxes[:, 2]) / scale), nd.round( (bboxes[:, 3]) / scale) _w = (_w >= x1.expand_dims(axis=-1)) * (_w <= x2.expand_dims(axis=-1)) _h = (_h >= y1.expand_dims(axis=-1)) * (_h <= y2.expand_dims(axis=-1)) _mask = nd.batch_dot(_h.expand_dims(axis=-1), _w.expand_dims(axis=-1), transpose_b=True) masks = _mask * masks return masks
def accuracy(self, y_hat, y): return (nd.argmax(nd.round(y_hat), axis=1) == y).asnumpy().mean()
_total_los += nd.sum(loss(_out, _label)).asnumpy() pred.extend(nd.softmax(_out)[:, 1].asnumpy()) label.extend(_label.asnumpy()) va_acc = accuracy_score(label, [round(p) for p in pred]) va_loss = _total_los / n_obs tqdm.write( 'Epoch {}: tr_loss = {}, tr_acc= {}, va_loss = {}, va_acc= {}'.format( epoch, tr_loss, tr_acc, va_loss, va_acc)) y_pred_mlp = mlp(nd.array(va_x, ctx=context)) # softmax를 적용하고 # 두번째 열을 뽑아와서 # nd.round 함수를 적용해서 0/1 예측값을 얻고 # numpy array로 바꾸고 # 첫번째 원소를 뽑아서 예측 label로 사용 pred_mlp = [nd.round(val).asnumpy()[0] for val in nd.softmax(y_pred_mlp)[:, 1]] accuracy_mlp = accuracy_score(va_y, pred_mlp) print('Accuracy: %.2f%%' % (accuracy_mlp * 100.0)) #### DNN without embedding class MLP(nn.Block): def __init__(self, **kwargs): super(MLP, self).__init__(**kwargs) with self.name_scope(): self.dense1 = nn.Dense(64) #self.dense2 = nn.Dense(32, activation = 'relu') self.bn = nn.BatchNorm() self.dense2 = nn.Dense(2)
def check_round(): y = nd.round(x) # expected ouput for middle 5 values after applying round() expected_output = [-1, -1, 0, 1, 1] assert_correctness_of_rounding_ops(y, LARGE_X // 2, expected_output)
def train(self, inputs, outputs, epochs=10, batch_size=32, lr=0.001, transform=None, verbose=True): """train the neural network to fit the outputs with the inputs. Args: inputs: an ndarray of input. outputs: an ndarray of outputs. epochs, batch_size, lr: the parameters of the learning algorithm. transform: if None, take the output as given, else try to compute transformed outputs = transform(outputs) and fit with them. verbose: If True then the results will be displayed all along the training. Returns: The historical of the training. (tuple of array).""" if transform: outputs = transform(outputs) n = (inputs.shape[1] - 1) // batch_size + 1 #inputs-1/batch - 1 < n <= inputs-1/batch if len(outputs.shape) == 1: outputs = outputs.reshape((1, outputs.shape[0])) assert inputs.shape[1] == outputs.shape[1], "Shapes does not match." data = nd.concat(inputs.T, outputs.T) efficiencies = [] cumuLosses = [] epochs = list(range(epochs)) for i in epochs: efficiency = 0 cumuLoss = 0 data = nd.shuffle(data) batchs = [ data[k * batch_size:min(inputs.shape[1], (k + 1) * batch_size), :] for k in range(n) ] for batch in batchs: with autograd.record(): output = self.compute(batch[:, :inputs.shape[0]].T) loss = SymNet.squared_error(output, batch[:, inputs.shape[0]:].T) loss.backward() self.adam_descent(batch_size, lr) output = nd.round(output) cumuLoss += loss.asscalar() efficiency += nd.sum( nd.equal(output, batch[:, inputs.shape[0]:].T)).asscalar() efficiency /= outputs.shape[1] * outputs.shape[0] efficiencies.append(efficiency) cumuLoss /= outputs.shape[1] * outputs.shape[0] cumuLosses.append(cumuLoss) if verbose: print("Epochs %d: Pe = %lf , loss = %lf" % (i, 1 - efficiency, cumuLoss)) return (epochs, cumuLosses, efficiencies)
# Sentiment analysis class sa = SA_Classifier(sen_rep, classifier, batch_size, context) sa.collect_params().initialize(mx.init.Xavier(), ctx=context) loss = gluon.loss.SigmoidBCELoss() trainer = gluon.Trainer(sa.collect_params(), 'adam', {'learning_rate': 1e-3}) # Train model train(5, log_interval, sa, train_data, valid_data, trainer, loss, context=context) # We need to specify batch_size explicitly becuase we need that in reshaping idx = np.random.choice(len(va_idx), batch_size) va_txt = [origin_txt[_idx] for _idx in va_idx] va_txt = [va_txt[j] for j in idx] va_txt = pd.DataFrame(va_txt, columns=['txt']) y_pred_sa = sa(nd.array([va_x[i] for i in idx], ctx=context)) pred_sa = [nd.round(val).asnumpy() for val in nd.sigmoid(y_pred_sa)] pred_sa_pd = pd.DataFrame(pred_sa, columns=['pred_sa']) label_pd = pd.DataFrame([va_y[j] for j in idx], columns=['label']) result = pd.concat([va_txt, pred_sa_pd, label_pd], axis=1) result.head(10) result[result['pred_sa'] != result['label']].shape
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
def train(epoch, train_loader, generator, executor, criterion, optimizer, opt, ctx): """ one epoch guided adaptation """ def set_bn_eval(m): if m.prefix[:9] == 'batchnorm': m._kwargs['use_global_stats'] = True m.grad_req = 'null' executor.apply(set_bn_eval) for idx, data in enumerate(train_loader): start = time.time() shapes = data.as_in_context(ctx) raw_shapes = data shapes = shapes.expand_dims(axis=1) with autograd.record(): pgms, params = generator.decode(shapes) # truly rendered shapes pgms_int = nd.round(pgms).astype('int64') params_int = nd.round(params).astype('int64') # neurally rendered shapes pgms = nd.exp(pgms) bsz, n_block, n_step, n_vocab = pgms.shape pgm_vector = pgms.reshape(bsz * n_block, n_step, n_vocab) bsz, n_block, n_step, n_param = params.shape param_vector = params.reshape(bsz * n_block, n_step, n_param) index = (n_step - 1) * nd.ones(bsz * n_block).astype('int64') index = index.as_in_context(ctx) pred = executor(pgm_vector, param_vector, index) pred = nd.softmax(pred, axis=1) #print(pred.shape) pred = pred[:, 1] pred = pred.reshape(bsz, n_block, 32, 32, 32) rec = nd.max(pred, axis=1) #print("rec.shape:",rec.shape,"shapes.shape:",shapes.shape) #rec1 = rec.expand_dims(axis=1) rec1 = nd.log(rec + 1e-11) rec0 = nd.log(1 - rec + 1e-11) #rec_all = nd.concat(rec0, rec1, dim=1) #rec_all1 = nd.log(rec_all + 1e-10) #rec_all2 = nd.log(1-rec_all + 1e-10) gt = shapes.squeeze().astype('int64') loss = -nd.where(gt, rec1, rec0).mean(axis=(1, 2, 3)) #loss = -(nd.pick(rec_all1,gt,axis = 1,keepdims=True)).mean(axis = (1,2,3,4)) #loss = criterion(rec_all, gt) loss.backward() optimizer.step(loss.shape[0], ignore_stale_grad=True) l = loss.mean().asscalar() rendered_shapes = decode_multiple_block(pgms_int, params_int) rendered_shapes = nd.from_numpy(rendered_shapes).astype( 'float32').as_in_context(mx.cpu()) IoU2 = BatchIoU(raw_shapes, rendered_shapes) reconstruction = (rec.as_in_context(mx.cpu()) > 0.5).astype('float32') IoU1 = BatchIoU(reconstruction, raw_shapes) #print("IoU1:",IoU1,IoU2) IoU1 = IoU1.mean() IoU2 = IoU2.mean() end = time.time() if idx % opt.info_interval == 0: print( "Train: epoch {} batch {}/{}, loss = {:.3f}, IoU1 = {:.3f}, IoU2 = {:.3f}, time = {:.3f}" .format(epoch, idx, len(train_loader), l, IoU1, IoU2, end - start)) sys.stdout.flush()
# Specify loss function; in this case because we use a single class # for the logistic regression, we will use SigmoidBinaryCrossEntropyLoss() # with from_sigmoid = False loss_func = gloss.SigmoidBinaryCrossEntropyLoss(from_sigmoid=False) # Specify the number of epochs and start training n_epochs = 50 for epoch in range(n_epochs): batch_losses = [] for batch_features, batch_labels in train_iter: batch_features = batch_features.as_in_context(CTX) batch_labels = batch_labels.as_in_context(CTX) with autograd.record(): logit_preds = log_reg(batch_features) loss = loss_func(logit_preds, batch_labels) batch_losses.append(nd.mean(loss).asscalar()) loss.backward() log_reg_trainer.step(batch_features.shape[0]) epoch_train_loss = np.mean(batch_losses) train_preds = nd.round(nd.sigmoid(log_reg(train_features))).reshape((-1, )) train_acc = nd.mean(train_preds == train_labels).asscalar() epoch_report_str = 'Epoch{}, Training loss {:.10f}, Training accuracy {:.3f}'.format( epoch, epoch_train_loss, train_acc) print(epoch_report_str)
# %% # Training loop for epoch in range(EPOCHS): with autograd.record(train_mode=True): # Compute f(x) = Wx y_pred = net(X_train) # Compute loss loss = loss_fn(y_pred, y_train) # Compute dL/dW loss.backward() # Show intermediate values to screen if epoch % 10 == 0: log_info(net, loss) # Update weights, normalization of grads happens here, not in the loss function trainer.step(batch_size=len(X_train)) # change learning rate for every 50 steps if epoch % 50 == 0 and epoch > 0: LR /= 3.0 # %% # Test the model y_pred = net(X_train) y_pred = nd.round(y_pred).asnumpy() acc_train = np.sum(np.equal(y_pred, y_train.asnumpy())) / len(y_train) y_pred = net(X_test) y_pred = nd.round(y_pred).asnumpy() acc_test = np.sum(np.equal(y_pred, y_test.asnumpy())) / len(y_test) print(f"acc_train: {acc_train:0.4f}") print(f"acc_test: {acc_test:0.4f}")
def train(epoch, train_loader, model, crit_cls, crit_reg, optimizer, opt, ctx): """ One epoch training """ cls_w = opt.cls_weight reg_w = opt.reg_weight # the prob: > 1 # the input of step t Operator where is missing FInferType attributeis always sampled from the output of step t-1 sample_prob = opt.inner_sample_prob for idx, data in enumerate(train_loader): start = time.time() #data, pgm, pgm_mask, param, param_mask shapes, labels, masks, params, param_masks = data[0], data[1], data[ 2], data[3], data[4] gt = shapes shapes = nd.expand_dims(shapes, axis=1) #print(labels[0],params[0]) shapes = shapes.as_in_context(ctx) labels = labels.as_in_context(ctx) labels2 = labels.as_in_context(ctx) masks = masks.as_in_context(ctx) params = params.as_in_context(ctx) param_masks = param_masks.as_in_context(ctx) #shapes.attach_grad(),labels.attach_grad() with autograd.record(): out = model(shapes, labels, sample_prob) #out = model.decode(shapes) # reshape bsz, n_block, n_step = labels.shape labels = labels.reshape(bsz, -1) masks = masks.reshape(bsz, -1) out_pgm = out[0].reshape(bsz, n_block * n_step, opt.program_size + 1) bsz, n_block, n_step, n_param = params.shape params = params.reshape(bsz, n_block * n_step, n_param) param_masks = param_masks.reshape(bsz, n_block * n_step, n_param) out_param = out[1].reshape(bsz, n_block * n_step, n_param) loss_cls, acc = crit_cls(out_pgm, labels, masks) loss_reg = crit_reg(out_param, params, param_masks) loss = cls_w * loss_cls + reg_w * loss_reg loss.backward() optimizer.step(bsz, ignore_stale_grad=True) loss_cls = loss_cls.mean().asscalar() loss_reg = loss_reg.mean().asscalar() end = time.time() if idx % (opt.info_interval * 10) == 0: out_1 = nd.round(out[0]).astype('int64') out_2 = nd.round(out[1]).astype('int64') pred = nd.from_numpy(decode_multiple_block( out_1, out_2)).astype("float32").as_in_context(mx.cpu()) IoU = BatchIoU(pred, gt) print( "Train: epoch {} batch {}/{},loss_cls = {:.3f},loss_reg = {:.3f},acc = {:.3f},IoU = {:.3f},time = {:.2f}" .format(epoch, idx, len(train_loader), loss_cls, loss_reg, acc[0].asscalar(), IoU.mean(), end - start)) sys.stdout.flush()