Aproximamos la función usando una red neuronal

Para desarrollar bibliotecas para trabajar con redes neuronales, resolveremos el problema de aproximar la función de un solo argumento utilizando algoritmos de redes neuronales para entrenamiento y predicción.


Entrada


Sea dada una función f: [x0, x1] -> R


Aproximamos la función dada f por la fórmula


P(x) = SUM W[i]*E(x,M[i]) 

donde


  • i = 1..n
  • M [i] de R
  • W [i] de R
  • E (x, M) = {0, para x <M; 1/2, con x = M; 1, para x> M

Obviamente, con una distribución uniforme de los valores de M [i] en el intervalo (x0, x1), existen tales cantidades W [i] para las cuales la fórmula P (x) se aproximará mejor a la función f (x). Además, para valores dados de M [i] definidos en el intervalo (x0, x1) y ordenados en orden ascendente, podemos describir un algoritmo secuencial para calcular las cantidades W [i] para la fórmula P (x).


Y aquí está la red neuronal.


Transformamos la fórmula P (x) = SUMA W [i] * E (x, M [i]) en un modelo de red neuronal con una neurona de entrada, una neurona de salida y n neuronas de capa oculta


 P(x) = SUM W[i]*S(K[i]*x + B[i]) + C 

donde


  • variable x - capa de "entrada" que consiste en una neurona
  • {K, B} - parámetros de la capa "oculta", que consta de n neuronas y función de activación - sigmoide
  • {W, C}: parámetros de la capa de "salida", que consta de una neurona, que calcula la suma ponderada de sus entradas.
  • S es un sigmoide

mientras que


  • parámetros iniciales de la capa "oculta" K [i] = 1
  • Los parámetros iniciales de la capa "oculta" B [i] se distribuyen uniformemente en el segmento (-x1, -x0)

Todos los parámetros de la red neuronal K, B, W y C se determinan entrenando la red neuronal en muestras (x, y) de los valores de la función f.


Sigmoide


La sigmoide es una función no lineal monotónica creciente y suave


  • S (x) = 1 / (1 + exp (-x)).

El programa


Usamos el paquete Tensorflow para describir nuestra red neuronal.


 #        x = tf.placeholder(tf.float32, [None, 1], name="x") #        y = tf.placeholder(tf.float32, [None, 1], name="y") #   nn = tf.layers.dense(x, hiddenSize, activation=tf.nn.sigmoid, kernel_initializer=tf.initializers.ones(), bias_initializer=tf.initializers.random_uniform(minval=-x1, maxval=-x0), name="hidden") #   model = tf.layers.dense(nn, 1, activation=None, name="output") #    cost = tf.losses.mean_squared_error(y, model) train = tf.train.GradientDescentOptimizer(learn_rate).minimize(cost) 

Entrenamiento


 init = tf.initializers.global_variables() with tf.Session() as session: session.run(init) for _ in range(iterations): train_dataset, train_values = generate_test_values() session.run(train, feed_dict={ x: train_dataset, y: train_values }) 

Texto completo


 import math import numpy as np import tensorflow as tf import matplotlib.pyplot as plt x0, x1 = 10, 20 #    test_data_size = 2000 #      iterations = 20000 #    learn_rate = 0.01 #   hiddenSize = 10 #    #     def generate_test_values(): train_x = [] train_y = [] for _ in range(test_data_size): x = x0+(x1-x0)*np.random.rand() y = math.sin(x) #   train_x.append([x]) train_y.append([y]) return np.array(train_x), np.array(train_y) #        x = tf.placeholder(tf.float32, [None, 1], name="x") #        y = tf.placeholder(tf.float32, [None, 1], name="y") #   nn = tf.layers.dense(x, hiddenSize, activation=tf.nn.sigmoid, kernel_initializer=tf.initializers.ones(), bias_initializer=tf.initializers.random_uniform(minval=-x1, maxval=-x0), name="hidden") #   model = tf.layers.dense(nn, 1, activation=None, name="output") #    cost = tf.losses.mean_squared_error(y, model) train = tf.train.GradientDescentOptimizer(learn_rate).minimize(cost) init = tf.initializers.global_variables() with tf.Session() as session: session.run(init) for _ in range(iterations): train_dataset, train_values = generate_test_values() session.run(train, feed_dict={ x: train_dataset, y: train_values }) if(_ % 1000 == 999): print("cost = {}".format(session.run(cost, feed_dict={ x: train_dataset, y: train_values }))) train_dataset, train_values = generate_test_values() train_values1 = session.run(model, feed_dict={ x: train_dataset, }) plt.plot(train_dataset, train_values, "bo", train_dataset, train_values1, "ro") plt.show() with tf.variable_scope("hidden", reuse=True): w = tf.get_variable("kernel") b = tf.get_variable("bias") print("hidden:") print("kernel=", w.eval()) print("bias = ", b.eval()) with tf.variable_scope("output", reuse=True): w = tf.get_variable("kernel") b = tf.get_variable("bias") print("output:") print("kernel=", w.eval()) print("bias = ", b.eval()) 

Eso es lo que paso



  • El azul es la función original.
  • Color rojo: aproximación de la función

Salida de la consola


 cost = 0.15786637365818024 cost = 0.10963975638151169 cost = 0.08536215126514435 cost = 0.06145831197500229 cost = 0.04406769573688507 cost = 0.03488277271389961 cost = 0.026663536205887794 cost = 0.021445846185088158 cost = 0.016708852723240852 cost = 0.012960446067154408 cost = 0.010525770485401154 cost = 0.008495906367897987 cost = 0.0067353141494095325 cost = 0.0057082874700427055 cost = 0.004624188877642155 cost = 0.004093789495527744 cost = 0.0038146725855767727 cost = 0.018593043088912964 cost = 0.010414039716124535 cost = 0.004842184949666262 hidden: kernel= [[1.1523403 1.181032 1.1671464 0.9644377 0.8377886 1.0919508 0.87283015 1.0875995 0.9677301 0.6194152 ]] bias = [-14.812331 -12.219926 -12.067375 -14.872566 -10.633507 -14.014006 -13.379829 -20.508204 -14.923473 -19.354435] output: kernel= [[ 2.0069902 ] [-1.0321712 ] [-0.8878887 ] [-2.0531905 ] [ 1.4293027 ] [ 2.1250408 ] [-1.578137 ] [ 4.141281 ] [-2.1264815 ] [-0.60681605]] bias = [-0.2812019] 

Código fuente


https://github.com/dprotopopov/nnfunc

Source: https://habr.com/ru/post/es428281/


All Articles