[PYTHON] [TensorFlow] Régression linéaire carrée minimale par méthode de descente de gradient (méthode de descente la plus raide)

TensorFlow: première étape

TensorFlow est une interface de programmation multi-plateforme évolutive pour la mise en œuvre et l'exécution d'algorithmes d'apprentissage automatique ........

Pour résumer brièvement, il semble que ce soit un package qui crée et exécute un flux de traitement appelé graphe de calcul. PyTorch et Keras rattrapent leur retard, mais TensorFlow est toujours très populaire.

キャプチャ.JPG

Il est plus difficile à déboguer et à comprendre que Keras. En fait, il semble que TensorFlow 2.0 a été publié, qui peut être simplement appliqué, probablement à cause des points ci-dessus.

Dans cet article, j'utiliserai la première grammaire TensorFlow. Soyez assuré même si vous avez installé TensorFlow 2.0. Vous pouvez convertir avec le code suivant ....!

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

Le style d'écriture est à peu près le suivant. 計算グラフ.JPG

Lançons-le pour le moment. Si vous installez le package TensorFlow et essayez de l'exécuter, vous obtiendrez souvent une erreur incompréhensible, alors désinstallez-le sans pitié → installez-le.

python


import os
import numpy as np
import tensorflow as tf
  
g = tf.Graph()
 
with g.as_default():
    x = tf.placeholder(dtype=tf.float32, shape=(None), name='x') #argument
    w = tf.Variable(2.0, name='weight') #Variable ①
    b = tf.Variable(0.7, name='bias')   #Variable ②
    z=w*x + b
    init=tf.global_variables_initializer()     #Initialisation variable(tf.Vous pouvez le définir dans Session, mais c'est plus simple à gérer ici)
  
with tf.Session(graph=g) as sess:
    sess.run(init)                             #Effectuer l'initialisation des variables
    for number in [1.0, 0.6, -1.8]:
        z = sess.run(z, feed_dict={x:number})  # z= w * x +Exécuter b
        print(z)                               #Imprimer le résultat du traitement

z = sess.run(z, feed_dict={x:number})

Seule cette partie est brièvement expliquée. sess.run (nom de la variable à laquelle vous voulez accéder, feed_dict = {argument: valeur que vous voulez passer à l'argument})

Allons-y régulièrement. Ensuite, faites fonctionner le tableau (tenseur). Dans TensorFlow, la valeur circulant le long du bord est appelée un tenseur dans le graphe de calcul. C'est juste un flux tenseur. Les tensols peuvent être interprétés comme des scalaires, des vecteurs et des matrices. Par exemple, la procédure est la suivante. テンソル.JPG Maintenant, exploitons le tenseur avec TensorFlow.

python


g = tf.Graph()
with g.as_default():
    x = tf.placeholder(dtype=tf.float32, shape=(None,2,3), name='input_x') #Arguments qui reçoivent le tenseur
    x2 = tf.reshape(x,shape=(-1,6),name='x2') #Transformez l'argument reçu x avec la méthode reshape
     
    print(x2) #Définition de la variable de sortie
     
    xsum=tf.reduce_sum(x2,axis=0,name='col_sum') #Total de chaque colonne
    xmean=tf.reduce_mean(x2,axis=0,name='col_mean') #Moyenne pour chaque colonne
 
with tf.Session(graph=g) as sess:
    x_array = np.arange(18).reshape(3,2,3) #Créer un tableau
    print('Column Sums:\n', sess.run(xsum, feed_dict={x:x_array}))   #Sortir la somme de chaque colonne
    print('Column Means:\n', sess.run(xmean, feed_dict={x:x_array})) #Sortie de la moyenne de chaque colonne

tf.reshape(x,shape=(-1,6),name='x2') Le point ici est que -1 est spécifié pour la forme.

Cela signifie que la définition de type est indécise et que vous devez la convertir en fonction du tableau d'entrée.

TensorFlow: Implémentation de la régression linéaire des moindres carrés

Tout d'abord, la régression linéaire quadratique minimale est d'en haut. ① Calculez la valeur prédite en utilisant la formule y = w * x + b ② (Valeur prédite par étiquette de réponse correcte) ^ 2 ③ Trouvez la valeur moyenne de ② ④ Utilisez ③ pour trouver w et b ⑤ Répétez ceci pour quelques époques

En conséquence, on peut dire que la valeur de coût a convergé lorsqu'elle se stabilise vers la valeur minimale globale. Il semble que j'ai essayé de calculer manuellement avec Excel ci-dessous. エクセル手動.JPG

Et une figure commune. Cela montre comment la valeur de coût (partie jaune d'Excel) est tracée et convergée. La fonction de coût d'une fonction linéaire devient une fonction convexe divisible. 画像.png

Jetons un coup d'œil au code réel! !! Tout d'abord, préparez les données d'entraînement

python


#Données d'entraînement
X_train = np.arange(10).reshape((10, 1))
y_train = np.array([1.0, 1.3, 3.1,2.0, 5.0, 6.3, 6.6, 7.4, 8.0, 9.0])
  
#Diagramme du modèle de régression linéaire
plt.scatter(X_train, y_train, marker='s', s=50,label='Training Data')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.tight_layout()
plt.show()

Oui, j'ai essayé de tracer avec matplotlib! ぷろっと.png

Ensuite, préparez la classe TfLinreg.

python


class TfLinreg(object):
     
    #constructeur
    def __init__(self, x_dim, learning_rate=0.01, random_seed=None):
        self.x_dim = x_dim
        self.learning_rate = learning_rate
        self.g = tf.Graph()
         
        with self.g.as_default():
            tf.set_random_seed(random_seed)
            self.build()
             
            #Initialiseur variable
            self.init_op = tf.global_variables_initializer()
     
    def build(self):
         
        #Définir un espace réservé
        self.X = tf.placeholder(dtype=tf.float32, shape=(None,self.x_dim), name='x_input')
        self.y = tf.placeholder(dtype=tf.float32, shape=(None), name='y_input')
         
        # tf.zeros:Matrice avec tous les 0 éléments
        #1x1 tenseur
        w = tf.Variable(tf.zeros(shape=(1)), name='weight')
        b = tf.Variable(tf.zeros(shape=(1)), name='bias')
         
        self.w = w
        self.b = b
         
        #Calculer la valeur prévue
        # tf.squeeze:Une fonction qui supprime une dimension et abaisse le tenseur d'une unité
        self.test = w * self.X + b
        self.z_net = tf.squeeze(w * self.X + b, name='z_net')
         
        #Valeur actuelle-Valeur prédite
        # tf.square:Prenez le carré pour chaque élément
        sqr_errors = tf.square(self.y - self.z_net, name='sqr_errors')
        self.sqr_errors = sqr_errors
         
        #Fonction de coût
        # tf.reduce_mean:Une fonction qui calcule la valeur moyenne des nombres dans la liste donnée
        self.mean_cost = tf.reduce_mean(sqr_errors, name='mean_cost')
         
        ##Créer un optimiseur
        # GradientDescentOptimizer:La méthode de descente la plus raide
        optimizer = tf.train.GradientDescentOptimizer(
            learning_rate=self.learning_rate,
            name='GradientDescent'
        )
         
        #Gradient de fonction de perte(Poids et inclinaison)Calculer
        self.optimizer = optimizer.minimize(self.mean_cost)

À ce stade, nous venons de définir la classe, donc aucun nombre spécifique n'a été défini. Un point ici. Il existe plusieurs types de méthodes de descente de gradient.

· Descente graduelle ・ Descente de gradient stochastique --SDG ・ Minibatch SGD - MSGD

Contrairement à la méthode de descente la plus raide, les paramètres sont mis à jour après la somme de toutes les erreurs. La méthode de descente de gradient probabiliste met à jour le poids de chaque donnée. Le mini-lot est une existence intermédiaire entre les deux, et l'image est qu'une énorme quantité de données est coupée et exécutée pour chaque numéro de lot.

Alors continuez. Tout d'abord, appelez le constructeur pour créer une instance.

python


#Instanciation du modèle
lrmodel = TfLinreg(x_dim=X_train.shape[1], learning_rate=0.01)

Puis effectuez l'apprentissage

python


###Apprentissage
# self.optimizer
def train_linreg(sess, model, X_train, y_train, num_epochs=10):
    #Initialisation variable
    sess.run(model.init_op)
    training_costs=[]
 
    #Même X_Répétez le train 10 fois
    for i in range(num_epochs):     
        """
        model.optimizer:Appliquer la méthode de descente rapide
        model.X:Données d'entraînement(Nombre d'étages 2)
        model.y:Corriger les données de réponse(Nombre d'étages 1)
        model.z_net:Valeur prédite(w * self.X +Calculé à partir de b)
        model.sqr_errors:Valeur actuelle-Carré prédit
        model.mean_cost:Valeur moyenne de l'erreur quadratique
        model.w:Poids après mise à jour
        model.b:Biais après mise à jour
        """
        _,X,y,z_net,sql_errors,cost,w,b= sess.run([
            model.optimizer,
            model.X,
            model.y,
            model.z_net,
            model.sqr_errors,
            model.mean_cost,
            model.w,
            model.b,
        ],feed_dict={model.X:X_train, model.y:y_train}) #Répétez la même chose 10 fois
         
        print('  ')
        print(X)
        print(y)
        print(z_net)
        print(sql_errors)
        print(cost)
        print(w)
        print(b)
         
        training_costs.append(cost)
         
    return training_costs

model.optimizer La méthode de descente la plus raide est exécutée à.

J'étais assez confus que w et b aient mis à jour les poids. Donc, la sortie est

[0.60279995] [0.09940001] Cependant, la première prédiction est effectuée en [0] [0].

Je vais le déplacer immédiatement.

python


sess = tf.Session(graph=lrmodel.g)
training_costs = train_linreg(sess, lrmodel, X_train, y_train)

Tracons la valeur du coût.

python


plt.plot(range(1,len(training_costs) + 1), training_costs)
plt.tight_layout()
plt.xlabel('Epoch')
plt.ylabel('Training Cost')
#plt.savefig('images/13_01.png', dpi=300)
plt.show()

コスト値.png

...! Vous l'avez fait, c'est convergé! !!

Ensuite, faisons une prédiction. La prédiction n'est pas difficile car elle n'appelle que la valeur prédite (z_net). Il est exécuté en insérant un tenseur du second ordre dans l'argument x_test.

python


###Prévoir
# model.z_net
def predict_linreg(sess, model, X_test):
    y_pred = sess.run(model.z_net, feed_dict={model.X:X_test})
    return y_pred

Enfin, visualisons le modèle créé avec les données d'entraînement.

python


###Diagramme du modèle de régression linéaire
#Données d'entraînement
plt.scatter(X_train, y_train, marker='s', s=50,label='Training Data')
 
#Sortie de modèle de régression linéaire à l'aide de données d'entraînement
plt.plot(range(X_train.shape[0]), predict_linreg(sess, lrmodel, X_train),color='gray'
         , marker='o', markersize=6, linewidth=3,label='LinReg Model')
 
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.tight_layout()
plt.show()

プロット1.png

L'alignement est joliment dessiné ...........! Alors c'est tout pour cette fois.

Recommended Posts

[TensorFlow] Régression linéaire carrée minimale par méthode de descente de gradient (méthode de descente la plus raide)
Analyse de régression simple par la méthode des moindres carrés
Expliquez ce qu'est la méthode de descente de gradient stochastique en l'exécutant en Python
Simulation de Deep Learning / Probabilistic Gradient Descente (SGD)
Régression linéaire
Prédiction des prix des logements (retour par régression linéaire (kaggle)) ver1.0