¿Problemas con mi red RBF en Tensorflow?

Estoy trabajando en una red RBF usando Tensorflow, pero hay un error que aparece en la línea 112 que dice esto: ValueError: No se puede alimentar el valor de forma (40, 13) para Tensor ‘Placeholder: 0’, que tiene forma ‘( ?, 12) ‘

Aquí está mi código de abajo. Creé mi propia función de activación para mi red RBF siguiendo este tutorial . Además, si hay algo más que noten que debe solucionarse, indíquelo, porque soy muy nuevo en Tensorflow, por lo que sería útil recibir cualquier comentario que pueda obtener.

import tensorflow as tf import numpy as np import math from sklearn import datasets from sklearn.model_selection import train_test_split from tensorflow.python.framework import ops ops.reset_default_graph() RANDOM_SEED = 42 tf.set_random_seed(RANDOM_SEED) boston = datasets.load_boston() data = boston["data"] target = boston["target"] N_INSTANCES = data.shape[0] N_INPUT = data.shape[1] - 1 N_CLASSES = 3 TEST_SIZE = 0.1 TRAIN_SIZE = int(N_INSTANCES * (1 - TEST_SIZE)) batch_size = 40 training_epochs = 400 learning_rate = 0.001 display_step = 20 hidden_size = 200 target_ = np.zeros((N_INSTANCES, N_CLASSES)) data_train, data_test, target_train, target_test = train_test_split(data, target_, test_size=0.1, random_state=100) x_data = tf.placeholder(shape=[None, N_INPUT], dtype=tf.float32) y_target = tf.placeholder(shape=[None, N_CLASSES], dtype=tf.float32) # creates activation function def gaussian_function(input_layer): initial = math.exp(-2*math.pow(input_layer, 2)) return initial np_gaussian_function = np.vectorize(gaussian_function) def d_gaussian_function(input_layer): initial = -4 * input_layer * math.exp(-2*math.pow(input_layer, 2)) return initial np_d_gaussian_function = np.vectorize(d_gaussian_function) np_d_gaussian_function_32 = lambda input_layer: np_d_gaussian_function(input_layer).astype(np.float32) def tf_d_gaussian_function(input_layer, name=None): with ops.name_scope(name, "d_gaussian_function", [input_layer]) as name: y = tf.py_func(np_d_gaussian_function_32, [input_layer],[tf.float32], name=name, stateful=False) return y[0] def py_func(func, inp, Tout, stateful=True, name=None, grad=None): rnd_name = 'PyFunGrad' + str(np.random.randint(0, 1E+8)) tf.RegisterGradient(rnd_name)(grad) g = tf.get_default_graph() with g.gradient_override_map({"PyFunc": rnd_name}): return tf.py_func(func, inp, Tout, stateful=stateful, name=name) def gaussian_function_grad(op, grad): input_variable = op.inputs[0] n_gr = tf_d_gaussian_function(input_variable) return grad * n_gr np_gaussian_function_32 = lambda input_layer: np_gaussian_function(input_layer).astype(np.float32) def tf_gaussian_function(input_layer, name=None): with ops.name_scope(name, "gaussian_function", [input_layer]) as name: y = py_func(np_gaussian_function_32, [input_layer], [tf.float32], name=name, grad=gaussian_function_grad) return y[0] # end of defining activation function def rbf_network(input_layer, weights): layer1 = tf.matmul(tf_gaussian_function(input_layer), weights['h1']) layer2 = tf.matmul(tf_gaussian_function(layer1), weights['h2']) output = tf.matmul(tf_gaussian_function(layer2), weights['output']) return output weights = { 'h1': tf.Variable(tf.random_normal([N_INPUT, hidden_size], stddev=0.1)), 'h2': tf.Variable(tf.random_normal([hidden_size, hidden_size], stddev=0.1)), 'output': tf.Variable(tf.random_normal([hidden_size, N_CLASSES], stddev=0.1)) } pred = rbf_network(x_data, weights) cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y_target)) my_opt = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y_target, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) init = tf.global_variables_initializer() sess = tf.InteractiveSession() sess.run(init) # Training loop for epoch in range(training_epochs): avg_cost = 0. total_batch = int(data_train.shape[0] / batch_size) for i in range(total_batch): randidx = np.random.randint(int(TRAIN_SIZE), size=batch_size) batch_xs = data_train[randidx, :] batch_ys = target_train[randidx, :] sess.run(my_opt, feed_dict={x_data: batch_xs, y_target: batch_ys}) avg_cost += sess.run(cost, feed_dict={x_data: batch_xs, y_target: batch_ys})/total_batch if epoch % display_step == 0: print("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost)) train_accuracy = sess.run(accuracy, feed_dict={x_data: batch_xs, y_target: batch_ys}) print("Training accuracy: %.3f" % train_accuracy) test_acc = sess.run(accuracy, feed_dict={x_data: data_test, y_target: target_test}) print("Test accuracy: %.3f" % (test_acc)) sess.close() 

Como se ha dicho, debe tener N_Input = data.shape[1] .

En realidad, data.shape[0] refiere al número de realizaciones que tiene en su conjunto de datos y data.shape[1] nos dice cuántas características debe considerar la red.

El número de funciones es, por definición, el tamaño de la capa de entrada, independientemente de la cantidad de datos que propondrá (a través de feed_dict) a su red.

Además, el conjunto de datos de Boston es un problema de regresión , mientras que softmax_cross_entropy es una función de costo para el problema de clasificación . Puede probar tf.square para evaluar la distancia euclidiana entre lo que está prediciendo y lo que desea:

 cost = tf.reduce_mean(tf.square(pred - y_target)) 

Verá que su red está aprendiendo, aunque la precisión no sea muy alta.

Editar:

Su código realmente está aprendiendo bien, pero utilizó la herramienta incorrecta para medirlo.

Principalmente, sus errores aún residen en el hecho de que está tratando con un problema de regresión, no con un problema de clasificación.

En el problema de clasificación, puede evaluar la precisión de su proceso de aprendizaje continuo utilizando

 correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y_target, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 

Consiste en verificar si la clase predicha es la misma que la clase esperada, para una entrada entre x_test.

En el problema de regresión, hacerlo no tiene sentido ya que está buscando un número real, es decir, una infinidad de posibilidades desde el punto de vista de la clasificación.

En el problema de regresión, puede estimar el error (media o lo que sea) entre los valores pronosticados y los valores esperados. Podemos usar lo que sugerí a continuación:

 cost = tf.reduce_mean(tf.square(pred - y_target)) 

He modificado su código en consecuencia aquí está

 pred = rbf_network(x_data, weights) cost = tf.reduce_mean(tf.square(pred - y_target)) my_opt = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) #correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y_target, 1)) #accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) init = tf.global_variables_initializer() sess = tf.InteractiveSession() sess.run(init) plt.figure("Error evolution") plt.xlabel("N_epoch") plt.ylabel("Error evolution") tol = 5e-4 epoch, err=0, 1 # Training loop while epoch <= training_epochs and err >= tol: avg_cost = 0. total_batch = int(data_train.shape[0] / batch_size) for i in range(total_batch): randidx = np.random.randint(int(TRAIN_SIZE), size=batch_size) batch_xs = data_train[randidx, :] batch_ys = target_train[randidx, :] sess.run(my_opt, feed_dict={x_data: batch_xs, y_target: batch_ys}) avg_cost += sess.run(cost, feed_dict={x_data: batch_xs, y_target: batch_ys})/total_batch plt.plot(epoch, avg_cost, marker='o', linestyle="none", c='k') plt.pause(0.05) err = avg_cost if epoch % 10 == 0: print("Epoch: {}/{} err = {}".format(epoch, training_epochs, avg_cost)) epoch +=1 print ("End of learning process") print ("Final epoch = {}/{} ".format(epoch, training_epochs)) print ("Final error = {}".format(err) ) sess.close() 

La salida es

 Epoch: 0/400 err = 0.107879924503 Epoch: 10/400 err = 0.00520248359747 Epoch: 20/400 err = 0.000651647908274 End of learning process Final epoch = 26/400 Final error = 0.000474644409471 

Trazamos la evolución del error en el entrenamiento a través de las diferentes épocas. introduzca la descripción de la imagen aquí

También soy nuevo en Tensorflow y esta es mi primera respuesta en stackoverflow. Probé tu código y obtuve el mismo error.

Puede ver en el código de error ValueError: Cannot feed value of shape (40, 13) for Tensor 'Placeholder:0', which has shape '(?, 12) , que hay una falta de coincidencia en las formas del primer marcador de posición:

 x_data = tf.placeholder(shape=[None, N_INPUT], dtype=tf.float32) 

así que no estoy seguro de por qué el N_INPUT tiene un -1 en esta línea

 N_INPUT = data.shape[1] - 1 

He intentado eliminarlo y el código se ejecuta. Aunque parece que la red no está aprendiendo.

Si bien esta implementación hará el trabajo, no creo que sea la implementación RBF más óptima. Está utilizando un tamaño fijo de 200 centroides (unidades ocultas) en su RBF. Esto hace que los centroides no se coloquen de manera óptima y que el ancho de su función de base gaussiana no tenga un tamaño óptimo. Normalmente, los centroides deben aprenderse en una etapa previa sin supervisión mediante el uso de K Keans o cualquier otro tipo de algoritmo de agrupamiento.

Por lo tanto, su primera etapa de entrenamiento implicaría encontrar los centroides / centros de las RBF, y la segunda etapa sería la clasificación / regresión real utilizando la red RBF