Многослойный персептрон в Керасе странный прогноз - PullRequest
0 голосов
/ 25 апреля 2018

Я использую Keras в R для прогнозирования финансовых последовательностей. Мне нужно тренировать MLP с двумя скрытыми слоями по 40 нейронов в каждом, чтобы предсказать цены акций. Целевые данные состоят из цен на акции, а данные о поездах - из четырех лагов этих цен.

input_data выглядит так:

               price_lag_4 price_lag_3 price_lag_2 price_lag_1  price
    2018-04-13      157.73      161.21      160.28      162.21 161.37
    2018-04-16      161.21      160.28      162.21      161.37 162.60
    2018-04-17      160.28      162.21      161.37      162.60 166.10
    2018-04-18      162.21      161.37      162.60      166.10 166.44
    2018-04-19      161.37      162.60      166.10      166.44 164.91
    2018-04-20      162.60      166.10      166.44      164.91 162.30

Далее я делю данные на обучающие и целевые наборы

    train_data = input_data["2014::2017",1:4]
    train_targets = input_data["2014::2017",5]

и нормализуйте его с помощью нормализации min-max

    train_data = as.matrix(train_data)
    train_targets = as.matrix(train_targets)

    train_data = (train_data - min(train_data)) / (max(train_data) - 
    min(train_data))
    train_targets = (train_targets - min(train_targets)) / 
    (max(train_targets) - min(train_targets))

Затем я строю MLP с 4 нейронами во входном слое, 2 скрытых слоя с 40 нейронами в каждом и одним нейроном в выходном слое. Тогда мне это подходит:

    validation_split = 0.05
    model = keras_model_sequential() %>%

    layer_dense(units = 40, activation = "relu", input_shape = 
    dim(train_data)[2]) %>%
    layer_dense(units = 40, activation = "relu") %>%  
    layer_dense(units = 1, activation = "relu")

    model %>% compile(optimizer = optimizer_sgd(), loss = "mse", metrics = 
    c("mae"))

    fit(x = train_data, y = train_targets, epochs = 60, batch_size = 32, 
    validation_split = validation_split)

штуцер сошёл:

enter image description here

Trained on 956 samples, validated on 51 samples (batch_size=32, epochs=60)
Final epoch (plot to see history):
           val_loss: 0.0004162
val_mean_absolute_error: 0.0159
               loss: 0.0002706
mean_absolute_error: 0.01215

Далее, чтобы предсказать, я использую цены в 2018

validation_data = input_data["2018",1:4]
tail(validation_data)
           price_lag_4 price_lag_3 price_lag_2 price_lag_1
2018-04-13      157.73      161.21      160.28      162.21
2018-04-16      161.21      160.28      162.21      161.37
2018-04-17      160.28      162.21      161.37      162.60
2018-04-18      162.21      161.37      162.60      166.10
2018-04-19      161.37      162.60      166.10      166.44
2018-04-20      162.60      166.10      166.44      164.91

prediction_sgd = predict(object = model, x = validation_data)

tail(prediction_sgd)
          [,1]
[71,] 147.2574
[72,] 148.6506
[73,] 148.6407
[74,] 149.8874
[75,] 150.8464
[76,] 151.8221

прогнозы как-то близки к ценам

validation_targets = prices["2018"]
tail(validation_targets)
         [,1]
2018-04-13 161.37
2018-04-16 162.60
2018-04-17 166.10
2018-04-18 166.44
2018-04-19 164.91
2018-04-20 162.30

Итак, эта архитектура MLP работает как-то, но когда я меняю функцию активации на tanh, модель становится:

   validation_split = 0.05
   model = keras_model_sequential() %>%

   layer_dense(units = 40, activation = "tanh", input_shape = 
   dim(train_data)[2]) %>%
   layer_dense(units = 40, activation = "tanh") %>%  
   layer_dense(units = 1)

   model %>% compile(optimizer = optimizer_sgd(), loss = "mse", metrics = 
   c("mae"))

   history = model %>% fit(x = train_data, y = train_targets, epochs = 60, 
   batch_size = 32, validation_split = validation_split)

   Trained on 956 samples, validated on 51 samples (batch_size=32, 
   epochs=60)
   Final epoch (plot to see history):
                  val_loss: 0.0306
   val_mean_absolute_error: 0.1728
                    loss: 0.001923
       mean_absolute_error: 0.0343

enter image description here

И я получаю странные прогнозы:

    prediction_sgd = predict(object = model, x = validation_data)
    tail(prediction_sgd)
               [,1]
    [71,] 0.9751762
    [72,] 0.9749264
    [73,] 0.9750333
    [74,] 0.9750219
    [75,] 0.9747972
    [76,] 0.9749493

Когда я использую sigmoid передаточную функцию, я также получаю странные прогнозы

Следовательно, у меня есть следующие вопросы:

1) Почему предсказанные данные такие странные во втором случае? Я что-то не так делаю?

2) Нужно ли нормализовать целевые данные, то есть y ввод в функции fit?

1 Ответ

0 голосов
/ 25 апреля 2018

Проблема в том, что tanh и sigmoid имеют выходной диапазон [-1, 1] и [0, 1] соответственно.Таким образом, если у не в этом диапазоне, то сеть не может узнать это, потому что она не может предсказать эти значения.Он будет пытаться предсказать настолько высокий уровень, насколько это возможно для сети, но это только 1.

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

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