emlloss.py 2.8 KB
Newer Older
1 2 3
import math
import numpy as np
import paddle.fluid as fluid
K
kebinC 已提交
4 5 6
from . import datareader as reader
from .metrics import calculate_order_dist_matrix
from .metrics import get_gpu_num
7 8

class emlloss():
K
kbChen 已提交
9 10
    def __init__(self, train_batch_size = 40, samples_each_class=2):
        num_gpus = get_gpu_num()
11
        self.samples_each_class = samples_each_class
K
kbChen 已提交
12 13
        self.train_batch_size = train_batch_size
        assert(train_batch_size % num_gpus == 0)
K
kebinC 已提交
14
        self.cal_loss_batch_size = train_batch_size // num_gpus
K
kbChen 已提交
15
        assert(self.cal_loss_batch_size % samples_each_class == 0)
K
kebinC 已提交
16
        class_num = train_batch_size // samples_each_class
K
kbChen 已提交
17 18 19 20 21 22
        self.train_reader = reader.eml_train(train_batch_size, samples_each_class)
        self.test_reader = reader.test()

    def surrogate_function(self, beta, theta, bias):
        x = theta * fluid.layers.exp(bias) 
        output = fluid.layers.log(1+beta*x)/math.log(1+beta)
23
        return output
K
kbChen 已提交
24 25 26

    def surrogate_function_approximate(self, beta, theta, bias):
        output = (fluid.layers.log(theta) + bias + math.log(beta))/math.log(1+beta)
27
        return output
K
kbChen 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40

    def surrogate_function_stable(self, beta, theta, target, thresh):
        max_gap = fluid.layers.fill_constant([1], dtype='float32', value=thresh)
        max_gap.stop_gradient = True

        target_max = fluid.layers.elementwise_max(target, max_gap)
        target_min = fluid.layers.elementwise_min(target, max_gap)
        
        loss1 = self.surrogate_function(beta, theta, target_min)
        loss2 = self.surrogate_function_approximate(beta, theta, target_max)
        bias = self.surrogate_function(beta, theta, max_gap)
        loss = loss1 + loss2 - bias
        return loss
41 42 43

    def loss(self, input):
        samples_each_class = self.samples_each_class
K
kbChen 已提交
44 45 46 47 48 49
        batch_size = self.cal_loss_batch_size   
        d = calculate_order_dist_matrix(input, self.cal_loss_batch_size, self.samples_each_class)
        ignore, pos, neg = fluid.layers.split(d, num_or_sections= [1, 
            samples_each_class-1, batch_size-samples_each_class], dim=1)
        ignore.stop_gradient = True 
                    
50 51
        pos_max = fluid.layers.reduce_max(pos, dim=1)
        pos_max = fluid.layers.reshape(pos_max, shape=[-1, 1])
K
kbChen 已提交
52
        pos = fluid.layers.exp(pos - pos_max)
53
        pos_mean = fluid.layers.reduce_mean(pos, dim=1)
K
kbChen 已提交
54

55 56 57 58
        neg_min = fluid.layers.reduce_min(neg, dim=1)
        neg_min = fluid.layers.reshape(neg_min, shape=[-1, 1])
        neg = fluid.layers.exp(-1*(neg-neg_min))
        neg_mean = fluid.layers.reduce_mean(neg, dim=1)
K
kbChen 已提交
59
        bias = pos_max - neg_min
60
        theta = fluid.layers.reshape(neg_mean * pos_mean, shape=[-1,1])
K
kbChen 已提交
61 62 63
        thresh = 20.0
        beta = 100000
        loss = self.surrogate_function_stable(beta, theta, bias, thresh)
64
        return loss