• 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 слоев пакетной нормализации (исключая один после слоя сглаживания):
Чтобы решить эту проблему, я попытался добавить with tf.name_scope("init_lr_{}".format(
hparams[HP_INITIAL_LEARNING_RATE])):
, но это не решило проблемы: он продолжает показывать предыдущие графики с предыдущими именами и показывает другие графики, как в следующее изображение, имеющее другой макет:
Как я могу заставить тензорную плату группировать гистограммы в соответствии с моделью 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