Tensorflow символьный уровень CNN - форма ввода - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь добавить двухуровневые CNN на уровне символов в большую нейронную сеть, но получаю ValueError для входных измерений.

Чего я хочу добиться, так это получить орфографические представления для входных слов, заменив символы (в соответствии с заглавными буквами, числовыми или буквенными) и вставив их в CNN. Я знаю, что этого можно достичь с помощью LSTM / RNN, но требования указывают на использование CNN, поэтому использование другого NN не является обязательным.

В большинстве примеров, естественно, используются наборы данных изображений (MNIST и т. Д.), Но не наборы текстовых данных. Поэтому я запутался и не уверен, как «изменить» встраивание символов, чтобы они могли быть действительными входными данными для CNN.

Итак, вот часть кода, которую я пытаюсь запустить:

# ...

# shape = (batch size, max length of sentence, max length of word)
self.char_ids = tf.placeholder(tf.int32, shape=[None, None, None],
                name="char_ids")

# ...

# Char embedding lookup
_char_embeddings = tf.get_variable(
        name="_char_embeddings",
        dtype=tf.float32,
        shape=[self.config.nchars, self.config.dim_char])
char_embeddings = tf.nn.embedding_lookup(_char_embeddings,
        self.char_ids, name="char_embeddings")

# Reshape for CNN?
s = tf.shape(char_embeddings)
char_embeddings = tf.reshape(char_embeddings, shape=[s[0]*s[1], self.config.dim_char, s[2]])

# Conv #1
conv1 = tf.layers.conv1d(
    inputs=char_embeddings,
    filters=64,
    kernel_size=3,
    padding="valid",
    activation=tf.nn.relu)

# Conv #2
conv2 = tf.layers.conv1d(
    inputs=conv1,
    filters=64,
    kernel_size=3,
    padding="valid",
    activation=tf.nn.relu)
pool2 = tf.layers.max_pooling1d(inputs=conv2, pool_size=2, strides=2)

# Dense Layer
output = tf.layers.dense(inputs=pool2, units=32, activation=tf.nn.relu)

# ...

И это ошибка, которую я получаю:

File "/home/emre/blstm-crf-ner/model/ner_model.py", line 159, in add_word_embeddings_op activation=tf.nn.relu)
File "/home/emre/blstm-crf-ner/virtner/lib/python3.4/site-packages/tensorflow/python/layers/convolutional.py", line 411, in conv1d return layer.apply(inputs)
File "/home/emre/blstm-crf-ner/virtner/lib/python3.4/site-packages/tensorflow/python/layers/base.py", line 809, in apply return self.__call__(inputs, *args, **kwargs)
File "/home/emre/blstm-crf-ner/virtner/lib/python3.4/site-packages/tensorflow/python/layers/base.py", line 680, in __call__ self.build(input_shapes)
File "/home/emre/blstm-crf-ner/virtner/lib/python3.4/site-packages/tensorflow/python/layers/convolutional.py", line 132, in build raise ValueError('The channel dimension of the inputs '
ValueError: The channel dimension of the inputs should be defined. Found `None`.

Любая помощь будет оценена.
Спасибо.

UPDATE

Так что после просмотра некоторых постов в блогах 1 , 2 и благодаря Виджаю m я понимаю, что мы должны заранее предоставить входные размеры (в отличие от sequence_length s с RNN / LSTM). Итак, вот последний фрагмент кода:

# Char embedding lookup
_char_embeddings = tf.get_variable(
        name="_char_embeddings",
        dtype=tf.float32,
        shape=[self.config.nchars, self.config.dim_char])
char_embeddings = tf.nn.embedding_lookup(_char_embeddings,
        self.char_ids, name="char_embeddings")

# max_len_of_word: 20
# Just pad shorter words and truncate the longer ones.
s = tf.shape(char_embeddings)
char_embeddings = tf.reshape(char_embeddings, shape=[-1, self.config.dim_char, self.config.max_len_of_word])

# Conv #1
conv1 = tf.layers.conv1d(
    inputs=char_embeddings,
    filters=64,
    kernel_size=3,
    padding="valid",
    activation=tf.nn.relu)

# Conv #2
conv2 = tf.layers.conv1d(
    inputs=conv1,
    filters=64,
    kernel_size=3,
    padding="valid",
    activation=tf.nn.relu)
pool2 = tf.layers.max_pooling1d(inputs=conv2, pool_size=2, strides=2)

# Dense Layer
output = tf.layers.dense(inputs=pool2, units=32, activation=tf.nn.relu)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Формат ввода по умолчанию в Conv1d имеет форму (пакет, длина, каналы), возможно, char_embeddings должен выглядеть так:

s = char_embeddings.get_shape()
char_embeddings = tf.reshape(char_embeddings, shape=[-1, s[2], dim_char])

thx!

0 голосов
/ 11 мая 2018

conv1d ожидает, что размер канала будет определен во время создания графика.Таким образом, вы не можете передать размер как None.

. Необходимо внести следующие изменения:

char_ids = tf.placeholder(tf.int32, shape=[None, max_len_sen, max_len_word],
            name="char_ids")
#max_len_sen and max_len_word has to be set.

#Reshapping for CNN, should be
s = char_embeddings.get_shape()
char_embeddings = tf.reshape(char_embeddings, shape=[-1, dim_char, s[2]])
...