Нейронная сеть для подсчета элементов в тексте - PullRequest
2 голосов
/ 18 марта 2020

Проблема

Я пытаюсь создать нейронную сеть в кератах (хотя я открыт для других предложений), которая бы взяла текст (часть осмотра пациентом врача) и посчитала количество системы, которые были исследованы

Пример данных

Общее : Бдительные и ориентированные, хорошо питаются.

Глаз : EOMI, нормальный конъюнктива.

HENT : нормоцефалия c, нормальный слух, влажная слизистая оболочка полости рта, отсутствие склеральной желтухи,

шея : гибкая, без болезненные, без лимфаденопатии.

Обследование молочной железы: клинически не требуется

Скелетно-мышечная система : норма движений и сила X3 двусторонняя верхняя конечность, левая нижняя конечность, уменьшенный диапазон движений

Кожа : Кожа теплая, dry и розовая, без сыпи или повреждений, без экхимоза.

Неврология c: Пробуждение , бдительный и ориентированный X3, без очаговых дефицитов.

Психиатрия c: кооператив e, соответствующее настроение и аффект.

Правильный результат для этого примера - 8 (по количеству систем / органов, которые я выделил жирным шрифтом), исключая Breast Exam, который был упомянут, но не выполнен

Тренировочные данные и результаты

У меня есть 50k помеченных точек данных (текст + подсчет системы). Данные были очищены от элементов, которые не влияют на системы подсчета, и были лемматизированы, поэтому я бы сказал, качество входных данных это довольно хорошо.

Пока что лучшие результаты, которые я получил, это точность около 40%, что недостаточно (в идеале, я бы хотел получить точность + 90%).

Вопрос

У меня двоякий вопрос:

  1. Если в целом я двигаюсь в правильном направлении, что мешает модели давать лучшие результаты?

  2. Если есть лучший способ решения этой задачи, на что мне обратить внимание?

Спасибо

Что я пробовал

Я попробовал несколько подходов для построения модели:

  1. LS Модель ТМ с нейроном регрессии сверху (код ниже) - она ​​имеет тенденцию отдавать предпочтение одному конкретному выводу c, учитывая достаточное количество эпох, чтобы изучить - я изучил существующие вопросы по этому поводу и попробовал предложения - не помогло (например, изменение пакета) размер, используя class_weights, понижение LR et c - не помогло)
  2. Заменен LSTM с Flatten + Dense layer (s). Полученная точность никогда не превышала 40%, результат был + -1 от правильного результата
  3. Попытка увидеть это как проблему классификации, поэтому LSTM сопровождается активацией softmax. Те же результаты, что и в # 1 - очень предпочтителен один класс
  4. Удалены вложения и только что переданы токенизированные и дополненные тексты в плотные слои - не помогло
  5. Поиграл с гиперпараметрами для всех конфигураций выше: встраивание dims , скрытые единицы измерения, размер пакета, длина заполнения и т. д. c - в большинстве случаев это не помогло
  6. Я подумал о том, чтобы просто иметь словарь систем и найти их вхождения в тексте. Но это будет не так просто, так как имена систем могут быть введены с ошибками, сокращены, заменены синонимом (например, «Респиратор» = «легкие» = «грудь» и т. Д. 1102 *), и нам необходимо сосчитать те системы, которые упомянуты но не рассматривается, и формулировка для таких случаев может варьироваться

Наблюдения

  1. В попытках LSTM я отслеживал потерю проверки между партиями во время обучения, и кажется, что это так постепенно не уменьшается, а скорее скачет - как если модель прогнозирует «4» для каждой выборки и в какой-то момент решает прогнозировать «9», что в целом дает лучший результат проверки
  2. Пространственное выпадение после внедрения например, точность + 10%
  3. Уменьшение размера отступа помогло с точностью (возможно, мы получаем некоторую проблему исчезающего градиента, когда в дополненных последовательностях слишком много нулей)

Код

X_train, X_test_initial, y_train, y_test = train_test_split(training_data['text'], training_data['num_exam'], test_size=0.02,
                                                        random_state=42)

    tokenizer = Tokenizer(num_words=5000,lower=True)
    tokenizer.fit_on_texts(training_data['text'])

    vocab_size = len(tokenizer.word_index) + 1

    maxlen = 40
    X_train = pad_sequences(tokenizer.texts_to_sequences(X_train), padding='post', maxlen=maxlen)
    X_test = pad_sequences(tokenizer.texts_to_sequences(X_test_initial), padding='post', maxlen=maxlen)

    embedding_dim = 50
    hidden_size = 50
    model = Sequential()
    model.add(Embedding(vocab_size, embedding_dim, input_length=maxlen))
    model.add(SpatialDropout1D(0.5))
    model.add(LSTM(hidden_size, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(1, activation='relu'))
    model.compile(optimizer='adam',
                  loss='mean_squared_error',
                  metrics=['mse'])
    model.summary()

    history = model.fit(X_train, y_train, shuffle=False,
                        epochs=20, batch_size=128, verbose=1,
                        validation_split=0.02)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...