Хотя на первый взгляд кажется, что скорость обучения по умолчанию может быть неуместной, реальная проблема здесь в том, что 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.