def train(): batch_size = 32 train_iter, _ = d2l.load_data_pikachu(batch_size) ctx, net = d2l.try_gpu(), TinySSD(num_classes=1) net.initialize(init=init.Xavier(), ctx=ctx) trainer = gluon.Trainer(net.collect_params(), 'sgd', { 'learning_rate': 0.2, 'wd': 5e-4 }) cls_loss = gloss.SoftmaxCrossEntropyLoss() bbox_loss = gloss.L1Loss() def calc_loss(cls_preds, cls_labels, bbox_preds, bbox_labels, bbox_masks): cls = cls_loss(cls_preds, cls_labels) bbox = bbox_loss(bbox_preds * bbox_masks, bbox_labels * bbox_masks) return cls + bbox def cls_eval(cls_preds, cls_labels): # 由于类别预测结果放在最后一维,argmax需要指定最后一维 return (cls_preds.argmax(axis=-1) == cls_labels).sum().asscalar() def bbox_eval(bbox_preds, bbox_labels, bbox_masks): return ((bbox_labels - bbox_preds) * bbox_masks).abs().sum().asscalar() for epoch in range(20): acc_sum, mae_sum, n, m = 0.0, 0.0, 0, 0 train_iter.reset() # 从头读取数据 start = time.time() for batch in train_iter: X = batch.data[0].as_in_context(ctx) Y = batch.label[0].as_in_context(ctx) with autograd.record(): # 生成多尺度的锚框,为每个锚框预测类别和偏移量 anchors, cls_preds, bbox_preds = net(X) # 为每个锚框标注类别和偏移量 bbox_labels, bbox_masks, cls_labels = \ contrib.nd.MultiBoxTarget(anchors, Y, cls_preds.transpose((0, 2, 1))) # 根据类别和偏移量的预测和标注值计算损失函数 l = calc_loss(cls_preds, cls_labels, bbox_preds, bbox_labels, bbox_masks) l.backward() trainer.step(batch_size) acc_sum += cls_eval(cls_preds, cls_labels) n += cls_labels.size mae_sum += bbox_eval(bbox_preds, bbox_labels, bbox_masks) m += bbox_labels.size if (epoch + 1) % 5 == 0: print( 'epoch %2d, class err %.2e, bbox mae %.2e, time %.1f sec' % (epoch + 1, 1 - acc_sum / n, mae_sum / m, time.time() - start))
net = TinySSD(num_classes=1) net.initialize() X = nd.zeros((32, 3, 256, 256)) anchors, cls_preds, bbox_preds = net(X) print('output anchors:', anchors.shape) print('output class preds:', cls_preds.shape) print('output bbox preds:', bbox_preds.shape) #9.7.2-训练 #读取数据和初始化 batch_size = 32 print('try_gpu') train_iter, _ = d2l.load_data_pikachu(batch_size) ctx, net = d2l.try_gpu(), TinySSD(num_classes=1) net.initialize(init=init.Xavier(), ctx=ctx) print("start train...\n") trainer = gluon.Trainer(net.collect_params(), 'sgd', { 'learning_rate': 0.2, 'wd': 5e-4 }) print("end train...\n") #定义损失函数和评价函数 cls_loss = gloss.SoftmaxCrossEntropyLoss() bbox_loss = gloss.L1Loss() def calc_loss(cls_preds, cls_labels, bbox_preds, bbox_labels, bbox_masks):