Ошибка в сценарии прогнозирования с использованием модели CNN для классификации текста - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь написать прогнозную часть сценария для учебника: https://mxnet.incubator.apache.org/tutorials/nlp/cnn.html

import mxnet as mx

from collections import Counter
import os
import re
import threading
import sys
import itertools
import numpy as np

from collections import namedtuple

SENTENCES_DIR = 'C:/code/mxnet/sentences'
CURRENT_DIR = 'C:/code/mxnet'

def clean_str(string):
    string = re.sub(r"[^A-Za-z0-9(),!?\'\`]", " ", string)
    string = re.sub(r"\'s", " \'s", string)
    string = re.sub(r"\'ve", " \'ve", string)
    string = re.sub(r"n\'t", " n\'t", string)
    string = re.sub(r"\'re", " \'re", string)
    string = re.sub(r"\'d", " \'d", string)
    string = re.sub(r"\'ll", " \'ll", string)
    string = re.sub(r",", " , ", string)
    string = re.sub(r"!", " ! ", string)
    string = re.sub(r"\(", " \( ", string)
    string = re.sub(r"\)", " \) ", string)
    string = re.sub(r"\?", " \? ", string)
    string = re.sub(r"\s{2,}", " ", string)
    return string.strip().lower()

def load_data_sentences(filename):
    sentences_file = open( filename, "r")
    # Tokenize
    x_text = [line.decode('Latin1').strip() for line in sentences_file.readlines()] 
    x_text = [clean_str(sent).split(" ") for sent in x_text]
    return x_text


def pad_sentences(sentences, padding_word=""):"
    sequence_length = max(len(x) for x in sentences)
    padded_sentences = []
    for i in range(len(sentences)):
        sentence = sentences[i]
        num_padding = sequence_length - len(sentence)
        new_sentence = sentence + [padding_word] * num_padding
        padded_sentences.append(new_sentence)
    return padded_sentences


def build_vocab(sentences):
    word_counts = Counter(itertools.chain(*sentences))
    vocabulary_inv = [x[0] for x in word_counts.most_common()]
    vocabulary = {x: i for i, x in enumerate(vocabulary_inv)}
    return vocabulary, vocabulary_inv

def build_input_data(sentences, vocabulary):
    x = np.array([
            [vocabulary[word] for word in sentence]
            for sentence in sentences])
    return x

def predict(mod, sen):
    mod.forward(Batch(data=[mx.nd.array(sen)]))
    prob = mod.get_outputs()[0].asnumpy()
    prob = np.squeeze(prob)
    a = np.argsort(prob)[::-1]    
    for i in a[0:5]:
        print('probability=%f' %(prob[i]))   


sentences = load_data_sentences( os.path.join( SENTENCES_DIR, 'test-pos-1.txt') )
sentences_padded = pad_sentences(sentences)
vocabulary, vocabulary_inv = build_vocab(sentences_padded)
x = build_input_data(sentences_padded, vocabulary)


Batch = namedtuple('Batch', ['data'])

sym, arg_params, aux_params = mx.model.load_checkpoint( os.path.join( CURRENT_DIR, 'cnn'), 19)
mod = mx.mod.Module(symbol=sym, context=mx.cpu(), label_names = None)
mod.bind(for_training=False, data_shapes=[('data', (50,56))], label_shapes=mod._label_shapes)
mod.set_params(arg_params, aux_params, allow_missing=True)

predict(mod, x)

Но я получил ошибку:

ошибка infer_shape. Аргументы: данные: (50, 26л) Traceback (последний вызов был последним): Файл "C: \ code \ mxnet \ test2.py", строка 152, в прогнозе (мод, х) Файл "C: \ code \ mxnet \ test2.py", строка 123, в прогнозе mod.forward (Batch (данные = [mx.nd.array (сено)])) ...

MXNetError: ошибка в форме оператора Проверка не удалась: oshape.Size () == dshape.Size () (840000 против 390000) Размер целевой формы отличается от исходного. Цель: [50,1,56,300] Источник: [50,26,300]

Источник - текстовый файл с 50 строками предложений

К сожалению, я не нашел никакой помощи в Интернете. Пожалуйста, взгляните. ОС: Windows 10. Python 2.7 Спасибо.

1 Ответ

0 голосов
/ 17 июля 2018

Я полагаю, что ваша ошибка в том, что заполнение ваших входных предложений отличается от того, что ожидает модель. Способ работы pad_sentences состоит в том, чтобы дополнить предложения длиной до самого длинного, переданного предложения, поэтому, если вы используете другой набор данных, вы почти наверняка получите дополнение, отличное от заполнения вашей модели (которое равно 56). В этом случае похоже, что вы получаете отступ 26 (из сообщения об ошибке «Источник: [50, 26, 300]»).

Мне удалось успешно запустить ваш код, изменив pad_sentence следующим образом и запустив его с sequence_length = 56 для соответствия модели.

def pad_sentences(sentences, sequence_length, padding_word=""):
    padded_sentences = []
    for i in range(len(sentences)):
        sentence = sentences[i]
        num_padding = sequence_length - len(sentence)
        new_sentence = sentence + [padding_word] * num_padding
        padded_sentences.append(new_sentence)
    return padded_sentences

N.B. После успешного запуска вы столкнетесь с ошибкой, поскольку prob [i] не является float.

def predict(mod, sen):
    mod.forward(Batch(data=[mx.nd.array(sen)]))
    prob = mod.get_outputs()[0].asnumpy()
    prob = np.squeeze(prob)
    a = np.argsort(prob)[::-1]    
    for i in a[0:5]:
        print('probability=%f' %(prob[i]))   << prob is a numpy.ndarray, not a float.

Vishaal

...