Keras LSTM больше возможностей, чем меньше? - PullRequest
0 голосов
/ 04 сентября 2018

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

Я пытаюсь построить модель, которая имеет 3 функции из 3 разных входов:

  1. Текстовая последовательность
  2. Поплавок
  3. Поплавок

Теперь все три из них составляют один временной шаг. Но так как я использую перчатку для векторизации моей текстовой последовательности, используя 100 измерений, текстовая последовательность из 20 слов в конечном итоге будет иметь длину 2000. Следовательно, общий ввод на шаг имеет длину 2002 (каждый шаг шага - матрица с формой (1, 2002), с 2000 из которых исходят из одной функции.

Является ли текстовая последовательность подавляющей два числа с плавающей запятой, поэтому независимо от значения числа с плавающей запятой это не имеет отношения к предсказанию? Если так, что я могу сделать, чтобы это исправить? Возможно, вручную взвесить, сколько нужно использовать каждой функции? Код прилагается

def build_model(embedding_matrix) -> Model:
    text = Input(shape=(9, news_text.shape[1]), name='text')
    price = Input(shape=(9, 1), name='price')
    volume = Input(shape=(9, 1), name='volume')

    text_layer = Embedding(
        embedding_matrix.shape[0],
        embedding_matrix.shape[1],
        weights=[embedding_matrix]
    )(text)
    text_layer = Dropout(0.2)(text_layer)
    # Flatten the vectorized text matrix
    text_layer = Reshape((9, int_shape(text_layer)[2] * int_shape(text_layer)[3]))(text_layer)

    inputs = concatenate([
        text_layer,
        price,
        volume
    ])

    output = Convolution1D(128, 5, activation='relu')(inputs)
    output = MaxPool1D(pool_size=4)(output)
    output = LSTM(units=128, dropout=0.2, return_sequences=True)(output)
    output = LSTM(units=128, dropout=0.2, return_sequences=True)(output)
    output = LSTM(units=128, dropout=0.2)(output)
    output = Dense(units=2, activation='linear', name='output')(output)

    model = Model(
        inputs=[text, price, volume],
        outputs=[output]
   )

    model.compile(optimizer='adam', loss='mean_squared_error')

    return model

Редактировать: обратите внимание, что форма ввода в lstm - (?, 9, 2002), что означает, что сейчас 2000, исходящие из текста, рассматриваются как 2000 независимых элементов

1 Ответ

0 голосов
/ 05 сентября 2018

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

# Branch one: process text data
text_input = Input(shape=(news_text.shape[1],), name='text')

text_emb = Embedding(embedding_matrix.shape[0],embedding_matrix.shape[1],
                weights=[embedding_matrix])(text_input)

# you may alternatively use only Conv1D + MaxPool1D or
# stack multiple LSTM layers on top of each other or
# use a combination of Conv1D, MaxPool1D and LSTM
text_conv = Convolution1D(128, 5, activation='relu')(text_emb)
text_lstm = LSTM(units=128, dropout=0.2)(text_conv)

# Branch two: process float features
price_input = Input(shape=(9, 1), name='price')
volume_input = Input(shape=(9, 1), name='volume')

pv = concatenate([price_input, volume_input])

# you can also stack multiple LSTM layers on top of each other
pv_lstm = LSTM(units=128, dropout=0.2)(pv)

# merge output of branches
text_pv = concatenate([text_lstm, pv_lstm])

output = Dense(units=2, activation='linear', name='output')(text_pv)

model = Model(
    inputs=[text_input, price_input, volume_input],
    outputs=[output]
)
model.compile(optimizer='adam', loss='mean_squared_error')

Как я прокомментировал в коде, это просто простая иллюстрация. Возможно, вам потребуется дополнительно добавить или удалить слои или регуляризацию и настроить гиперпараметры.

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