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

TensorFlow: аппроксимация функции

Я написал простую программу TensorFlow, которая не работает. Вот проблема, которую я пытаюсь решить. Учитывая x в качестве входных данных, я хотел бы приблизительно оценить функцию, которая возвращает значение 0,0, если x находится в интервале или , и 1,0, если x находится в интервале (0,33, 0,66).

import tensorflow as tf import numpy import scipy # input and output x = tf.placeholder(tf.float32, shape=[None, 1]) y_true = tf.placeholder(tf.float32, shape=[None, 1]) # vars weights = tf.Variable(tf.zeros([1, 1])) biases = tf.Variable(tf.zeros([1])) logits = tf.matmul(x, weights) + biases y_pred = tf.nn.softmax(logits) cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_true) cost = tf.reduce_mean(cross_entropy) optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost) x_train = [ [0.1], [0.2], [0.3], [0.4], [0.5], [0.6], [0.7], [0.8], [0.9] ] y_train = [ [0.0], [0.0], [0.0], [1.0], [1.0], [1.0], [0.0], [0.0], [0.0] ] sess = tf.Session() sess.run(tf.global_variables_initializer()) for i in range(100): sess.run(optimizer, ) we, bi = sess.run([weights, biases]) print("we: %s bi: %s"%(we, bi)) answer = sess.run(y_pred, feed_dict=) print(answer) 

Значения в весах и смещениях просто неверны после тренировки. Все они равны 1, даже после первой итерации и не меняются после.

Код, который я написал, основан на некотором коде, который использовался для распознавания цифр, и я подумал, что «минимизирую» проблему до одного числа / «пикселя».

Любые идеи, что попробовать, кроме изменения количества итераций или скорости обучения?

РЕДАКТИРОВАТЬ: Таким образом, мне удалось решить мою проблему с помощью сигмоида, как предложено ниже, и с использованием большего количества слоев. Вот рабочий код:

import tensorflow as tf import numpy # consts input_num_units = 1 hidden1_num_units = 8 hidden2_num_units = 16 output_num_units = 1 # input and output x = tf.placeholder(tf.float32, shape=[None, 1]) y_true = tf.placeholder(tf.float32, shape=[None, 1]) # vars weights = < 'hidden1': tf.Variable(tf.random_normal([input_num_units, hidden1_num_units])), 'hidden2': tf.Variable(tf.random_normal([hidden1_num_units, hidden2_num_units])), 'output': tf.Variable(tf.random_normal([hidden2_num_units, output_num_units])) >biases = < 'hidden1': tf.Variable(tf.random_normal([hidden1_num_units])), 'hidden2': tf.Variable(tf.random_normal([hidden2_num_units])), 'output': tf.Variable(tf.random_normal([output_num_units])) >hidden_layer_1 = tf.add(tf.matmul(x, weights['hidden1']), biases['hidden1']) hidden_layer_1 = tf.nn.sigmoid(hidden_layer_1) hidden_layer_2 = tf.add(tf.matmul(hidden_layer_1, weights['hidden2']), biases['hidden2']) hidden_layer_2 = tf.nn.sigmoid(hidden_layer_2) output_layer = tf.matmul(hidden_layer_2, weights['output']) + biases['output'] output_value = tf.nn.sigmoid(output_layer) cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output_layer, labels=y_true)) optimizer = tf.train.AdamOptimizer(learning_rate=0.01).minimize(cost) x_train = [ [0.1], [0.2], [0.3], [0.4], [0.5], [0.6], [0.7], [0.8], [0.9] ] y_train = [ [0.75], [0.0], [0.0], [1.0], [0.5], [1.0], [0.0], [0.0], [0.0] ] sess = tf.Session() sess.run(tf.global_variables_initializer()) for i in range(10000): sess.run(optimizer, ) answer = sess.run(output_value, feed_dict=) print(answer) 

Чтобы проверить, хорошо ли работает моя модель, я на самом деле построил целый набор значений с интервалом и выяснил, что после прохождения через сеть, они произвели почти то, что я ожидал. С этим можно поиграться. Например, я заметил, что чем больше итераций я выполняю, тем более «крутой» становится функция и тем более плавной она становится, если выполняется несколько итераций.

Читайте также:  What is an html email template

Источник

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

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

Вступление

Пусть задана функция f:[x0,x1]->R

Аппроксимируем заданную функцию f формулой

Очевидно, что при равномерном распределении значений M[i] на отрезке (x0,x1) найдутся такие величины W[i], при которых формула P(x) будет наилучшим образом апроксимировать функцию f(x). При этом, для заданных значений M[i], определённых на отрезке (x0,x1) и упорядоченных по возрастанию, можно описать последовательный алгоритм вычисления величин W[i] для формулы P(x).

А вот и нейросеть

Преобразуем формулу P(x) = SUM W[i]*E(x,M[i]) к модели нейросети с одним входным нейроном, одним выходным нейроном и n нейронами скрытого слоя

  • переменная x — «входной» слой, состоящий из одного нейрона
  • — параметры «скрытого» слоя, состоящего из n нейронов и функцией активации — сигмоида
  • — параметры «выходного» слоя, состоящего из одного нейрона, который вычисляет взвешенную сумму своих входов.
  • S — сигмоида,
  • начальные параметры «скрытого» слоя K[i]=1
  • начальные параметры «скрытого» слоя B[i] равномерно распределены на отрезке (-x1,-x0)

Все параметры нейросети K, B, W и C определим обучением нейросети на образцах (x,y) значений функции f.

Сигмоида

Сигмоида — это гладкая монотонная возрастающая нелинейная функция

Программа

Используем для описания нашей нейросети пакет Tensorflow

# узел на который будем подавать аргументы функции 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 >) 

Полный текст

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 vot-chto-poluchilos">Вот что получилось

График функции и аппроксимации


  • Синий цвет — исходная функция
  • Красный цвет — аппроксимация функции

Вывод консоли


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]

Исходный код

Источник

Русские Блоги

Функция приближения с использованием нейронной сети BP-реализация Python

Основная ссылка на статьюhttps://blog.csdn.net/john_bian/article/details/79503572, Оригинальный текст является реализацией версии Matlab. Исходя из этого, используйте Python для реализации функции сетевой пары BPПриближение. Основные принципы и выводы BP нейронной сети не будут повторяться здесь, вы можете обратиться к соответствующей литературе.

Код выглядит следующим образом:

###function approximation f(x)=sin(x) ###2018.08.15 ### Функция активации использует сигмоид import numpy as np import math #import matplotlib.pyplot as plt x = np.linspace(-3,3,100) x_size = x.size y = np.zeros((x_size,1)) # print(y.size) for i in range(x_size): y[i]= math.sin(x[i]) hidesize = 10 W1 = np.random.random ((hidesize, 1)) # Вес между входным слоем и скрытым слоем B1 = np.random.random ((hidesize, 1)) # порог нейрона скрытого слоя W2 = np.random.random ((1, hidesize)) # Вес между скрытым слоем и выходным слоем B2 = np.random.random ((1,1)) # Порог нейронов выходного слоя threshold = 0.005 max_steps = 501 def sigmoid(x_): y_ = 1/(1+math.exp(-x_)) return y_ E = np.zeros ((max_steps, 1)) # ошибка изменяется с количеством итераций Y = np.zeros ((x_size, 1)) # вывод модели for k in range(max_steps): temp = 0 for i in range(x_size): hide_in = np.dot (x [i], W1) -B1 # входные данные скрытого слоя #print(x[i]) hide_out = np.zeros ((hidesize, 1)) # выходные данные скрытого слоя for j in range(hidesize): #print ("Значение <> -ого элемента - <>". формат (j, hide_in [j])) #print(j,sigmoid(j)) hide_out[j] = sigmoid(hide_in[j]) #print ("Значение <> равно <>". format (j, hide_out [j])) #print(hide_out[3]) y_out = np.dot (W2, hide_out) -B2 # вывод модели Y[i] = y_out e = y_out-y [i] # вывод модели минус фактический результат. Производная ошибка ## Обратная связь, изменить параметры dB2 = -1*threshold*e dW2 = e*threshold*np.transpose(hide_out) dB1 = np.zeros((hidesize,1)) for j in range(hidesize): dB1[j] = np.dot(np.dot(W2[0][j],sigmoid(hide_in[j])),(1-sigmoid(hide_in[j]))*(-1)*e*threshold) dW1 = np.zeros((hidesize,1)) for j in range(hidesize): dW1[j] = np.dot(np.dot(W2[0][j],sigmoid(hide_in[j])),(1-sigmoid(hide_in[j]))*x[i]*e*threshold) W1 = W1 - dW1 B1 = B1 - dB1 W2 = W2 - dW2 B2 = B2 - dB2 temp = temp + abs(e) E[k] = temp if k%100==0: print(k) 

Выше приведен код для реализации аппроксимации функции синуса, конкретная часть чертежа не размещена. Эффект итерации 500 заключается в следующем:

 500

Видно, что эффект не очень хороший, в основном по следующим причинам: во-первых, нужно получить слишком мало очков за функцию (100 баллов в приведенном выше коде), а во-вторых, число итераций еще не достигнуто. Всем известно, что нейронные сети требуют больших объемов данных и высоких вычислительных затрат. Измените параметры, выберите 600 точек и повторите 700 раз, эффект будет следующим:

700

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

Источник

Оцените статью