#python #keras #optimization #deep-learning #neural-network
#питон #keras #оптимизация #глубокое обучение #нейронная сеть
Вопрос:
Я настраиваю код NST и хотел поиграть с оптимизатором, в настоящее время установленным на ADAM. Я хочу реализовать оптимизатор LGBFS, но, похоже, он недоступен в библиотеке keras.optimizers.
Есть ли в любом случае, что я могу им воспользоваться?
P. S: Я самоучка = старайся, чтобы мне было легко.
Часть кода, вызывающая озабоченность, заключается в следующем:
optimizer = keras.optimizers.Adam( keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=25.0, decay_steps=100, decay_rate=0.96 ) ) base_image = preprocess_image(base_image_path) style_reference_image = preprocess_image(style_reference_image_path) combination_image = tf.Variable(preprocess_image(base_image_path)) iterations = 1000 for i in range(1, iterations 1): loss, grads = compute_loss_and_grads( combination_image, base_image, style_reference_image ) optimizer.apply_gradients([(grads, combination_image)]) if i % 250 == 0: print("Iteration %d: loss=%.2f" % (i, loss)) img = deprocess_image(combination_image.numpy()) fname = result_prefix "_at_iteration_%d.png" % i keras.preprocessing.image.save_img(fname, img)
Полный Код:
import numpy as np import tensorflow as tf from tensorflow import keras from tensorflow.keras.applications import vgg16 base_image_path = "./My_Home.jpg" style_reference_image_path = "./Van Gogh.jpg" result_prefix = "./SomeFolder" # Weights of the different loss components total_variation_weight = 1e-6 style_weight = 1e-7 content_weight = 0.05e-6 # Dimensions of the generated picture. width, height = keras.preprocessing.image.load_img(base_image_path).size ar = 1.0 #aspect_ratio_to_fix_resizing img_nrows = round(height * ar) img_ncols = round(width * ar) from IPython.display import Image, display def preprocess_image(image_path): # Util function to open, resize and format pictures into appropriate tensors img = keras.preprocessing.image.load_img( image_path, target_size=(img_nrows, img_ncols) ) img = keras.preprocessing.image.img_to_array(img) img = np.expand_dims(img, axis=0) img = vgg16.preprocess_input(img) return tf.convert_to_tensor(img) def deprocess_image(x): # Util function to convert a tensor into a valid image x = x.reshape((img_nrows, img_ncols, 3)) # Remove zero-center by mean pixel x[:, :, 0] = 103.939 #* 0.1140 x[:, :, 1] = 116.779 #* 0.5870 x[:, :, 2] = 123.68 #* 0.2989 # 'BGR'-gt;'RGB' -gt; 'GreyScale' x = x[:, :, ::-1] x = np.clip(x, 0, 255).astype("uint8") return x def gram_matrix(x): x = tf.transpose(x, (2, 0, 1)) features = tf.reshape(x, (tf.shape(x)[0], -1)) gram = tf.matmul(features, tf.transpose(features)) return gram def style_loss(style, combination): S = gram_matrix(style) C = gram_matrix(combination) channels = 3 size = img_nrows * img_ncols return tf.reduce_sum(tf.square(S - C)) / (4.0 * (channels ** 2) * (size ** 2)) # An auxiliary loss function # designed to maintain the "content" of the # base image in the generated image def content_loss(base, combination): return tf.reduce_sum(tf.square(combination - base)) # The 3rd loss function, total variation loss, # designed to keep the generated image locally coherent def total_variation_loss(x): a = tf.square( x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, 1:, : img_ncols - 1, :] ) b = tf.square( x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, : img_nrows - 1, 1:, :] ) return tf.reduce_sum(tf.pow(a b, 1.25)) """ Next, let's create a feature extraction model that retrieves the intermediate activations of VGG16 (as a dict, by name). """ # Build a VGG16 model loaded with pre-trained ImageNet weights model = vgg16.VGG16(weights="imagenet", include_top=False) # Get the symbolic outputs of each "key" layer (we gave them unique names). outputs_dict = dict([(layer.name, layer.output) for layer in model.layers]) # Set up a model that returns the activation values for every layer in # VGG16 (as a dict). feature_extractor = keras.Model(inputs=model.inputs, outputs=outputs_dict) """ Finally, here's the code that computes the style transfer loss. """ # List of layers to use for the style loss. style_layer_names = ["block1_conv1", "block1_conv2", "block2_conv1", "block3_conv1", "block3_conv2", "block4_conv1", "block5_conv1" ] # The layer to use for the content loss. content_layer_name = "block4_conv2" def compute_loss(combination_image, base_image, style_reference_image): input_tensor = tf.concat( [base_image, style_reference_image, combination_image], axis=0 ) features = feature_extractor(input_tensor) # Initialize the loss loss = tf.zeros(shape=()) # Add content loss layer_features = features[content_layer_name] base_image_features = layer_features[0, :, :, :] combination_features = layer_features[2, :, :, :] loss = loss content_weight * content_loss( base_image_features, combination_features ) # Add style loss for layer_name in style_layer_names: layer_features = features[layer_name] style_reference_features = layer_features[1, :, :, :] combination_features = layer_features[2, :, :, :] sl = style_loss(style_reference_features, combination_features) if layer_name == "block2_conv1": loss = (style_weight * 0.3) * sl elif layer_name == "block1_conv1": loss = (style_weight * 0.175) * sl elif layer_name == "block1_conv2": loss = (style_weight * 0.15) * sl elif layer_name == "block3_conv2": loss = (style_weight * 0.15) * sl elif layer_name == "block3_conv1": loss = (style_weight * 0.075) * sl elif layer_name == "block4_conv1": loss = (style_weight * 0.075) * sl elif layer_name == "block5_conv1": loss = (style_weight * 0.075) * sl # Add total variation loss loss = total_variation_weight * total_variation_loss(combination_image) return loss """ ## Add a tf.function decorator to loss amp; gradient computation To compile it, and thus make it fast. """ @tf.function def compute_loss_and_grads(combination_image, base_image, style_reference_image): with tf.GradientTape() as tape: loss = compute_loss(combination_image, base_image, style_reference_image) grads = tape.gradient(loss, combination_image) return loss, grads """ ## The training loop Repeatedly run vanilla gradient descent steps to minimize the loss, and save the resulting image every 100 iterations. We decay the learning rate by 0.96 every 100 steps. """ optimizer = keras.optimizers.Adam( keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=25.0, decay_steps=100, decay_rate=0.96 ) ) base_image = preprocess_image(base_image_path) style_reference_image = preprocess_image(style_reference_image_path) combination_image = tf.Variable(preprocess_image(base_image_path)) iterations = 6000 for i in range(1, iterations 1): loss, grads = compute_loss_and_grads( combination_image, base_image, style_reference_image ) optimizer.apply_gradients([(grads, combination_image)]) if i % 250 == 0: print("Iteration %d: loss=%.2f" % (i, loss)) img = deprocess_image(combination_image.numpy()) fname = result_prefix "_at_iteration_%d.png" % i keras.preprocessing.image.save_img(fname, img)