Тонкая настройка гиперпараметров CNN для сложной классификации текста - PullRequest
1 голос
/ 26 марта 2020

Я работаю над моделью CNN для сложной классификации текста (главным образом, электронных писем и сообщений). Набор данных содержит около 100 000 записей, распределенных по 10 различным классам. Моя фактическая последовательная модель Keras имеет следующую структуру:

model = Sequential(
        [
            Embedding(
                input_dim=10000,
                output_dim=150,
                input_length=400),
            Convolution1D(
                filters=128,
                kernel_size=4,
                padding='same',
                activation='relu'),
                BatchNormalization(),
            MaxPooling1D(),
            Flatten(),
            Dropout(0.4),
            Dense(
                100,
                activation='relu'),
            Dropout(0.4),
            Dense(
                len(y_train[0]),
                activation='softmax')])

При компиляции модели я использую оптимизатор Nadam , категориальный_кросентропия потеря с LabelSmoothing установлено на 0,2.

При подгонке модели я использую 30 эпох и Размер партии , установленный на 512 . Я также использую EarlyStopping для мониторинга val_loss и терпения, установленного на 8 эпох. Размер теста установлен на 25% от набора данных.

На самом деле тренировка прекращается после 16/18 эпох со значениями, которые начинают немного колебаться после 6/7 эпохи, а затем go до тех пор, пока их не остановит EarlyStopping. Значения в среднем такие:

потери: 1,1673 - точность: 0,9674 - val_loss: 1,2464 - val_accuracy: 0,8964

с точностью тестирования, достигающей:

потеря: 1,2461 - точность: 0,8951

Теперь я хотел бы улучшить точность моего CNN, я пробовал разные гиперпараметры, но на данный момент я не был возможность получить более высокое значение. Поэтому я пытаюсь выяснить:

  1. , если еще есть возможности для улучшений (могу поспорить)
  2. , если решение заключается в тонкой настройке моих гиперпараметров и, если да, то какие мне следует изменить?
  3. , если углубление путем добавления слоев к модели может быть полезным, и если да, то как улучшить мою модель
  4. есть ли еще какие-то глубокие обучение / Нейронные сети, а не CNN, которые могут привести к лучшему результату?

Большое спасибо всем, кто поможет! :)

1 Ответ

1 голос
/ 26 марта 2020

Есть много библиотек, но я нахожу эту очень гибкой. https://github.com/keras-team/keras-tuner

Просто установите с помощью пипса.

Ваша обновленная модель, не стесняйтесь выбирать диапазон поиска.

from tensorflow import keras
from tensorflow.keras import layers
from kerastuner.tuners import RandomSearch


def build_model(hp):
    model = keras.Sequential()
    model.add(layers.Embedding(input_dim=hp.Int('input_dim',
                                        min_value=5000,
                                        max_value=10000,
                                        step = 1000),
                              output_dim=hp.Int('output_dim',
                                        min_value=200,
                                        max_value=800,
                                        step = 100),
                              input_length = 400))
    model.add(layers.Convolution1D(
                filters=hp.Int('filters',
                                        min_value=32,
                                        max_value=512,
                                        step = 32),
                kernel_size=hp.Int('kernel_size',
                                        min_value=3,
                                        max_value=11,
                                        step = 2),
                padding='same',
                activation='relu')),
    model.add(layers.BatchNormalization())
    model.add(layers.MaxPooling1D())
    model.add(layers.Flatten())
    model.add(layers.Dropout(0.4))
    model.add(layers.Dense(units=hp.Int('units',
                                        min_value=64,
                                        max_value=256,
                                        step=32),
                           activation='relu'))
    model.add(layers.Dropout(0.4))
    model.add(layers.Dense(y_train[0], activation='softmax'))
    model.compile(
    optimizer=keras.optimizers.Adam(
        hp.Choice('learning_rate',
                  values=[1e-2, 1e-3, 1e-4])),
    loss='categorical_crossentropy',
    metrics=['accuracy'])
    return model


tuner = RandomSearch(
    build_model,
    objective='val_accuracy',
    max_trials=5,
    executions_per_trial=3,
    directory='my_dir',
    project_name='helloworld')
tuner.search_space_summary()

## The following lines are based on your model


tuner.search(x, y,
             epochs=5,
             validation_data=(val_x, val_y))

models = tuner.get_best_models(num_models=2)

Вы можете попробовать заменить слои Conv1D слоями LSTM и посмотреть, улучшите ли вы производительность.

LSTM(units = 512) https://keras.io/layers/recurrent/

Если вы хотите извлечь Более значимые функции. Один из подходов, которые я нашел многообещающим, заключается в извлечении предварительно обученных функций BERT, а затем в обучении с использованием CNN / LSTM.

Отличный репозиторий для начала работы - https://github.com/UKPLab/sentence-transformers

Как только вы получите вложение предложения из BERT / X LNet, вы можете использовать эти функции для обучения другой CNN, аналогичной той, которую вы используете, за исключением, возможно, избавления от слоя внедрения, поскольку это дорого.

...