2017-01-16 14 views
5

w kerasach, chcę dostosować funkcję utraty, która nie tylko przyjmuje (y_true, y_pred) jako dane wejściowe, ale także musi wykorzystywać dane wyjściowe z warstwy wewnętrznej sieć jako etykieta dla warstwy wyjściowej. To zdjęcie pokazuje, że wewnętrzne wyjście to xn, który jest wektorem cech 1D. w prawym górnym rogu wyjście to xn ', które jest predykcją xn. Innymi słowy, xn jest etykietą xn '.Keras Implementacja funkcji utraty niestandardowej, która wymaga wyjścia z warstwy wewnętrznej jako etykiety

Podczas gdy [Axe, Ay] jest tradycyjnie znany jako y_true, a [Axe, Ay '] jest y_pred.

Chcę połączyć te dwa składniki strat w jeden i wspólnie trenować sieć.

Wszelkie pomysły i przemyślenia są mile widziane!

Odpowiedz

0

Przede wszystkim powinieneś używać Functional API. Następnie należy zdefiniować wyjście sieciowe jako wynik plus wynik z warstwy wewnętrznej, połączyć je w jedno wyjście (przez konkatenację), a następnie utworzyć niestandardową funkcję utraty, która następnie podzieli scalone wyjście na dwie części i wykona obliczenia strat na własną rękę.

Coś jak:

def customLoss(y_true, y_pred): 
    #loss here 
    internalLayer = Convolution2D()(inputs) #or other layers 
    internalModel = Model(input=inputs, output=internalLayer) 
    tmpOut = Dense(...)(internalModel) 
    mergedOut = merge([tmpOut, mergedOut], mode = "concat", axis = -1) 
    fullModel = Model(input=inputs, output=mergedOut) 

    fullModel.compile(loss = customLoss, optimizer = "whatever") 
+0

Dzięki za odpowiedź! Moim głównym zmartwieniem jest to, jak utworzyć funkcję utraty. Tak, możemy połączyć oba wyjścia w jeden, ale przy obliczaniu straty dla wewnętrznego wyjścia (xn '), niestandardowa strata potrzebuje dostępu do samego modelu, aby uzyskać etykietę dla wewnętrznego wyjścia (xn). xn nie jest danymi treningowymi, ale pewną transformacją danych treningowych przetwarzanych przez model. – ljklonepiece

+0

@LiJuekun nie możesz po prostu wstawić "etykiety wewnętrznej" do wartości y, którą pasujesz? –

7

I zorientowali się wyjście, na wypadek gdyby ktoś szuka tego samego, Zamieściłem tutaj (na podstawie sieci podanych w tym poście):

The Pomysł polega na zdefiniowaniu dostosowanej funkcji straty i wykorzystaniu jej jako wyjścia sieci. (Oznaczenia: A jest prawdziwym etykieta zmiennej A i A' jest przewidywana wartość zmiennej A)

def customized_loss(args): 
    #A is from the training data 
    #S is the internal state 
    A, A', S, S' = args 
    #customize your own loss components 
    loss1 = K.mean(K.square(A - A'), axis=-1) 
    loss2 = K.mean(K.square(S - S'), axis=-1) 
    #adjust the weight between loss components 
    return 0.5 * loss1 + 0.5 * loss2 

def model(): 
    #define other inputs 
    A = Input(...) # define input A 
    #construct your model 
    cnn_model = Sequential() 
    ... 
    # get true internal state 
    S = cnn_model(prev_layer_output0) 
    # get predicted internal state output 
    S' = Dense(...)(prev_layer_output1) 
    # get predicted A output 
    A' = Dense(...)(prev_layer_output2) 
    # customized loss function 
    loss_out = Lambda(customized_loss, output_shape=(1,), name='joint_loss')([A, A', S, S']) 
    model = Model(input=[...], output=[loss_out]) 
    return model 

    def train(): 
     m = model() 
     opt = 'adam' 
     model.compile(loss={'joint_loss': lambda y_true, y_pred:y_pred}, optimizer = opt) 
     # train the model 
     .... 
+0

Wiem, że od jakiegoś czasu było cicho, ale czy możesz wyjaśnić, czym są A i A? A "to przewidywanie A, czy nie jest? A powinien być faktycznym oczekiwanym wynikiem, dlaczego więc jest zdefiniowany jako wejście zamiast tablicy numpy, która przyjmuje wartości? – tryingtolearn

Powiązane problemy