[PYTHON] J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)

Aperçu

L'optimisation bayésienne est l'une des méthodes pour trouver la valeur maximale ou minimale d'une fonction inconnue f (x). En raison de sa nature, il convient aux cas problématiques suivants.

--La forme de «f (x)» est inconnue. On ne sait pas s'il s'agit d'un package convexe ou s'il a des propriétés bimodales. --Même si vous calculez la valeur de la fonction f (x) une fois pour une certaine entrée x, le coût augmentera (cela prendra du temps, etc.)

La diapositive suivante était facile à comprendre pour des algorithmes spécifiques et des explications mathématiques.

Introduction à l'optimisation bayésienne pour l'apprentissage automatique - Slideshare [01. Présentation de l'optimisation bayésienne](https://colab.research.google.com/github/TatsuyaKatayama/OpenFOAMandBaysianOpt_Notebooks/blob/master/01.%E3%83%99%E3%82%A4%E3%82% Ba

Ensuite, j'ai trouvé un événement que je voulais optimiser un peu, alors j'ai construit un programme pour cela.

Bibliothèque et exemple de code utilisés pour l'optimisation bayésienne

Utilisez la bibliothèque GPyOpt qui a également été utilisée dans la documentation Python Notebook mentionnée ci-dessus. Il s'agit d'une bibliothèque qui vous permet d'effectuer facilement des calculs d'optimisation bayésienne en Python, et lorsque vous écrivez un exemple de code, cela ressemble à ceci.

import GPyOpt
from numpy.core.multiarray import ndarray


def func(x: float, y: float) -> float:
    # Rosenbrock function
    #Cible de cette optimisation. La solution exacte est(x, y) = (1, 1)Au moment de f(x, y) = 0
    val = 100.0 * (y - x * x) ** 2 + (1 - x) ** 2
    print(f'f({x}, {y}) = {val}')
    return val


def func_wrapper(arr: ndarray) -> float:
    #Par défaut, tous les arguments sont passés ensemble dans le type ndarray, ce qui est difficile à comprendre.
    #Fonction de pose et d'emballage avec la fonction réelle
    return func(arr[:, 0][0], arr[:, 1][0])


if __name__ == '__main__':
    #Nom dans chaque variable(Nom de variable)-Valeur continue ou valeur discrète-Plage de valeurs.
    # type=type au lieu de continu=S'il est discret, il peut gérer des valeurs discrètes
    bounds = [
        {'name': 'x', 'type': 'continuous', 'domain': (-2, 2)},
        {'name': 'y', 'type': 'continuous', 'domain': (-1, 3)},
        # {'name': 'y', 'type': 'discrete', 'domain': tuple(range(-1, 3))},
        ]

    #Définition du problème. maximiser=Si c'est vrai, visez la maximisation
    problem = GPyOpt.methods.BayesianOptimization(func_wrapper, domain=bounds, maximize=False, verbosity=True)

    #Courir. verbosité=Lorsqu'il est défini sur True, le temps de calcul écoulé est également affiché.
    max_iter = 25
    problem.run_optimization(max_iter, verbosity=True)

    #Représentation graphique de la valeur d'évaluation et de la transition de la meilleure valeur à chaque exécution dans le processus d'optimisation
    problem.plot_convergence()

    #Meilleure solution(La meilleure note que j'ai jamais vue)Spectacle
    print(problem.x_opt, problem.fx_opt)

    #Graphique de la forme estimée de la fonction(Moyenne / dispersion)Et un graphique montrant où regarder ensuite(Fonction d'acquisition)Afficher
    problem.plot_acquisition()

** Valeur d'évaluation dans chaque implémentation et transition de la meilleure valeur ** Figure_1.png

** Graphique de la forme estimée de la fonction (moyenne / variance) et graphique montrant où chercher ensuite (fonction d'acquisition) ** Figure_2.png

Quel événement souhaitez-vous optimiser?

** Il s'agit d'un réglage de balance des blancs de l'appareil photo correspondant à la couleur de l'objectif. ** **

Je ne pense pas qu'elle sera transmise à la majorité des gens, alors je vais l'expliquer étape par étape.

Qu'est-ce que la balance des blancs?

Vous pouvez vous en faire une idée, mais même si les objets que vous prenez avec l'appareil photo sont les mêmes, La couleur de l'objet change en fonction du "type de lumière (éclairage) auquel il est exposé". Par exemple ** quand il fait beau **. Par exemple, ** dans un ciel nuageux **. Par exemple, ** lorsque vous êtes dans une pièce éclairée par une ampoule ** …….

La couleur de l'éclairage est appelée "température de couleur". De plus, le «réglage de la balance des blancs» est le processus de calcul à partir de la température de couleur, de correction de la photo et de retour à la couleur correcte.

image.png (Extrait de https://av.jpn.support.panasonic.com/support/dsc/knowhow/knowhow31.html)

Quelle est la couleur de la lentille?

L'objectif est essentiellement en verre. De plus, comme vous pouvez le voir sur le côté du verre plat, le verre a une légère "couleur". Ensuite, la lumière qui a traversé le verre, y compris la lentille, aura une légère "couleur".

De plus, les objectifs des caméras modernes ont un revêtement fin. Cela rendra la photo encore meilleure, mais ce revêtement a également une légère "couleur".

image.png (Extrait de https://av.jpn.support.panasonic.com/support/dsc/knowhow/knowhow17.html)

De plus, tous les fabricants n'utilisent pas le même revêtement de verre, et Le type et le nombre d'objectifs utilisés diffèrent pour chaque objectif d'appareil photo. Par conséquent, ** chaque objectif de caméra présente une légère différence de couleur **.

Cependant, le revêtement, qui est une technologie spécifique au fabricant, a un effet plus fort, et la situation est "différence entre les fabricants de lentilles> différence de verre". (Eh bien, même le même fabricant peut avoir des couleurs différentes selon la marque.)

Ce cas

Habituellement, Panasonic LUMIX G9 PRO et [LEICA DG LENS] de Panasonic (https://panasonic.jp/dc/lens/leica_dg_lens. J'ai joint du html), mais j'utilise parfois objectif M.ZUIKO PRO. Cependant, les deux sont ** légèrement différents en couleur **, donc je me demandais combien de correction.

Par conséquent, en photographiant un mur blanchâtre avec le premier (* flou intentionnellement la mise au point pour faire une image uniforme), et en photographiant le même sujet ** tout en changeant la balance des blancs à chaque fois ** avec ce dernier, qui Déterminez si la valeur de réglage de la balance est appropriée comme correction.

Dans l'image ci-dessus, il n'y a qu'un seul axe de réglage de dimension appelé "température de couleur", mais le réglage de la balance des blancs du G9 PRO est "axe A (orange) -B (bleu)" et "axe G (vert) -M (rouge)". Il y a deux axes et la solution optimale est recherchée en les ajustant dans la plage de ± 9.

image.png

(Extrait de https://panasonic.jp/p-db/contents/manualdl/1428353073217.pdf)

Progresser dans l'optimisation bayésienne!

Tout d'abord, considérez la fonction que vous souhaitez optimiser. Avant cela, créez une fonction qui "lit l'image et calcule la teinte avec (R, V, B)".

from typing import Tuple
from PIL import Image
from PIL.Image import BOX
from PIL.MpoImagePlugin import MpoImageFile

def get_sample_color(path: str) -> Tuple[int, int, int]:
    """Lire le fichier image du chemin spécifié, vertical et horizontal 1/Coupez 10 espaces à partir du centre, obtenez la couleur moyenne et revenez

    :param path:nom de fichier
    :return: (R, G, B)
    """
    im: MpoImageFile = Image.open(path)
    image_size = im.size
    image_size2 = (image_size[0] / 10, image_size[1] / 10)
    left_upper_pos = ((image_size[0] - image_size2[0]) / 2, (image_size[1] - image_size2[1]) / 2)
    cropped_im = im.crop((left_upper_pos[0], left_upper_pos[1],
                          left_upper_pos[0] + image_size2[0], left_upper_pos[1] + image_size2[1]))
    resized_im = cropped_im.resize((1, 1), resample=BOX)
    data_r = resized_im.getcolors()[0][1][0]
    data_g = resized_im.getcolors()[0][1][1]
    data_b = resized_im.getcolors()[0][1][2]
    return data_r, data_g, data_b

Vous avez également besoin d'une fonction pour calculer la différence de couleur. Convertissez en espace colorimétrique YCbCr au lieu de l'espace RVB et calculez la norme L2 pour Cb et Cr.

def calc_color_diff(color1: Tuple[int, int, int], color2: Tuple[int, int, int]) -> float:
    """Calculez la différence entre les deux couleurs

    :param color1:Couleur 1
    :param color2:Couleur 2
    :return:Différence entre deux couleurs dans l'espace YCrCr
    """
    #Différence de formule JPEG YCbCr
    cb_1 = -0.1687 * color1[0] - 0.3313 * color1[1] + 0.5 * color1[2] + 128
    cr_1 = 0.5 * color1[0] - 0.4187 * color1[1] - 0.0813 * color1[2] + 128
    cb_2 = -0.1687 * color2[0] - 0.3313 * color2[1] + 0.5 * color2[2] + 128
    cr_2 = 0.5 * color2[0] - 0.4187 * color2[1] - 0.0813 * color2[2] + 128
    return (cb_1 - cb_2) ** 2 + (cr_1 - cr_2) ** 2

Et la fonction que vous souhaitez optimiser, mais contrairement à la fonction Pyhon générale, Il est nécessaire d'effectuer le processus «** Arrêtez le processus jusqu'à ce qu'il puisse être lu après avoir pris une photo **». …… Je pensais que le moyen le plus rapide était la fonction ʻinput () `, donc je l'ai implémentée en utilisant cela.

import os

def get_score(a: float, g: float) -> float:
    """Score dans les paramètres spécifiés(= Distance de la couleur standard)Calculer

    :param a:Paramètre A(ambre)La valeur du. B si c'est un nombre négatif(bleu)Devenez la couleur du côté
    :param g:Paramètre G(vert)La valeur du. S'il s'agit d'un nombre négatif, M(Magenta)Devenez la couleur du côté
    :return:La distance entre les nuances. Le plus petit sera le mieux
    """

    #Générez le nom du fichier que vous souhaitez lire
    if a >= 0.0:
        temp1 = f'A{int(a)}'
    else:
        temp1 = f'B{int(-a)}'
    if g >= 0.0:
        temp2 = f'G{int(g)}'
    else:
        temp2 = f'M{int(-g)}'
    file_name = f'MZD_{temp1}{temp2}.jpg'

    #Vérifiez si le fichier n'existe pas et laissez-le être créé s'il n'existe pas
    while not os.path.exists(file_name):
        _ = input(f'{file_name}Après la création, appuyez sur Entrée.')

    #Lire le fichier et la couleur moyenne près du centre(= Valeur mesurée)Obtenir
    mzd_rgb = get_sample_color(file_name)

    #Comparer avec la couleur des données d'échantillon
    score = calc_color_diff(mzd_rgb, base_rgb)
    print(f'a={a} g={g} score={score}')
    return score

Le reste du flux est presque le même. Veuillez noter que cette entrée (valeur de réglage de la balance des blancs) est une valeur discrète, il est donc nécessaire de définir `` type ':' discret '' pour la valeur discrète. Eh bien, comme mentionné ci-dessus, même avec «type»: «discret», la valeur entière («type int») n'est pas transmise à la fonction que vous souhaitez optimiser, mais il s'agit toujours du type «float».

from numpy.core.multiarray import ndarray

def get_score2(x: ndarray) -> float:
    """Score dans les paramètres spécifiés(= Distance par rapport à la couleur standard)Calculer"""
    return get_score(x[:, 0][0], x[:, 1][0])


if __name__ == '__main__':
    bounds = [{'name': 'a', 'type': 'discrete', 'domain': tuple(range(-9, 10))},
              {'name': 'g', 'type': 'discrete', 'domain': tuple(range(-9, 10))}]

    myProblem = GPyOpt.methods.BayesianOptimization(get_score2,
                                                    domain=bounds,
                                                    maximize=False,
                                                    verbosity=True)
    max_iter = 25
    myProblem.run_optimization(max_iter, verbosity=True)
    myProblem.plot_convergence()
    print(myProblem.x_opt, myProblem.fx_opt)
    myProblem.plot_acquisition()

Résultat d'optimisation

Ça ressemble à ça. La valeur d'évaluation étant un peu collante, la convergence était faible, mais les résultats étaient généralement satisfaisants.

Figure_1.jpg Figure_2.jpg

Si vous souhaitez le modifier davantage

"Couleur" ne concerne pas seulement la balance des blancs, mais également le contraste de l'image. Par exemple, certaines personnes estiment que le contraste est différent selon qu'il s'agit de la marque LUMIX ou de la marque LEICA.

Cette fois, je l'ai ajusté avec "Mur blanc flou (≒ 18% de gris)", donc je ne peux régler que la balance des blancs, mais En ajustant avec "Objet avec couleur blanche à noire imprimée par étapes (graphique gris)" Le degré de couleur neutre ... En d'autres termes, le contraste peut également être réglé.

Non seulement l'optimisation bayésienne, mais aussi les entrées 3D ou plus sont prises en charge, donc Si vous souhaitez effectuer des réglages plus précis, essayez de modifier le programme ci-dessus.

Recommended Posts

J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)
J'ai essayé l'optimisation bayésienne!
J'ai essayé de résoudre le problème d'optimisation des combinaisons avec Qiskit
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai essayé de commencer avec Hy
J'ai essayé d'utiliser l'optimisation bayésienne de Python
(Apprentissage automatique) J'ai essayé de comprendre attentivement la régression linéaire bayésienne avec l'implémentation
J'ai essayé de prédire l'année prochaine avec l'IA
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'utiliser lightGBM, xg boost avec Boruta
J'ai essayé d'apprendre le fonctionnement logique avec TF Learn
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé de détecter un objet avec M2Det!
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé d'utiliser Linux avec Discord Bot
J'ai essayé d'étudier DP avec séquence de Fibonacci
J'ai essayé de démarrer Jupyter avec toutes les lumières d'Amazon
J'ai essayé de juger Tundele avec Naive Bays
J'ai essayé de déboguer.
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de déplacer Faster R-CNN rapidement avec pytorch
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2 2
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
Je veux gérer l'optimisation avec python et cplex
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2
J'ai essayé de démarrer avec le script python de blender_Partie 02
J'ai essayé de générer ObjectId (clé primaire) avec pymongo
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de créer un pipeline ML avec Cloud Composer
J'ai essayé de découvrir notre obscurité avec l'API Chatwork
J'ai essayé de résumer quatre méthodes d'optimisation de réseau neuronal
[Introduction à Pytorch] J'ai essayé de catégoriser Cifar10 avec VGG16 ♬
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé d'interpoler le masque R-CNN avec un flux optique
J'ai essayé de trouver la classe alternative avec tensorflow
[Introduction à AWS] J'ai essayé de jouer avec la conversion voix-texte ♪
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
J'ai essayé de résoudre le problème d'optimisation du placement de la machine virtuelle (version simple) avec blueqat
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
J'ai essayé d'apprendre PredNet
J'ai essayé Learning-to-Rank avec Elasticsearch!
J'ai essayé d'organiser SVM.
J'ai essayé le clustering avec PyCaret