embedding_lookup Tensorflow

Я пытаюсь изучить словесное представление набора данных imdb «с нуля» с помощью функции TensorFlow tf.nn.embedding_lookup(). Если я правильно понимаю, мне нужно настроить слой встраивания перед другим скрытым слоем, а затем, когда я выполню градиентный спуск, слой «узнает» представление слова в весах этого слоя. Однако, когда я пытаюсь это сделать, я получаю ошибку формы между моим слоем внедрения и первым полносвязным слоем моей сети.

def multilayer_perceptron(_X, _weights, _biases):
    with tf.device('/cpu:0'), tf.name_scope("embedding"):
        W = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),name="W")
        embedding_layer = tf.nn.embedding_lookup(W, _X)    
    layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(embedding_layer, _weights['h1']), _biases['b1'])) 
    layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, _weights['h2']), _biases['b2'])) 
    return tf.matmul(layer_2, weights['out']) + biases['out']

x = tf.placeholder(tf.int32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])

pred = multilayer_perceptron(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred,y))
train_step = tf.train.GradientDescentOptimizer(0.3).minimize(cost)

init = tf.initialize_all_variables()

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

ValueError: Shapes TensorShape([Dimension(None), Dimension(300), Dimension(128)])
and TensorShape([Dimension(None), Dimension(None)]) must have the same rank

person nicolasdavid    schedule 09.02.2016    source источник


Ответы (2)


Ошибка формы возникает из-за того, что вы используете двумерный тензор x для индексации двумерного тензора вложения W. Вспомните tf.nn.embedding_lookup() (и его близкого родственника tf.gather()), взяв каждое целочисленное значение i в x и заменив его строкой W[i, :]. Из сообщения об ошибке можно сделать вывод, что n_input = 300 и embedding_size = 128. В общем, результат tf.nn.embedding_lookup() числа измерений равен rank(x) + rank(W) - 1, в данном случае 3. Ошибка возникает при попытке умножить этот результат на _weights['h1'], который является (двумерной) матрицей.

Чтобы исправить этот код, это зависит от того, что вы пытаетесь сделать, и почему вы передаете матрицу входных данных для внедрения. Обычно нужно агрегировать векторы встраивания для каждого входного примера в одну строку для каждого примера, используя такую ​​операцию, как tf.reduce_sum(). Например, вы можете сделать следующее:

W = tf.Variable(
    tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0) ,name="W")
embedding_layer = tf.nn.embedding_lookup(W, _X)

# Reduce along dimension 1 (`n_input`) to get a single vector (row)
# per input example.
embedding_aggregated = tf.reduce_sum(embedding_layer, [1])

layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(
    embedding_aggregated, _weights['h1']), _biases['b1'])) 
person mrry    schedule 09.02.2016
comment
Спасибо ! Я думаю, что tf.nn.reduce_sum должен быть tf.reduce_sum ? Когда вы решили уменьшить размер слоя внедрения, как вы выбрали тот, который нужно уменьшить между n_input=300 и embedding_size=128? - person nicolasdavid; 09.02.2016
comment
Вы правы насчет опечатки - исправил выше, спасибо! Я решил уменьшить по измерению n_input, потому что казалось более вероятным, что это будет соответствовать вашей проблеме, и я предположил, что (например) порядок входных данных не важен. Довольно типично делать это для задач типа «мешок слов». Вы можете уменьшить по embedding_size, но я думаю, что это приведет к потере большого количества информации из-за встраивания, поэтому, вероятно, это тоже не сработает. - person mrry; 09.02.2016

Еще одно возможное решение: вместо добавления векторов встраивания объедините эти векторы в один вектор и увеличьте количество нейронов в скрытом слое.
Я использовал:
embedding_aggregated = tf.reshape(embedding_layer, [-1, embedding_size * sequence_length])
Кроме того, я изменил количество нейронов в скрытом слое на embedding_size * sequence_length. Наблюдение: Точность также улучшилась при использовании конкатенации, а не сложения.

person Nitin    schedule 08.09.2016