1

Je suis nouveau à l'apprentissage automatique et Tensorflow. Actuellement, j'essaie de suivre la logique du tutoriel pour créer un modèle de régression linéaire simple de forme y = a * x (il n'y a pas de terme de biais ici). Cependant, pour une raison quelconque, le modèle ne parvient pas à converger vers la valeur correcte "a". L'ensemble de données est créé par moi dans Excel. Comme indiqué ci-dessous:La régression linéaire simple a échoué à converger dans tensorflow

enter image description here

voici mon code qui tente d'exécuter tensorflow sur cet ensemble de données fictives I généré.

import tensorflow as tf 
import pandas as pd 

w = tf.Variable([[5]],dtype=tf.float32) 
b = tf.Variable([-5],dtype=tf.float32) 
x = tf.placeholder(shape=(None,1),dtype=tf.float32) 
y = tf.add(tf.matmul(x,w),b) 

label = tf.placeholder(dtype=tf.float32) 
loss = tf.reduce_mean(tf.squared_difference(y,label)) 

data = pd.read_csv("D:\\dat2.csv") 
xs = data.iloc[:,:1].as_matrix() 
ys = data.iloc[:,1].as_matrix() 
optimizer = tf.train.GradientDescentOptimizer(0.000001).minimize(loss) 
sess = tf.InteractiveSession() 
sess.run(tf.global_variables_initializer()) 

for i in range(10000): 
    sess.run(optimizer,{x:xs,label:ys}) 
    if i%100 == 0: print(i,sess.run(w)) 
print(sess.run(w)) 

ci-dessous est l'impression dans la console ipython, comme vous pouvez le voir après itération 10000e, la valeur w est d'environ 4,53 au lieu de la valeur correcte 6. J'apprécierais vraiment si quelqu'un pouvait faire la lumière sur qu'est-ce qui ne va pas ici? J'ai joué avec différents taux d'apprentissage de 0,01 à 0,0000001, aucun des paramètres ne peut faire converger le w à 6. J'ai lu certains suggérant de normaliser la fonctionnalité à la distribution normale standard, je voudrais savoir si cette normalisation est un indispensable? sans normalisation, gradientdescent n'est pas capable de trouver la solution? Merci beaucoup!

enter image description here

+0

si le 'randbetween' a passé 0 et 0,1 au lieu de -2, 2? –

+0

Votre taux d'apprentissage est trop faible. Combien de valeurs différentes avez-vous? (combien de lignes dans votre Excel?). Si ce nombre est trop petit cela peut être un problème ... Vous devriez pouvoir converger sans aucune normalisation si vous avez assez de données (et avec une gamme assez grande) – gdelab

+0

@gdelab l'ensemble de données contient environ 160 points de données. J'ai joué avec des taux d'apprentissage beaucoup plus élevés comme 0,1 ou même 1, mais en vain. Je pensais qu'en itérant 10000 fois, le modèle devrait toujours pouvoir converger – Rookie

Répondre

1

Il est un problème de mise en forme: y et l'étiquette n'ont pas la même forme ([batch_size, 1] vs [batch_size]). En loss = tf.reduce_mean(tf.squared_difference(y, label)), cela provoque une tension d'interprétation différente de ce que vous voulez, probablement en utilisant une diffusion ... De toute façon, le résultat est que votre perte n'est pas du tout celle que vous voulez.

Pour corriger cela, il suffit de remplacer

y = tf.add(tf.matmul(x, w), b) 

par

y = tf.add(tf.matmul(x, w), b) 
y = tf.reshape(y, shape=[-1]) 

Mon code complet de travail ci-dessous:

import tensorflow as tf 
import pandas as pd 

w = tf.Variable([[4]], dtype=tf.float64) 
b = tf.Variable([10.0], dtype=tf.float64, trainable=True) 
x = tf.placeholder(shape=(None, 1), dtype=tf.float64) 
y = tf.add(tf.matmul(x, w), b) 
y = tf.reshape(y, shape=[-1]) 
label = tf.placeholder(shape=(None), dtype=tf.float64) 
loss = tf.reduce_mean(tf.squared_difference(y, label)) 

my_path = "/media/sf_ShareVM/data2.csv" 
data = pd.read_csv(my_path, sep=";") 
max_n_samples_to_use = 50 
xs = data.iloc[:max_n_samples_to_use, :1].as_matrix() 
ys = data.iloc[:max_n_samples_to_use, 1].as_matrix() 
lr = 0.000001 
optimizer = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(loss) 
sess = tf.InteractiveSession() 
sess.run(tf.global_variables_initializer()) 

for i in range(100000): 
    _, loss_value, w_value, b_value, y_val, lab_val = sess.run([optimizer, loss, w, b, y, label], {x: xs, label: ys}) 
    if i % 100 == 0: print(i, loss_value, w_value, b_value) 
    if (i%2000 == 0 and 0< i < 10000): # We use a smaller LR at first to avoid exploding gradient. It would be MUCH cleaner to use gradient clipping (by global norm) 
     lr*=2 
     optimizer = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(loss) 

print(sess.run(w)) 
+0

Bien sûr, vous pouvez supprimer les tirages que vous ne voulez pas – gdelab

+0

Vous verrez que, après les quelques premières étapes très bonnes, il converge très lentement (en particulier le biais). Pour y remédier, nous aurions besoin d'un plus grand taux d'apprentissage. Malheureusement, nous sommes aux limites du gradient explosif ici, surtout si vous conservez toutes les valeurs de vos données, c'est pourquoi nous avons besoin d'un petit taux d'apprentissage. Idéalement, vous devez couper le dégradé et utiliser un taux d'apprentissage plus élevé. – gdelab

+0

merci @ gdelab, c'est en effet la question de la mise en forme. Une fois fixé, le modèle converge vers la bonne valeur très rapidement. Merci – Rookie