Оптимизатор L-GBFS для Keras на Python (с реализацией передачи нейронного стиля)?

#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)