В моей предыдущей статье мы рассмотрели экстрактивное суммирование и то, как оно работает. Сегодня давайте погрузимся в захватывающий мир абстрактного обобщения.

Абстрактное обобщение

Абстрактное обобщение — это сложная техника, позволяющая создать краткое и понятное изложение более длинного текста. В отличие от экстрактивного обобщения, при котором просто извлекаются ключевые предложения, абстрактное обобщение создает новое, уникальное резюме, которое отражает суть и основные идеи текста, часто используя другой язык. Этот метод требует глубокого понимания текста и способности генерировать новый язык на основе этого понимания.

Итак, вы готовы исследовать захватывающий мир абстрактного обобщения? Давай сделаем это!

Подход к абстрактному суммировщику

Мы будем выполнять абстрактное суммирование текста, используя модель seq2seq. Наш подход к проблеме можно разделить на эти широкие категории.

Введение в архитектуру seq2seq для генерации текста

  • Модель использует архитектуру кодировщика-декодера последовательностей (seq2seq) для генерации текста.
  • Кодер обрабатывает входной текст и кодирует его в вектор фиксированной длины, который затем передается декодеру.
  • Декодер использует этот вектор для генерации выходного текста.

Описание энкодера

  • Кодер состоит из двух слоев ячеек LSTM: ячеек рекуррентной нейронной сети (RNN), которые могут запоминать предыдущий ввод и использовать его для информирования о текущем выводе.
  • Первый слой обрабатывает входной текст и создает представление скрытого состояния ввода.
  • Второй слой обрабатывает скрытое состояние и создает окончательное векторное представление входных данных фиксированной длины.

Описание декодера

  • Декодер также состоит из двух слоев ячеек LSTM, причем первый слой получает вектор фиксированной длины от кодировщика в качестве своего начального ввода.
  • Первый слой создает представление скрытого состояния вектора.
  • Второй слой обрабатывает скрытое состояние и выдает текст на выходе.

Обучение и использование модели

  • Модель обучается на большом корпусе текстовых данных, где входной текст представляет собой последовательность слов, а выходной текст — следующее слово в последовательности.
  • Во время обучения модель учится предсказывать следующее слово в последовательности на основе входного текста.
  • После обучения модель можно использовать для создания нового текста, предоставляя начальный входной текст и позволяя модели предсказывать следующее слово в последовательности.
  • Архитектура кодировщика-декодера seq2seq позволяет модели изучать отношения между входными и выходными последовательностями, что позволяет ей генерировать связный текст.

Что такое модели seq2seq?

Модели Seq2seq — это тип модели машинного обучения, используемой при обработке естественного языка. Это отличный способ превратить входные последовательности в выходные последовательности! Идея состоит в том, что модель учится понимать отношения между вводом и желаемым результатом. Это позволяет ему генерировать новый связный текст на основе заданного ввода. Модели состоят из двух частей: кодера и декодера. Кодер обрабатывает входную последовательность и кодирует ее в вектор фиксированной длины, который затем передается декодеру. Декодер использует этот вектор для генерации выходной последовательности. По сути, это забавный способ заставить компьютер писать как человек!

Давайте углубимся в детали.

Поскольку абстрактное обобщение — длительный процесс, я не буду показывать каждую часть кода.

Шаг 0: предварительная обработка набора данных
Предварительная обработка набора данных — очень важный шаг не только для абстракции, но и для любого приложения НЛП. Однако основное внимание в этой статье уделяется кодировщику seq2seq, поэтому мы не будем подробно обсуждать этапы предварительной обработки. Короче говоря, мы определим функцию очистки текста, которая принимает документ в качестве входных данных и очищает его для дальнейшей обработки. Эта функция преобразует документ в нижний регистр, разбивает его на слова, расширяет сокращения, удаляет URL-адреса, HTML-теги, знаки препинания и многое другое с помощью регулярных выражений. Наконец, он удалит их из документа и вернет очищенный результат.

Шаг 1. Токенизация текста и сводных данных

Сначала мы разделили чистый набор данных на четыре переменные: train_x, test_x, train_y и test_y. train_x и train_y будут использоваться для обучения модели машинного обучения, а test_x и test_y — для оценки производительности модели.

train_x, test_x, train_y, test_y = train_test_split(New_df['document'], New_df['summary'], # split the data into training and testing sets
                                                    test_size=0.1, # use 10% of the data for testing
                                                    random_state=0) # use a fixed seed for the random number generator
del New_df# delete the original dataframe

Затем мы берем список текстов, подгоняем к нему токенизатор и считаем различную статистику о словах в текстах. Он смотрит на частоту каждого слова в текстах и ​​увеличивает счетчики в зависимости от того, меньше ли частота слова заданного порога. К концу кода вы подсчитаете общее количество слов, общую частоту всех слов, количество слов с частотой меньше порога и общую частоту слов с частотой меньше порога. .

# Initialize the Tokenizer object
Tokenizer = Tokenizer()

# Fit the Tokenizer object on the training data
Tokenizer.fit_on_texts(list(train_x))

# convert train_y and val_y to sequences
train_y = Tokenizer.texts_to_sequences(train_y)
val_y = Tokenizer.texts_to_sequences(val_y)

Шаг 3. Чтение встроенных слов.

Вы можете скачать встраивание слова Glove из Kaggle.

Далее мы читаем файл «glove.6B.100d.txt», используя кодировку utf8 и присваивая результат переменной «glove_file».

glove_file = open('<path to your embedding>/glove.6B.100d.txt', encoding = 'utf8')

Шаг 4. Определение архитектуры модели

Теперь мы определяем модель seq2seq для кодирования и декодирования последовательностей. Для моей модели я установил количество измерений в скрытом пространстве равным 128. Кодер принимает последовательность текста в качестве входных данных и обрабатывает ее с использованием входного слоя, слоя внедрения и двунаправленного слоя LSTM. Затем прямые и обратные скрытые состояния и состояния ячеек из двунаправленного LSTM объединяются, чтобы сформировать окончательные скрытые состояния и состояния ячеек кодировщика. Декодер принимает последовательность в качестве входных данных, обрабатывает ее с помощью входного слоя, слоя внедрения и слоя LSTM и выводит распределенный по времени плотный слой с активацией softmax. Окончательная модель определяется с помощью входных данных кодера и декодера и выходных данных декодера. Распечатывается сводка модели, а также строится диаграмма модели.

latent_dim = 128 # number of dimensions in the latent space

# Encoder
eInput  = Input(shape=(maxlen_text, )) # input layer for the encoder
eEmbed = Embedding(t_max_features, embed_dim, input_length=maxlen_text, weights=[t_embed], trainable=False)(eInput ) # embedding layer for the encoder

eLstm = Bidirectional(LSTM(latent_dim, return_state=True)) # bidirectional LSTM for the encoder
eOut, eFh, eFc, eBh, eBc = eLstm(eEmbed) # forward hidden state, forward cell state, backward hidden state, and backward cell state
eH= Concatenate(axis=-1, name='eH')([eFh, eBh]) # concatenate forward and backward hidden states
eC= Concatenate(axis=-1, name='eC')([eFc, eBc]) # concatenate forward and backward cell states

#Decoder
dInput = Input(shape=(None, )) # input layer for the decoder
dEmbed = Embedding(s_max_features, embed_dim, weights=[s_embed], trainable=False)(dInput) # embedding layer for the decoder
dLstm = LSTM(latent_dim*2, return_sequences=True, return_state=True, dropout=0.3, recurrent_dropout=0.2) # LSTM layer for the decoder
dOut, _, _ = dLstm(dEmbed, initial_state=[eH, eC]) # output sequence and hidden and cell states

dDense = TimeDistributed(Dense(s_max_features, activation='softmax')) # time distributed dense layer for the decoder
dOut = dDense(dOut) # output of the decoder

model = Model([eInput , dInput], dOut) # define the model with encoder and decoder inputs and decoder output
model.summary() # print model summary

Шаг 5. Соответствие модели

Теперь мы подгоняем модель с целью уменьшения потерь, используя разреженную категориальную кросс-энтропию. Я использовал оптимизатор rmsprop, который регулирует параметры модели, чтобы минимизировать потери. Код также включает механизм ранней остановки, который остановит процесс обучения, если потери при проверке не улучшились за последние две эпохи. Модель обучается в общей сложности 10 эпох с размером пакета 128 с использованием указанных данных проверки и механизма ранней остановки для обеспечения наилучших результатов.

model.compile(loss='sparse_categorical_crossentropy', optimizer='rmsprop') # compile the model with sparse categorical crossentropy loss and rmsprop optimizer
arly_stop = keras.callbacks.EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=2) # define early stopping callback with minimum validation loss as monitor and a patience of 2 epochs
model.fit([train_x, train_y[:, :-1]], train_y.reshape(train_y.shape[0], train_y.shape[1], 1)[:, 1:], epochs=10, callbacks=[early_stop], batch_size=128, verbose=2, validation_data=([val_x, val_y[:, :-1]], val_y.reshape(val_y.shape[0], val_y.shape[1], 1)[:, 1:])) # fit the model on the training data with early stopping callback and validation data, using 10 epochs and a batch size of 128, with verbose output set to 2

Шаг 6. Создайте предложения

Чтобы сгенерировать сводку, мы берем входную последовательность и в двух словах генерируем ее сводку. Код начинается с использования модели кодировщика для прогнозирования скрытых состояний и состояний ячеек входной последовательности. Затем он устанавливает следующий маркер в качестве маркера начала последовательности и пустую строку выходной последовательности. Следующим шагом является вход в цикл, который продолжается до тех пор, пока либо не будет встречен маркер конца последовательности, либо не будет достигнуто максимальное количество итераций. В каждой итерации модель декодера используется для предсказания следующего маркера, а также скрытого состояния и состояния ячейки последовательности. Выбирается токен с наибольшей вероятностью, добавляется к выходной последовательности (если это не токен начала или конца последовательности), а затем он становится следующим токеном. И так цикл продолжается до тех пор, пока не будет выполнено условие остановки.

def generate_summary(input_seq):
  h, c = eModel.predict(input_seq) # get hidden and cell state from encoder model

  next_token = np.zeros((1, 1))
  next_token[0, 0] = yTokenizer.word_index['sostok']  # set next token to start of sequence token
  output_seq = ''

  stop = False
  count = 0

  while not stop:
      if count > 100:  # maximum number of iterations
          break
      decoder_out, state_h, state_c = dModel.predict([next_token]+[h, c])  # get output from decoder model
      token_idx = np.argmax(decoder_out[0, -1, :])  # get index of predicted token
      
      if token_idx == yTokenizer.word_index['eostok']:  # end of sequence token
          stop = True
      elif token_idx > 0 and token_idx != yTokenizer.word_index['sostok']:  # exclude special tokens
          token = yTokenizer.index_word[token_idx]  # get actual word from token index
          output_seq = output_seq + ' ' + token  # append to output sequence
      
      next_token = np.zeros((1, 1))
      next_token[0, 0] = token_idx  # set next token to predicted token
      h, c = state_h, state_c  # update hidden and cell state
      count += 1
      
  return output_seq  # return generated summary sequence

Шаг 6. Получите сводку

Наконец, мы определяем функцию под названием «get_summary», которая принимает введенный пользователем текст и возвращает его сводку. Функция начинается с очистки входного текста с помощью функции «text_cleaner». Затем он преобразует очищенный текст в последовательности целых чисел с помощью метода «Tokenizer.texts_to_sequences». Затем последовательности дополняются до максимальной длины документов с помощью функции «pad_sequences». Наконец, сводка входного текста генерируется с помощью функции «generate_summary» и возвращается в качестве вывода функции «get_summary».

#get summary for one custom input
def get_summary(input_text):
    #clean the input document
    input_text = text_cleaner(input_text)
    #convert the cleaned document to sequences of integers
    input_text = Tokenizer.texts_to_sequences([input_text])
    #pad the sequences to match the maximum length of document
    input_text = pad_sequences(input_text, maxlen=maxlen_text, padding='post')
    #generate the summary
    summary = generate_summary(input_text)
    return summary

Окончательный результат

Для следующего ввода

Dougie Freedman is on the verge of agreeing a new two-year deal to remain at Nottingham Forest.
Freedman has stabilised Forest since he replaced cult hero Stuart Pearce and the club's owners are pleased with the job he has done at the City Ground. 
Dougie Freedman is set to sign a new deal at Nottingham Forest.
Freedman has impressed at the City Ground since replacing Stuart Pearce in February.
They made an audacious attempt on the play-off places when Freedman replaced Pearce but have tailed off in recent weeks.
That has not prevented Forest's ownership making moves to secure Freedman on a contract for the next two seasons.

На выходе мы получаем:

Dougie Freedman is likely to sign a new two-year deal at Nottingham Forest after impressing since replacing Stuart Pearce in February and stabilizing the club.
Despite a recent drop in performance, Forest's owners are pleased with Freedman's work and want to secure him for the next two seasons.

Некоторые применения абстрактного суммировщика в повседневной жизни

Абстрактное обобщение нашло применение в различных программных системах и платформах, особенно в области искусственного интеллекта и обработки естественного языка. Некоторые популярные примеры включают в себя:

  • Агрегаторы новостей, такие как Google News, Apple News и Flipboard, используют методы абстрактного обобщения, чтобы предоставить краткий обзор наиболее важных новостей дня на основе различных источников.
  • Чат-боты и виртуальные помощники, такие как Alexa от Amazon, Siri от Apple и Google Assistant, используют абстрактное обобщение, чтобы предоставить пользователям краткую и актуальную информацию в ответ на их запросы.
  • Системы управления контентом и платформы управления знаниями, такие как IBM Watson Discovery и Microsoft SharePoint, используют абстрактное обобщение для автоматического создания сводок больших коллекций документов, упрощая пользователям поиск необходимой информации.
  • Почтовые клиенты и приложения для обмена сообщениями, такие как Gmail и Slack, используют абстрактное суммирование, чтобы предоставить пользователям сводное представление о входящих сообщениях и уведомлениях.

Абстрактное и экстрактивное обобщение: споры продолжаются

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

В заключение, абстрактное обобщение — это мощная техника, которая создает краткое и понятное резюме более длинного текста, создавая новый язык на основе своего понимания текста. Наш подход к этой задаче использует архитектуру кодировщик-декодер последовательностей (seq2seq), где кодировщик обрабатывает входной текст и кодирует его в вектор фиксированной длины, который затем передается декодеру. Декодер использует этот вектор для генерации выходного текста. Модель seq2seq обучается на большом корпусе текстовых данных, где входной текст представляет собой последовательность слов, а выходной текст — следующее слово в последовательности. К концу процесса обучения модель может генерировать связный текст на основе заданных входных данных. Удивительно, как мы можем научить компьютер писать как человек, используя эти методы!

Спасибо, что нашли время прочитать эту статью. Совмещать аспирантуру и писательство может быть непросто, но я почувствовал вдохновение поделиться своими знаниями после прохождения курса обработки естественного языка в прошлом семестре. Для моего финального проекта я решил сосредоточиться на обобщении и надеюсь, что, написав об этом, я смогу помочь другим прояснить свое понимание этой темы.

Требуется много работы, чтобы найти и написать такую ​​статью, а хлопок или подписка 👏 от вас значит для меня весь мир 🌍. У вас это займет меньше 10 секунд, а мне поможет! Вы также можете задать мне любые вопросы, указать что-нибудь или просто написать «Привет» 👇 внизу.