Как сгруппировать гистограммы, показанные на тензорной доске в Keras? - PullRequest
0 голосов
/ 19 июня 2020
• 1000 цифры MNIST от 0 до 4. Функция создания сводок, показанных на тензорной доске, следующая:
def run(run_dir, hparams):
    with tf.summary.create_file_writer(run_dir).as_default() as summ:
        hp.hparams(hparams)  # record the values used in this trial
        num_layers = 5
        m = train_test_model(hparams, run_dir, num_layers=num_layers)
        with tf.name_scope("init_lr_{}".format(
                 hparams[HP_INITIAL_LEARNING_RATE])):
            for i,l in enumerate(m.layers[1:]):
                #print(l.get_config())
                if "batch_normalization" in l.get_config()['name']:
                    w, b,c,d = l.get_weights()
                    tf.summary.histogram(name='W%d'%i, data=w, step=1, description="weigths of " + l.get_config()['name'])
                    tf.summary.histogram(name='B%d'%i, data=b, step=1, description="biases of " + l.get_config()['name'])
                else:
                    w, b = l.get_weights()
                    tf.summary.histogram(name='W%d'%i, data=w, step=1, description="weigths of " + l.get_config()['name'])
                    tf.summary.histogram(name='B%d'%i, data=b, step=1, description="biases of " + l.get_config()['name'])

train_test_model - это функция, которая обучает различные модели, используя hp.Hparam для переменных гиперпараметров. Проблема с гистограммами. С помощью этого кода графики гистограммы (весов и смещений) называются последовательно: так, например, для первой модели у меня от W_1 до W_6 и от B1 до B_6, для второй от W7 на W_12. Модель, к которой они принадлежат, показана вверху соответствующего рисунка, но я думаю, что лучше сгруппировать веса и смещения в соответствии с моделью, к которой они принадлежат, и в каждой модели иметь имена гистограмм от W_1 до W_6 и от B1 до B_6.

Примером того, что я получаю, является следующее, где каждая модель на самом деле имеет только 5 плотных слоев и 5 слоев пакетной нормализации (исключая один после слоя сглаживания): enter image description here

Чтобы решить эту проблему, я попытался добавить with tf.name_scope("init_lr_{}".format( hparams[HP_INITIAL_LEARNING_RATE])):, но это не решило проблемы: он продолжает показывать предыдущие графики с предыдущими именами и показывает другие графики, как в следующее изображение, имеющее другой макет:

enter image description here

Как я могу заставить тензорную плату группировать гистограммы в соответствии с моделью NN, к которой они принадлежат? Должен ли я создавать специальную папку c для каждой обученной модели?

ПОЛНЫЙ КОД

#SET UP
import tensorflow as tf
from tensorflow import keras
from tensorboard.plugins.hparams import api as hp
import os
keras.backend.clear_session()

#LOAD DATA
(X_train_full, y_train_full), (X_test, y_test) = keras.datasets.mnist.load_data()
X_train_reduced = X_train_full[y_train_full<5]
y_train_reduced = y_train_full[y_train_full<5]
X_test_reduced = X_test[y_test<5]
y_test_reduced = y_test[y_test<5]
X_train = X_train_reduced[5000:]
y_train = y_train_reduced[5000:]
X_valid = X_train_reduced[:5000]
y_valid = y_train_reduced[:5000]

#set the hyperparameters to tune
keras.backend.clear_session()
HP_INITIAL_LEARNING_RATE = hp.HParam("initial_learning_rate", hp.Discrete([0.0001, 0.00012, 0.00015]))
HP_NUM_BATCH_SIZE        = hp.HParam("batch_size", hp.Discrete([32]))
HP_NUM_EPOCHS            = hp.HParam("epochs", hp.Discrete([180]))
HP_BETA_1                = hp.HParam("beta_1", hp.Discrete([0.95]))
HP_BETA_2                = hp.HParam("beta_2", hp.Discrete([0.9994]))
HP_DECAY_STEP            = hp.HParam("decay_step", hp.Discrete([10000]))
HP_DECAY_RATE            = hp.HParam("decay_rate", hp.Discrete([0.8]))


#function creating the summaries 
def run(run_dir, hparams):
    with tf.summary.create_file_writer(run_dir).as_default() as summ:
        hp.hparams(hparams)  # record the values used in this trial
        num_layers = 5
        m = train_test_model(hparams, run_dir, num_layers=num_layers)
        with tf.name_scope("init_lr_{}".format(
                 hparams[HP_INITIAL_LEARNING_RATE])):
            for i,l in enumerate(m.layers[1:]):
                #print(l.get_config())
                if "batch_normalization" in l.get_config()['name']:
                    w, b,c,d = l.get_weights()
                    tf.summary.histogram(name='W%d'%i, data=w, step=1, description="weigths of " + l.get_config()['name'])
                    tf.summary.histogram(name='B%d'%i, data=b, step=1, description="biases of " + l.get_config()['name'])
                    #tf.summary.histogram(name='3rd type of weight in batch %d'%i, data=c, step=1, description="3rd argument of " + l.get_config()['name'])
                    #tf.summary.histogram(name='4th type of weight in batch %d'%i, data=d, step=1, description="4th argument of " + l.get_config()['name'])
                else:
                    w, b = l.get_weights()
                    tf.summary.histogram(name='W%d'%i, data=w, step=1, description="weigths of " + l.get_config()['name'])
                    tf.summary.histogram(name='B%d'%i, data=b, step=1, description="biases of " + l.get_config()['name'])

#function creating different models according to the hyperparameters passed with 
# hparams
def train_test_model(hparams, folder, num_layers=5):
    act_fun = "elu"
    initializer = "he_normal"
    NAME = "MNIST_0-4-earl_stp-nDens_{}-{}-{}-batch_norm-btch_sz_{}-epo_{}-Adam_opt-b1_{}-b2_{}-lr_exp_dec-in_lr_{}-lr_decRate_{}-lr_decStep_{}".format(
        num_layers, act_fun, initializer, hparams[HP_NUM_BATCH_SIZE], hparams[HP_NUM_EPOCHS], hparams[HP_BETA_1], 
               hparams[HP_BETA_2], hparams[HP_INITIAL_LEARNING_RATE], hparams[HP_DECAY_RATE], hparams[HP_DECAY_STEP])
    model = keras.models.Sequential()
    model.add(keras.layers.Flatten(input_shape=[28,28]))
    input_size=28**2
    model.add(keras.layers.BatchNormalization())
    hidden_layer_neurons=100
    for i in range(num_layers):
        model.add(keras.layers.Dense(hidden_layer_neurons, activation=act_fun, kernel_initializer="he_normal"))
        model.add(keras.layers.BatchNormalization())

    model.add(keras.layers.Dense(5, activation='softmax'))
    lr_schedule = keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate = hparams[HP_INITIAL_LEARNING_RATE],
        decay_steps=hparams[HP_DECAY_STEP],
        decay_rate=hparams[HP_DECAY_RATE])
    my_opt = keras.optimizers.Adam(learning_rate=lr_schedule, beta_1=hparams[HP_BETA_1], beta_2 = hparams[HP_BETA_2])
    early_stopping_cb =   keras.callbacks.EarlyStopping(patience = 10, restore_best_weights=True)
    #model_checkpoint_cb = keras.callbacks.ModelCheckpoint("GridSearchCV.h5", save_best_only=True)
    run_index = 1 # increment every time you train the model
    logdir = os.path.join(os.curdir, folder, NAME)
    tensorboard_cb = keras.callbacks.TensorBoard(logdir, histogram_freq=1)
    callbacks = [
        early_stopping_cb,
        tensorboard_cb,  
        hp.KerasCallback(logdir, hparams),  # log hparams
        ]
    model.compile(loss='sparse_categorical_crossentropy', metrics=["accuracy"], optimizer=my_opt)
    model.fit(X_train, y_train, epochs=hparams[HP_NUM_EPOCHS], batch_size=hparams[HP_NUM_BATCH_SIZE],
              validation_data=(X_valid, y_valid), callbacks=callbacks)
    return model


session_num = 0

LOG_FOLDER='logs/batch_normalization/'
for num_batch in HP_NUM_BATCH_SIZE.domain.values:
    for epoch in HP_NUM_EPOCHS.domain.values:
        for beta_1 in HP_BETA_1.domain.values:
            for beta_2 in HP_BETA_2.domain.values:
                for initial_learning_rate in HP_INITIAL_LEARNING_RATE.domain.values:
                    for decay_rate in HP_DECAY_RATE.domain.values:
                        for decay_step in HP_DECAY_STEP.domain.values:
                            hparams = {
                                HP_NUM_BATCH_SIZE: num_batch,
                                HP_NUM_EPOCHS: epoch,
                                HP_BETA_1: beta_1,
                                HP_BETA_2: beta_2,
                                HP_INITIAL_LEARNING_RATE: initial_learning_rate,
                                HP_DECAY_RATE: decay_rate,
                                HP_DECAY_STEP: decay_step
                            }
                            #print('--- Starting trial: %s' % run_name)
                            print({h.name: hparams[h] for h in hparams})
                            run(LOG_FOLDER , hparams)
                            session_num += 1
...