2017-07-19 4 views
1

J'essaye de créer un NN pour approximer des fonctions (sinus, cos, custom ...) mais je me bats avec le format, je ne veux pas utiliser l'entrée - étiquette, mais plutôt, entrée-sortie. Comment puis-je le changer?Approximation de fonction avec réseau neuronal - Perte 0

que je suis this tutorial

import tensorflow as tf 
import random 
from math import sin 
import numpy as np 


n_nodes_hl1 = 500 
n_nodes_hl2 = 500 
n_nodes_hl3 = 500 

n_inputs = 1 # CHANGES HERE 
n_outputs = 1 #CHANGES HERE 
batch_size = 100 

x = tf.placeholder('float', [None, n_inputs]) #CHANGES HERE 
y = tf.placeholder('float', [None, n_outputs]) #CHANGES HERE 

def neural_network_model(data): 
    hidden_layer_1 = {'weights':tf.Variable(tf.random_normal([n_inputs, n_nodes_hl1])), 
         'biases': tf.Variable(tf.random_normal([n_nodes_hl1]))} #CHANGES HERE 

    hidden_layer_2 = {'weights':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])), 
         'biases': tf.Variable(tf.random_normal([n_nodes_hl2]))} 

    hidden_layer_3 = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])), 
         'biases': tf.Variable(tf.random_normal([n_nodes_hl2]))} 

    output_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl3, n_outputs])), 
        'biases': tf.Variable(tf.random_normal([n_outputs]))} #CHANGES HERE 


    l1 = tf.add(tf.matmul(data, hidden_layer_1['weights']), hidden_layer_1['biases']) 
    l1 = tf.nn.relu(l1) 


    l2 = tf.add(tf.matmul(l1, hidden_layer_2['weights']), hidden_layer_2['biases']) 
    l2 = tf.nn.relu(l2) 

    l3 = tf.add(tf.matmul(l2, hidden_layer_3['weights']), hidden_layer_3['biases']) 
    l3 = tf.nn.relu(l3) 

    output = tf.add(tf.matmul(l3, output_layer['weights']), output_layer['biases']) 

    return output 

def train_neural_network(x): 
    prediction = neural_network_model(x) 
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y)) 

    optmizer = tf.train.AdamOptimizer().minimize(cost) 

    epochs = 10 

    with tf.Session() as sess: 
     sess.run(tf.global_variables_initializer()) 

     for epoch in range(epochs): 
      loss = 0 
      for _ in range(batch_size^2): #CHANGES HERE 
       batch_x, batch_y = generate_input_output(batch_size) #CHANGES HERE 
       a, c = sess.run([optmizer, cost], feed_dict={x: batch_x, y:batch_y}) 
       loss += c 
      print("Epoch:", epoch+1, "out of", epochs, "- Loss:", loss) 

     correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y,1)) 
     accuracy = tf.reduce_mean(tf.cast(correct, 'float')) 

     test_x, test_y = generate_input_output(batch_size) #CHANGES HERE 

     print('Accuracy', accuracy.eval({x:test_x, y:test_y})) 

def desired_function(x): #CHANGES HERE 
    return sin(x) 

def generate_input_output(batch_size): #CHANGES HERE 
    batch_x = [random.uniform(-10, 10) for _ in range(batch_size)] 
    batch_y = [desired_function(x) for x in batch_x] 
    batch_x = np.reshape(batch_x, (-1, 1)) 
    batch_y = np.reshape(batch_y, (-1, 1)) 
    return batch_x, batch_y 

train_neural_network(x) 

Répondre

0

N'a pas essayé moi-même, donc il pourrait y avoir plus de choses que vous devez changer pour obtenir le modèle à courir, mais vous voudrez certainement changer cette ligne:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y)) 

à quelque chose comme:

cost = tf.reduce_sum(tf.square(prediction - y)) 

Fondamentalement, votre la fonction de coût est beaucoup plus simple dans ce cas ... vous voulez juste réduire la somme de la différence au carré entre la sortie du réseau et la valeur y attendue.

+0

La fonction de perte Jonas Adler donné dans sa réponse est plus appropriée: coût = tf.nn.l2_loss (prédiction - y) –

1

Votre solution me semble très verbeuse. Je vais poster une solution très simplifiée, pourriez-vous préciser quelle partie de ce que vous ne comprenez pas?

import tensorflow as tf 
import numpy as np 

n_nodes_hl1 = 500 
n_nodes_hl2 = 500 
n_nodes_hl3 = 500 
batch_size = 100 

x = tf.placeholder('float', [None, 1]) 
y = tf.placeholder('float', [None, 1]) 

x1 = tf.contrib.layers.fully_connected(x, n_nodes_hl1) 
x2 = tf.contrib.layers.fully_connected(x1, n_nodes_hl2) 
x3 = tf.contrib.layers.fully_connected(x2, n_nodes_hl3) 
result = tf.contrib.layers.fully_connected(x3, 1, 
              activation_fn=None) 

loss = tf.nn.l2_loss(result - y) 

train_op = tf.train.AdamOptimizer().minimize(loss) 

with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 

    for i in range(10000): 
     xpts = np.random.rand(batch_size) * 10 
     ypts = np.sin(xpts) 

     _, loss_result = sess.run([train_op, loss], 
            feed_dict={x: xpts[:, None], 
              y: ypts[:, None]}) 

     print('iteration {}, loss={}'.format(i, loss_result)) 

Il me semble que votre solution est destinée au classement et que vous avez pas entièrement réécrit pour la régression, car il y a des choses comme softmax_cross_entropy_with_logits gauche là-bas, que vous ne voulez certainement pas dans un réseau de régression.