En général, trouver les propriétés physiques d'une substance synthétisée à partir des conditions de la source de synthèse est appelé un ** problème direct **, et dans la direction opposée, il est parfois exprimé comme ** résolution d'un problème inverse **.
** Effectuer une analyse inverse du modèle d'apprentissage automatique. ** **
Si les propriétés physiques peuvent être prédites par l'apprentissage automatique, il devrait être possible de rechercher une valeur d'entrée qui rend la sortie du modèle une valeur prédéterminée.
Cependant, plus la dimension d'entrée (le nombre de variables explicatives) est grande, plus l'espace à rechercher est grand, et il devrait y avoir des cas où l'analyse inverse ne peut pas être effectuée en fonction du temps de recherche et des performances de l'ordinateur.
Sans rien faire de compliqué, j'essaierai de ** rechercher la valeur d'entrée qui minimise la sortie pour le modèle de régression **.
La forêt aléatoire est utilisée comme modèle de régression pour le moment.
SMBO (Sequential Model-based Global Optimization) est utilisé comme algorithme de recherche et hyperopt est utilisé comme bibliothèque. (Il existe d'autres diverses méthodes).
En tant que modèle simple
y= x_1 {}^2 + x_2 {}^2, \qquad (x_1, x_2) \in \mathbb{R} ^2
Je pense à la correspondance. Évidemment, la valeur minimale est $ 0 $ et le point donnant cela est $ (x_1, x_2) = (0,0) $.
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
def true_function(x, y):
"""Vraie fonction"""
return x ** 2 + y ** 2
X, Y = np.mgrid[-100:100, -100:100]
Z = true_function(X, Y)
plt.rcParams["font.size"] = 10 #Augmenter la taille de la police
fig = plt.figure(figsize = (12, 9))
ax = fig.add_subplot(111, projection="3d", facecolor="w")
ax.plot_surface(X, Y, Z, cmap="rainbow", rstride=3, cstride=3)
ax.set_xlabel('x1', fontsize=15)
ax.set_ylabel('x2', fontsize=15)
ax.set_zlabel('y', fontsize=15)
plt.show()
Sur la base de la correspondance ci-dessus, un groupe d'échantillons d'entrée / sortie est généré.
Dessinez les données d'entraînement générées.
from sklearn.model_selection import train_test_split
def true_model(X):
return true_function(X[:,[0]], X[:,[1]])
X = np.random.uniform(low=-100,high=100,size=(3000,2))
Y = true_model(X)
test_size = 0.3 #Rapport de division
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=0)
fig = plt.figure(figsize = (12, 9))
ax = plt.axes(projection ="3d")
sctt = ax.scatter3D(x_train[:,0], x_train[:,1], y_train[:,0], c=y_train[:,0], s=8, alpha = 0.6,
cmap = plt.get_cmap('rainbow'), marker ='^')
plt.title("x_train, y_train")
ax.set_xlabel('x1', fontsize=15)
ax.set_ylabel('x2', fontsize=15)
ax.set_zlabel('y', fontsize=15)
plt.show()
La forêt aléatoire est entraînée avec les données d'apprentissage mentionnées précédemment et le résultat de l'inférence à partir des données de test est tiré.
Il semble que la valeur correcte puisse être estimée.
Essayez de trouver la valeur minimale par hyperopt.
Après avoir défini la fonction à minimiser, recherchez le point qui donne la valeur minimale et tracez le point obtenu au-dessus de la figure précédente.
from hyperopt import hp
from hyperopt import fmin
from hyperopt import tpe
def objective_hyperopt_by_reg(args):
"""Fonction objective pour hyperopt"""
global reg
x, y = args
return float(reg.predict([[x,y]]))
def hyperopt_exe():
"""Effectuer l'optimisation avec hyperopt"""
#Paramètres de l'espace de recherche
space = [
hp.uniform('x', -100, 100),
hp.uniform('y', -100, 100)
]
#Commencer l'exploration
best = fmin(objective_hyperopt_by_reg, space, algo=tpe.suggest, max_evals=500)
return best
best = hyperopt_exe()
print(f"best: {best}")
fig = plt.figure(figsize = (12, 9))
ax = plt.axes(projection ="3d")
sctt = ax.scatter3D(x_test[:,0], x_test[:,1], y_test[:,0], c=y_test[:,0], s=6, alpha = 0.5,
cmap = plt.get_cmap('rainbow'), marker ='^')
ax.scatter3D([best["x"]], [best["y"]], [objective_hyperopt_by_reg((best["x"], best["y"]))],
c="red", s=250, marker="*", label="minimum")
plt.title("x_test, y_pred", fontsize=18)
ax.set_xlabel('x1', fontsize=15)
ax.set_ylabel('x2', fontsize=15)
ax.set_zlabel('y', fontsize=15)
plt.legend(fontsize=15)
plt.show()
output
100%|██████████████████████████████████████████████| 500/500 [00:09<00:00, 52.54trial/s, best loss: 27.169204190118908]
best: {'x': -0.6924078319870626, 'y': -1.1731945130395605}
Un point proche du point minimum a été obtenu.
Dans cet article, nous avons effectué la procédure d'apprentissage du modèle de régression ⇒ analyse inverse sur des données simples.
Comme la dimension d'entrée était petite cette fois, nous avons pu trouver la valeur minimale par hasard, mais on s'attend à ce que divers problèmes surviennent lors de son application à des données réelles.
En outre, ** problème inverse est une analyse extrêmement absurde si elle n'est pas gérée correctement. On s'attend à ce qu'il y ait un risque de faire **.
Je veux vraiment éviter de gaspiller des efforts car j'ai posé un problème inverse malgré un tel problème.
Recommended Posts