Аппроксимация функции с помощью нейронной сети - потеря 0

Я пытаюсь создать NN для аппроксимации функций (sine, cos, custom...), но я борюсь с форматом, я не хочу использовать метку ввода, а скорее ввод-вывод. Как мне это изменить?

Я следую этому руководству

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)

person f.rodrigues    schedule 19.07.2017    source источник


Ответы (2)


Сам не пробовал, поэтому может быть что-то еще, что вам нужно изменить, чтобы модель заработала, но вы определенно захотите изменить эту строку:

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

к чему-то более похожему:

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

По сути, ваша функция стоимости в этом случае намного проще... вы просто хотите уменьшить сумму квадрата разницы между выходом сети и ожидаемым значением y.

person D. Reagan    schedule 19.07.2017
comment
Функция потерь, которую Джонас Адлер дал в своем ответе, более уместна: стоимость = tf.nn.l2_loss (прогноз - y) - person D. Reagan; 21.07.2017

Ваше решение кажется мне очень многословным. Я опубликую очень упрощенное решение, не могли бы вы указать, какую его часть вы не понимаете?

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))

Мне кажется, что ваше решение было предназначено для классификации и вы не полностью переписали его для регрессии, так как там остались такие вещи, как softmax_cross_entropy_with_logits, которые вам точно не нужны в регрессионной сети.

person Jonas Adler    schedule 19.07.2017