Почему я не могу предсказать линейное уравнение (Y = 2 * x) с Керасом? - PullRequest
0 голосов
/ 14 октября 2018

Я пытался предсказать линейное уравнение (Y = 2 * x) с Керасом, но там это не удалось.

С помощью функции активации сигмоида я получаю прямоугольные предсказания, с ReLu я получаю NaN´s.

В чем причина?Как я мог изменить код, чтобы предсказать у = 2 * х.

import numpy as np
from keras.layers import Dense, Activation
from keras.models import Sequential
import matplotlib.pyplot as plt
import math
import time


x = np.arange(-100, 100, 0.5)
y = x*2

model = Sequential()

model.add(Dense(10, input_shape=(1,)))
model.add(Activation('sigmoid'))

model.add(Dense(20) )
model.add(Activation('sigmoid'))


model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='SGD', metrics=['mean_squared_error'])

t1 = time.clock()
for i in range(40):
    model.fit(x, y, epochs=1000, batch_size=len(x), verbose=0)
    predictions = model.predict(x)
    print (i," ", np.mean(np.square(predictions - y))," t: ", time.clock()-t1)

    plt.hold(False)
    plt.plot(x, y, 'b', x, predictions, 'r--')
    plt.hold(True)
    plt.ylabel('Y / Predicted Value')
    plt.xlabel('X Value')
    plt.title([str(i)," Loss: ",np.mean(np.square(predictions - y))," t: ", str(time.clock()-t1)])
    plt.pause(0.001)
#plt.savefig("fig2.png")
plt.show()

1 Ответ

0 голосов
/ 14 октября 2018

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

Почему?Потому что ваш желаемый вывод должен НЕ быть ограниченным, а использование sigmoid подразумевает ограниченный вывод.Чтобы быть более точным, ваш последний слой вычисляет вывод y как

y=\sum_i{w_i*x_i} + b

, в то время как x_i - это вывод второго последнего слоя, который активируется sigmoid, указывая, что x_i \in [0,1].По этой причине ваш вывод y ограничен как y \in [-V+b,+V+b], где V=|w_0|+|w_1|+...+|w_19|, также известный как L1 норма матрицы весов, т.е. V=L1norm(W).

Поскольку матрица весов Wбудут изучены на основе ваших данных обучения, можно с уверенностью заключить, что ваша модель будет НЕ обобщена для тех данных тестирования, значение которых выходит за пределы диапазона ( min(x_train), max(x_train) ).

Как исправить?

Мысль 1 : для этой простой задачи вам на самом деле не нужна нелинейность.Просто используйте линейный MLP следующим образом.

model = Sequential()
model.add(Dense(1, input_shape=(1,)))
model.compile(loss='mse', optimizer='adam')

Я проверил его, и он должен сходиться за 200 эпох с MSE около 1e-5.

Мысль 2 : используйте другую функцию активации, не связанную с проблемой ограниченного вывода, например, relu (примечание: tanh также не подходит по той же причине).

model = Sequential()
model.add(Dense(10, input_shape=(1,)))
model.add(Activation('relu'))
model.add(Dense(20) )
model.add(Activation('relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')

Я также тестирую эту модель, иэто должно сходиться еще быстрее с сопоставимым MSE.

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