Невозможно правильно обучить нейронную сеть - PullRequest
1 голос
/ 06 июля 2019

Я пытаюсь обучить нейронную сеть (NN), реализованную через Keras, для реализации следующей функции.

y (n) = y (n-1) * 0,9 + x (n) * 0,1

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

import numpy as np
from keras.models import Sequential
from keras.layers.core import Activation, Dense
from keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt

train_x = np.concatenate((np.ones(100)*120,np.ones(150)*150,np.ones(150)*90,np.ones(100)*110), axis=None)
train_y = np.ones(train_x.size)*train_x[0]

alpha = 0.9

for i in range(train_x.size):
    train_y[i] = train_y[i-1]*alpha + train_x[i]*(1 - alpha)

данные train_x против графика данных train_y

Рассматриваемая функция y (n) является функцией нижних частот и заставляет значение x (n) не изменяться внезапно, как показано на графике.

Затем я делаю NN и подгоняю его к (train_x, train_y) и строю

model = Sequential()

model.add(Dense(128, kernel_initializer='normal', input_dim=1, activation='relu'))

model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))

model.add(Dense(1, kernel_initializer='normal', activation='linear'))

model.compile(loss='mean_absolute_error',
                              optimizer='adam',
                              metrics=['accuracy'])

history = model.fit(train_x, train_y, epochs=200, verbose=0)

print(history.history['loss'][-1])
plt.plot(history.history['loss'])
plt.show()

loss_plot_200_epoch

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

accuracy_plot_200_epochs

Поэтому, когда я проверяю прогноз нейронной сети по данным, которые она обучала

plt.plot(model.predict(train_x))
plt.plot(train_x)
plt.show()

train_x_vs_predict_x

Значения только немного смещены, и все. Я попытался изменить функции активации, количество нейронов и слоев, но результат все тот же. Что я делаю не так?

---- Редактировать ----

Сделано, чтобы NN принял двумерный ввод, и он работает как задумано

import numpy as np
from keras.models import Sequential
from keras.layers.core import Activation, Dense
from keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt

train_x = np.concatenate((np.ones(100)*120,np.ones(150)*150,np.ones(150)*90,np.ones(100)*110), axis=None)
train_y = np.ones(train_x.size)*train_x[0]

alpha = 0.9

for i in range(train_x.size):
    train_y[i] = train_y[i-1]*alpha + train_x[i]*(1 - alpha)

train = np.empty((500,2))

for i in range(500):
    train[i][0]=train_x[i]
    train[i][1]=train_y[i]

model = Sequential()

model.add(Dense(128, kernel_initializer='normal', input_dim=2, activation='relu'))

model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))
model.add(Dense(256, kernel_initializer='normal', activation='relu'))

model.add(Dense(1, kernel_initializer='normal', activation='linear'))

model.compile(loss='mean_absolute_error',
                              optimizer='adam',
                              metrics=['accuracy'])

history = model.fit(train, train_y, epochs=100, verbose=0)

print(history.history['loss'][-1])
plt.plot(history.history['loss'])
plt.show()

Ответы [ 2 ]

2 голосов
/ 06 июля 2019

Если я выполню ваш код, я получу следующий график для значений XY:

Plot of the X-Y values

Если я не пропустил что-то важное здесь ивы действительно кормите это своей нейронной сетью, вы, вероятно, не можете ожидать лучших результатов.Причина в том, что нейронная сеть - это просто функция, которая может рассчитать только один выходной вектор для одного входа.В вашем случае выходной вектор будет состоять только из одного элемента (вашего значения y), но, как вы можете видеть на диаграмме выше, для x = 90 не существует только одного выходного сигнала.То, что вы передаете в свою нейронную сеть, на самом деле не может быть рассчитано как функция, и, скорее всего, сеть пытается вычислить прямую линию между точкой ~ (90, 145) и ~ (150, 150).Я имею в виду «верхнюю линию» на диаграмме.

1 голос
/ 06 июля 2019

Нейронная сеть, которую вы создаете, представляет собой простой многослойный персептрон с одним входным узлом и одним выходным узлом.Это означает, что по сути это функция, которая принимает одно действительное число и возвращает одно действительное число - контекст не передается и поэтому не может рассматриваться.Выражение

model.predict(train_x)

Не вычисляет вектор-векторную функцию для вектора train_x, но оценивает функцию числа к числу для каждого числа в train_x, затем возвращает список результатов,Вот почему вы получаете плоские сегменты на графике train_x_vs_predict_x: одни и те же входные числа выдают одинаковые выходные значения каждый раз.

Учитывая это ограничение, аппроксимация на самом деле довольно хорошая.Например, сеть видела для значений x 150, много значений y, равных 150, и нескольких более низких значений, но никогда не превышающих 150. Таким образом, для значения x, равного 150, прогнозируется значение yy чуть ниже 150.

Требуемая функция, с другой стороны, ссылается на предыдущее значение функции и будет нуждаться в информации об этом при вводе.Если то, что вы пытаетесь построить, это функция, которая принимает последовательность действительных чисел и возвращает последовательность действительных чисел, вы можете сделать это с многократной повторяющейся сетью (и вам понадобится много больше обучающих данных, чем один пример последовательности), но, поскольку вы можете вычислить функцию напрямую, зачем вообще работать с нейронными сетями?Нет необходимости вырывать бензопилу, где подойдет нож для масла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...