Tengo dos listas de datos (x1, y1), (x2, y2) ...

No conozco la ecuación entre x e y. Entonces, traté de usar una red neuronal para encontrarlo.

El archivo hyperbolic.txt tiene (x1, y1), (x2, y2) ...

Los códigos están a continuación, pero no funciona.

ValueError: Cannot feed value of shape (30,) for Tensor 'Placeholder:0', which has shape '(?, 1)'

Supongo que la forma de np_poses_x, np_poses_y podría estar mal, pero no se me ocurre cómo cambiarla.

  • Creo que ambos deberían tener (30,1) forma.
import tensorflow as tf
import numpy as np
from tqdm import tqdm
import random

class datasource(object):
    def __init__(self, xx, yy):
        self.x = xx
        self.y = yy

def get_data(directory, dataset):
    xx = []
    yy = []

    with open(directory+dataset) as f:
        for line in f:
            p0,p1 = line.split()
            p0 = float(p0)
            p1 = float(p1)
            xx.append((p0))
            yy.append((p1))

    return datasource(xx, yy)


def gen_data(source):
    while True:
        indices = list(range(len(source.x)))
        random.shuffle(indices)
        for i in indices:
            yval = source.x[i]
            xval = source.y[i]
            yield xval, yval

def gen_data_batch(source, batch_size):
    data_gen = gen_data(source)
    while True:
        x_batch = []
        y_batch = []

        for _ in range(batch_size):
            _x, _y = next(data_gen)
            x_batch.append(_x)
            y_batch.append(_y)

        yield np.array(x_batch), np.array(y_batch)

X1 = tf.placeholder(tf.float32, shape=[None, 1])
Y = tf.placeholder(tf.float32, shape=[None, 1])

W1 = tf.Variable(tf.random_normal([1, 50], stddev=0.01))
L1 = tf.nn.relu(tf.matmul(X1, W1))

W2 = tf.Variable(tf.random_normal([50, 256], stddev=0.01))
L2 = tf.nn.relu(tf.matmul(L1, W2))

W3 = tf.Variable(tf.random_normal([256, 1], stddev=0.01))
model = tf.matmul(L2, W3)

cost = tf.reduce_mean(tf.square(model-Y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

datasource = get_data('', 'hyperbolic.txt')

max_iterations = 100000
batch = 30
data_gen = gen_data_batch(datasource, batch)
for i in range(max_iterations):
    np_poses_x, np_poses_y = next(data_gen)
    feed = {X1: np_poses_x, model: np_poses_y}
    sess.run(optimizer, feed_dict=feed)
    np_loss = sess.run(cost, feed_dict=feed)
2
Wooni 25 ago. 2020 a las 14:56

1 respuesta

La mejor respuesta

Lo hiciste bien, necesitas alimentar tu red con un tensor (N,1) y no con un tensor (N,).

La solución más fácil podría ser agregar la nueva dimensión en el lado numérico, usando np.newaxis (que es None) o la función np.reshape.

Entonces puede aplicar esto en gen_data_batch, reemplazando yield np.array(x_batch), np.array(y_batch) por yield np.array(x_batch)[:, np.newaxis], np.array(y_batch)[:, np.newaxis] por ejemplo.

También puede agregar este nuevo eje en np_poses_x y np_poses_y:

feed = {X1: np_poses_x.reshape((len(np_poses_x), 1)),
        model: np_poses_y.reshape((len(np_poses_y), 1))}
1
NiziL 25 ago. 2020 a las 13:49