2017-09-21 1 views
1

Je voudrais concevoir un nouveau régularisateur, pour lequel j'ai besoin de la valeur de l'époque actuelle pendant l'entraînement.Existe-t-il un moyen d'obtenir la valeur du nombre d'époques (nb_epochs) dans chaque itération?

Par exemple avec

Epoch 7/10 
0s - loss: 93.5298 - acc: 0.0000e+00 - val_loss: 98.3877 - val_acc: 0.0000e+00 
Epoch 8/10 
0s - loss: 91.8406 - acc: 0.0000e+00 - val_loss: 96.8459 - val_acc: 0.0000e+00 

Je voudrais obtenir la valeur de 7 et 8 au cours de la formation.

Comment cela peut-il être fait dans keras?

Répondre

0

Si vous utilisez des rappels, vous avez accès aux époques, aux lots et aux journaux pour chaque cas.

Un LambdaCallback serait une bonne option:

from keras.callbacks import LambdaCallback 

def epochStart(epoch,logs): 
    #do stuff when an epoch starts 

    #do stuff with the number of the 'epoch' 
     #(starting from 0, different from the written outputs in your question) 

    #do stuff with the logs, which is a dictionary with the 'loss', 'val_loss'  
     #and other metrics you may have used in compile, 
     #such as 'acc', 'val_acc' 
     #you may print(logs) to see everything 

def epochEnd(epoch,logs): 

    #do stuff when an epoch ends 
    #same idea as above 


myCallback = LambdaCallback(on_epoch_begin=epochStart,on_epoch_end=epochEnd) 

Lorsque la formation, passer une liste des callbacks:

model.fit(X,Y,....., callbacks=[myCallback]) 
+0

Ceci est OK pour callbacks mais ni pour régularisations qui doivent modifier les choses dont dépend le dégradé. – nemo

+0

Je vois ... ma réponse ne correspond pas vraiment à cela. –

3

Le régularisateur est délicat d'une manière qu'il est seulement appelé une fois au cours la construction du modèle. En Layer.add_weight():

if regularizer is not None: 
     self.add_loss(regularizer(weight)) 

Une fois que le tenseur de perte de régularisation supplémentaire est obtenue avec regularizer(weight) et ajouté au modèle, l'objet régularisateur lui-même est inutile et se est jeté. L'enregistrement de l'époque (en tant que int ou float) à l'intérieur de l'objet de régularisation ne fonctionnera pas.

Si vous voulez une valeur qui peut être manipulée pendant l'entraînement, vous devez faire une époque Variable, et l'inclure dans le calcul du tenseur de perte de régularisation. Par exemple,

epoch_variable = K.variable(0.) 

class MyRegularizer(Regularizer): 
    def __init__(self, epoch_variable): 
     self.epoch_variable = epoch_variable 

    def __call__(self, x): 
     # just to show that epoch is updated and used in loss computation 
     return self.epoch_variable ** 2 

model = Sequential() 
model.add(Dense(100, input_shape=(10,), kernel_regularizer=MyRegularizer(epoch_variable))) 
model.add(Dense(1)) 
model.compile(loss='binary_crossentropy', optimizer='adam') 

Pour mettre à jour la valeur de epoch_variable, utilisez un rappel personnalisé:

class MyCallback(Callback): 
    def __init__(self, epoch_variable): 
     self.epoch_variable = epoch_variable 

    def on_epoch_begin(self, epoch, logs=None): 
     K.set_value(self.epoch_variable, epoch + 1) 

model.fit(X, Y, callbacks=[MyCallback(epoch_variable)]) 

Vous devriez voir quelque chose comme:

Epoch 1/10 
100/100 [==============================] - 0s - loss: 3.0042 
Epoch 2/10 
100/100 [==============================] - 0s - loss: 4.9652 
Epoch 3/10 
100/100 [==============================] - 0s - loss: 9.9544 
Epoch 4/10 
100/100 [==============================] - 0s - loss: 16.7814 
Epoch 5/10 
100/100 [==============================] - 0s - loss: 25.7923 
Epoch 6/10 
100/100 [==============================] - 0s - loss: 36.7659 
Epoch 7/10 
100/100 [==============================] - 0s - loss: 49.7384 
Epoch 8/10 
100/100 [==============================] - 0s - loss: 64.7239 
Epoch 9/10 
100/100 [==============================] - 0s - loss: 81.7514 
Epoch 10/10 
100/100 [==============================] - 0s - loss: 100.7349