MindSpore如何实现多输出模型的loss用LossBase类实现
收藏回复举报
MindSpore如何实现多输出模型的loss用LossBase类实现
发表于2023-10-12 09:37:53
0 查看

1 系统环境

硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU

MindSpore版本: mindspore=2.0.0

执行模式(PyNative/ Graph):不限

Python版本: Python=3.9.7

操作系统平台: 不限

2 报错信息

2.1 问题描述

模型训练需要用到模型中间层特征来计算loss(特征间的距离),因此实现模型的时候会额外输出中间的特征。

class DCTLN(nn.Cell):
    def __init__(self, input_shape, num_classes, BatchNormal):
        super().__init__()
        self.feature_extractor = FeatureExtractor(input_shape, 20, 5, 1, 'same', 2, BatchNormal)
        self.hd_classifier = HealthConditionClassifier(100, num_classes)
        self.domain_classifier = DomainClassifier(100)
        self.grl = GradReverse()
        self.apply(self._init_weights)
        
    def construct(self, x):
        features = self.feature_extractor(x)
        health_condition = self.hd_classifier(features)
        domain = self.domain_classifier(self.grl(features))
        return features, health_condition, domain

使用pytorch写模型和训练脚本的时候,需要计算出loss然后backward就行。在mindspore的反向传播有些不同,目前写成了forward_fn,然后用value_rand_grad函数来获得梯度并反向传播。

def forward_fn(X_source, y_source, X_target, y_target, penalty_param):
    X = ops.concat([X_source, X_target], axis=0)
    # predict and calculate the loss
    features, logits, domain = model(X)
    
    classification_loss = loss_fn(logits.narrow(0, 0, source_size), y_source)
    domain_label = ops.concat([ops.zeros(source_size), ops.ones(target_size)], axis=0)
    domain_loss = ops.binary_cross_entropy(domain, domain_label.reshape(-1, 1))

    mmd_value = mmd(features.narrow(0, 0, source_size), features.narrow(0, source_size, target_size))
    
    # 更新惩罚系数
    model.set_lambda(penalty_param)
    loss = classification_loss #+ domain_loss + penalty_param * mmd_value
    
    return loss, logits
    
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)
(loss, logits), grads = grad_fn(X_source, y_source, X_target, y_target, penalty_param)
# backpropagation
optimizer(grads)

这种方式就不能用下面方式进行训练

Model(net, loss, opt, metrics={'acc', 'loss'})

如何把多输出模型的loss也用LossBase类实现,然后使用上面这种方式来训练?

3 根因分析

4 解决方案

******此处由用户填写******

包含文字方案和最终脚本代码

请将正确的脚本打包并上传附件

我要发帖子