web-dev-qa-db-fra.com

Le réseau neuronal profond de tensorflow pour la régression prédit toujours les mêmes résultats dans un lot

J'utilise un tensorflow pour implémenter un simple perceptron multicouche pour la régression. Le code est modifié à partir du classifieur mnist standard, qui modifie uniquement le coût de sortie en MSE (utilisez tf.reduce_mean(tf.square(pred-y))), ainsi que certains paramètres de taille d'entrée et de sortie. Cependant, si j'entraîne le réseau à l'aide de la régression, après plusieurs périodes, le lot de sortie est totalement identique. par exemple:

target: 48.129, estimated: 42.634
target: 46.590, estimated: 42.634
target: 34.209, estimated: 42.634
target: 69.677, estimated: 42.634
......

J'ai essayé différentes tailles de lot, différentes initialisations, normalisation des entrées à l'aide de sklearn.preprocessing.scale (mes plages d'entrées sont très différentes). Cependant, aucun d'entre eux n'a fonctionné. J'ai également essayé l'un des exemples de Sklearn de Tensorflow ( Régression du réseau neuronal profond avec Boston Data ). Mais j'ai une autre erreur à la ligne 40:

L'objet 'module' n'a pas d'attribut 'infer_real_valued_columns_from_input'

Quelqu'un a des indices sur le problème? Merci

Mon code est listé ci-dessous, peut-être un peu long, mais très straghtforward:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
from tensorflow.contrib import learn
import matplotlib.pyplot as plt

from sklearn.pipeline import Pipeline
from sklearn import datasets, linear_model
from sklearn import cross_validation
import numpy as np

boston = learn.datasets.load_dataset('boston')
x, y = boston.data, boston.target
X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(
x, y, test_size=0.2, random_state=42)

total_len = X_train.shape[0]

# Parameters
learning_rate = 0.001
training_epochs = 500
batch_size = 10
display_step = 1
dropout_rate = 0.9
# Network Parameters
n_hidden_1 = 32 # 1st layer number of features
n_hidden_2 = 200 # 2nd layer number of features
n_hidden_3 = 200
n_hidden_4 = 256
n_input = X_train.shape[1]
n_classes = 1

# tf Graph input
x = tf.placeholder("float", [None, 13])
y = tf.placeholder("float", [None])

# Create model
def multilayer_perceptron(x, weights, biases):
    # Hidden layer with RELU activation
    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
    layer_1 = tf.nn.relu(layer_1)

    # Hidden layer with RELU activation
    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
    layer_2 = tf.nn.relu(layer_2)

    # Hidden layer with RELU activation
    layer_3 = tf.add(tf.matmul(layer_2, weights['h3']), biases['b3'])
    layer_3 = tf.nn.relu(layer_3)

    # Hidden layer with RELU activation
    layer_4 = tf.add(tf.matmul(layer_3, weights['h4']), biases['b4'])
    layer_4 = tf.nn.relu(layer_4)

    # Output layer with linear activation
    out_layer = tf.matmul(layer_4, weights['out']) + biases['out']
    return out_layer

# Store layers weight & bias
weights = {
    'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1], 0, 0.1)),
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], 0, 0.1)),
    'h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3], 0, 0.1)),
    'h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4], 0, 0.1)),
    'out': tf.Variable(tf.random_normal([n_hidden_4, n_classes], 0, 0.1))
}
biases = {
    'b1': tf.Variable(tf.random_normal([n_hidden_1], 0, 0.1)),
    'b2': tf.Variable(tf.random_normal([n_hidden_2], 0, 0.1)),
    'b3': tf.Variable(tf.random_normal([n_hidden_3], 0, 0.1)),
    'b4': tf.Variable(tf.random_normal([n_hidden_4], 0, 0.1)),
    'out': tf.Variable(tf.random_normal([n_classes], 0, 0.1))
}

# Construct model
pred = multilayer_perceptron(x, weights, biases)

# Define loss and optimizer
cost = tf.reduce_mean(tf.square(pred-y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# Launch the graph
with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())

    # Training cycle
    for Epoch in range(training_epochs):
        avg_cost = 0.
        total_batch = int(total_len/batch_size)
        # Loop over all batches
        for i in range(total_batch-1):
            batch_x = X_train[i*batch_size:(i+1)*batch_size]
            batch_y = Y_train[i*batch_size:(i+1)*batch_size]
            # Run optimization op (backprop) and cost op (to get loss value)
            _, c, p = sess.run([optimizer, cost, pred], feed_dict={x: batch_x,
                                                          y: batch_y})
            # Compute average loss
            avg_cost += c / total_batch

        # sample prediction
        label_value = batch_y
        estimate = p
        err = label_value-estimate
        print ("num batch:", total_batch)

        # Display logs per Epoch step
        if Epoch % display_step == 0:
            print ("Epoch:", '%04d' % (Epoch+1), "cost=", \
                "{:.9f}".format(avg_cost))
            print ("[*]----------------------------")
            for i in xrange(3):
                print ("label value:", label_value[i], \
                    "estimated value:", estimate[i])
            print ("[*]============================")

    print ("Optimization Finished!")

    # Test model
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    # Calculate accuracy
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    print ("Accuracy:", accuracy.eval({x: X_test, y: Y_test}))
32
Sufeng Niu

Réponse courte:

Transposez votre vecteur pred en utilisant tf.transpose(pred).

Réponse plus longue:

Le problème est que pred (les prédictions) et y (les étiquettes) n'ont pas la même forme: l'un est un vecteur ligne et l'autre un vecteur colonne. Apparemment, lorsque vous leur appliquez une opération élémentaire, vous obtenez une matrice, ce qui n'est pas ce que vous voulez.

La solution consiste à transposer le vecteur de prédiction en utilisant tf.transpose() pour obtenir un vecteur correct et donc une fonction de perte appropriée. En fait, si vous définissez la taille du lot sur 1 dans votre exemple, vous verrez que cela fonctionne même sans correction, car la transposition d'un vecteur 1x1 est une opération sans effet.

J'ai appliqué ce correctif à votre exemple de code et ai observé le comportement suivant. Avant le correctif:

Epoch: 0245 cost= 84.743440580
[*]----------------------------
label value: 23 estimated value: [ 27.47437096]
label value: 50 estimated value: [ 24.71126747]
label value: 22 estimated value: [ 23.87785912]

Et après le correctif au même moment:

Epoch: 0245 cost= 4.181439120
[*]----------------------------
label value: 23 estimated value: [ 21.64333534]
label value: 50 estimated value: [ 48.76105118]
label value: 22 estimated value: [ 24.27996063]

Vous verrez que le coût est bien inférieur et que la valeur 50 a été correctement apprise. Vous devrez ajuster le taux d’apprentissage et améliorer vos résultats, bien sûr.

26
CNugteren

Il y a probablement un problème avec le chargement de votre ensemble de données ou la mise en œuvre de l'indexation. Si vous avez uniquement modifié le coût en MSE, assurez-vous que pred et y sont correctement mis à jour et que vous ne les avez pas écrasés par une autre opération graphique.

Une autre chose pour aider au débogage serait de prédire les résultats de régression réels. Il serait également utile si vous publiez davantage de votre code afin que nous puissions voir la mise en œuvre de votre chargement de données, etc.

1
ahaque