cntk

时间:2017-09-11 09:23:41

标签: python cntk loss

我想在下面计算加权误差:

def calc_err(pred, targets, weights) :
    nClass = np.size(pred, axis=0) 

    Is = [1.0 for i in range(nClass)]
    nonTargets = C.minus(Is, targets)
    wrongPred = C.minus(Is, pred)
    wColumn = C.times(targets, weights)
    wTarget = C.element_times(wColumn, targets)
    wNonTarget = C.element_times(wColumn, nonTargets)
    c1 = C.negate(C.reduce_sum(C.element_times(wTarget, C.log(pred)), axis = -1))
    c2 = C.negate(C.reduce_sum(C.element_times(wNonTarget, C.log(wrongPred)), axis = -1))
    ce = c1 + c2

    return ce.eval()

其中pred是预测概率,目标是预期的单热阵列,权重是2D阵列。我在下面创建了相应的自定义损失:

def WeightedCrossEntropy(z, targets):
    pred = C.softmax(z)
    nClass = np.size(pred, axis=0) 
    Is = [1 for i in range(nClass)]

    nonTargets = C.minus(Is, targets)
    wrongPred = C.minus(Is, pred)
    wColumn = C.times(targets, weights)
    wTarget = C.element_times(wColumn, targets)
    wNonTarget = C.element_times(wColumn, nonTargets)
    c1 = C.negate(C.reduce_sum(C.element_times(wTarget, C.log(pred)), axis=-1))
    c2 = C.negate(C.reduce_sum(C.element_times(wNonTarget, C.log(wrongPred)), axis=-1))
    ce = c1 + c2

    return ce

当我尝试训练时,我注意到虽然自定义丢失确实在减少,但来自calc_err(pred,目标,权重)的测试误差仅减少一个或两个时期或根本没有。我的WeightedCrossEntropy(z,目标)是正确的还是我做错了什么?

2 个答案:

答案 0 :(得分:0)

权重是常数还是参数?请确保这两个函数采用相同的输入,参数和常量。

答案 1 :(得分:0)

以下是预先计算权重的方式:

def ColBasedCustomWeight(nClass) :
    ratio = 1.0
    pfSum = [0] * nClass
    pWs = [[0 for x in range(nClass)] for y in range(nClass)]
    for j in range(nClass):
        for i in range(nClass):
            n = i - j
            if n > 0: 
                # false negative if j = 0
                pWs[j][i] = math.pow(1.5,ratio*n) if j == 0 else math.pow(1.2,ratio*n) 
            elif n < 0:
                # false positive if i = 0
                pWs[j][i] = math.pow(1.5, -ratio*n) if i == 0 else math.pow(1.2, -ratio*n)
            else: 
                pWs[j][i] = 1.0
            pfSum[i] += pWs[j][i]

    #normalize the weights to nClass
    for  j in range(nClass):
        for i in range(nClass):
            pWs[j][i] *= nClass / pfSum[i]

    return pWs

重量定义或计算有问题吗?