The Tuner class at Tuner_class()
can be subclassed to support advanced uses such as:
tuner %>% fit_tuner()
can be passed any arguments. These arguments will be passed directly to Tuner$run_trial
, along with a Trial object that contains information about the current trial, including hyperparameters and the status of the trial. Typically, Tuner$run_trial
is the only method that users need to override when subclassing Tuner.
Thanks to Daniel Falbel from RStudio, the Bayesian Optimization
example was successfully adapted.
library(keras)
library(tensorflow)
library(dplyr)
library(tfdatasets)
library(kerastuneR)
library(reticulate)
= function(hp) {
conv_build_model 'Builds a convolutional model.'
= tf$keras$Input(shape=c(28L, 28L, 1L))
inputs
= inputs
x
for (i in 1:hp$Int('conv_layers', 1L, 3L, default=3L)) {
= tf$keras$layers$Conv2D(filters = hp$Int(paste('filters_', i, sep = ''), 4L, 32L, step=4L, default=8L),
x kernel_size = hp$Int(paste('kernel_size_', i, sep = ''), 3L, 5L),
activation ='relu',
padding='same')(x)
if (hp$Choice(paste('pooling', i, sep = ''), c('max', 'avg')) == 'max') {
= tf$keras$layers$MaxPooling2D()(x)
x else {
} = tf$keras$layers$AveragePooling2D()(x)
x
}= tf$keras$layers$BatchNormalization()(x)
x = tf$keras$layers$ReLU()(x)
x
}if (hp$Choice('global_pooling', c('max', 'avg')) == 'max') {
= tf$keras$layers$GlobalMaxPooling2D()(x)
x else {
} = tf$keras$layers$GlobalAveragePooling2D()(x)
x
}
= tf$keras$layers$Dense(10L, activation='softmax')(x)
outputs = tf$keras$Model(inputs, outputs)
model = hp$Choice('optimizer', c('adam', 'sgd'))
optimizer %>% compile(optimizer, loss='sparse_categorical_crossentropy', metrics='accuracy')
model return(model)
}
= PyClass(
MyTuner 'Tuner',
inherit = Tuner_class(),
list(
run_trial = function(self, trial, train_ds){
= trial$hyperparameters
hp = train_ds$batch(hp$Int('batch_size', 32L, 128L, step=32L, default=64L))
train_ds = self$hypermodel$build(trial$hyperparameters)
model = hp$Float('learning_rate', 1e-4, 1e-2, sampling='log', default=1e-3)
lr = tf$keras$optimizers$Adam(lr)
optimizer = tf$keras$metrics$Mean()
epoch_loss_metric
= function(data){
run_train_step = data[[1]]
images = data[[2]]
labels
with (tf$GradientTape() %as% tape,{
= model(images)
logits = tf$keras$losses$sparse_categorical_crossentropy(labels, logits)
loss if(length(model$losses) > 0){
= loss + tf$math$add_n(model$losses)
loss
}= tape$gradient(loss, model$trainable_variables)
gradients
})$apply_gradients(purrr::transpose(list(gradients, model$trainable_variables)))
optimizer$update_state(loss)
epoch_loss_metric
loss
}
for (epoch in 1:1) {
print(paste('Epoch',epoch))
$on_epoch_begin(trial, model, epoch, logs= list())
self= make_iterator_one_shot(train_ds)
intializer
for (batch in 1:length(iterate(train_ds))) {
= iter_next(intializer)
init_next
$on_batch_begin(trial, model, batch, logs=list())
self= as.numeric(run_train_step(init_next))
batch_loss $on_batch_end(trial, model, batch, logs=list(paste('loss', batch_loss)))
self
if (batch %% 100L == 0L){
= epoch_loss_metric$result()$numpy()
loss print(paste('Batch',batch, 'Average loss', loss))
}
}
= epoch_loss_metric$result()$numpy()
epoch_loss $on_epoch_end(trial, model, epoch, logs=list('loss'= epoch_loss))
self$reset_states()
epoch_loss_metric
}
}
)
)
= function () {
main = MyTuner(
tuner oracle=BayesianOptimization(
objective=Objective(name='loss', direction = 'min'),
max_trials=1),
hypermodel=conv_build_model,
directory='results2',
project_name='mnist_custom_training2')
= dataset_fashion_mnist()
mnist_data c(mnist_train, mnist_test) %<-% mnist_data
rm(mnist_data)
$x = tf$dtypes$cast(mnist_train$x, 'float32') / 255.
mnist_train
$x = keras::k_reshape(mnist_train$x,shape = c(6e4,28,28,1))
mnist_train
= tensor_slices_dataset(mnist_train) %>% dataset_shuffle(1e3)
mnist_train
%>% fit_tuner(train_ds = mnist_train)
tuner
= tuner %>% get_best_models(1L)
best_model
}
main()