Могу ли я изменить class_weight во время обучения?

#python #tensorflow #keras #deep-learning

#python #tensorflow #keras #глубокое обучение

Вопрос:

Я хочу изменить свой class_weight во время обучения в Keras.

Я использовал метод fit_generator and Callback , подобный приведенному ниже.

 model.fit_generator(
                decoder_generator(x_train, y_train),
                steps_per_epoch=len(x_train),
                epochs=args.epochs,
                validation_data=decoder_generator(x_valid, y_valid),
                validation_steps=len(x_valid),
                callbacks=callback_list,
                class_weight=class_weights,
                verbose=1)
  

И

 class Valid_checker(keras.callbacks.Callback):
    def __init__(self, model_name, patience, val_data, x_length):
        super().__init__()
        self.best_score = 0
        self.patience = patience
        self.current_patience = 0 
        self.model_name = model_name
        self.validation_data = val_data
        self.x_length = x_length


    def on_epoch_end(self, epoch, logs={}):
        X_val, y_val = self.validation_data
        y_predict, x_predict = model.predict_generator(no_decoder_generator(X_val, y_val), steps=len(X_val))
        y_predict = np.asarray(y_predict)
        x_predict = np.asarray(x_predict)  
  

decoder_generator и no_decoder_generator являются просто пользовательским генератором.

Я хочу изменять вес класса каждый раз, когда заканчивается эпоха. Возможно ли это? Тогда как я могу сделать?

Мои данные являются несбалансированными данными, и переобучение продолжается для одного класса.

В конце эпохи я хочу увеличить вес для классов с низкой точностью, рассчитав точность по классам.

Как я могу сделать?

Ответ №1:

Как насчет простого подхода, такого как цикл по одной эпохе за раз?

 for i in range(args.epochs):
        class_weights = calculate_weights()
        model.fit_generator(
                    decoder_generator(x_train, y_train),
                    steps_per_epoch=len(x_train),
                    epochs=1,
                    validation_data=decoder_generator(x_valid, y_valid),
                    validation_steps=len(x_valid),
                    callbacks=callback_list,
                    class_weight=class_weights,
                verbose=1)
  

Не существует прямого способа использовать разные веса классов для каждой эпохи в fit_generator . Вы можете включить раннюю остановку, проверив значение model.stop_training

Пример

 import numpy as np
from keras.models import Sequential
from keras.layers import Input, Dense
from keras.models import Model
from keras.callbacks import Callback

class Valid_checker(Callback):
    def __init__(self):
        super().__init__()
        self.model = model
        self.n_epoch = 0

    def on_epoch_end(self, epoch, logs={}):   
        self.n_epoch  = 1
        if self.n_epoch == 8:
            self.model.stop_training = True

def decoder_generator():
    while True:        
        for i in range(10):
            yield np.random.rand(10,5), np.random.randint(3,size=(10,3))


inputs = Input(shape=(5,))
outputs = Dense(3, activation='relu')(inputs)
model = Model(inputs=inputs, outputs=outputs)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

for i in range(10):    
    model.fit_generator(generator=decoder_generator(),
                    class_weight={0:1/3, 1:1/3, 2:1/3},
                    steps_per_epoch=10,                    
                    epochs=1,
                    callbacks=[Valid_checker()])
    if model.stop_training:
        break
  

Комментарии:

1. Я думаю, что мог бы попробовать это. Однако в Valid_checker классе я реализовал пользовательскую раннюю остановку и сохранение модели. Итак, я думаю, что я должен вернуть текущую точность в on_epoch_end функцию. У вас есть еще какие-либо комментарии для меня?