1

我尝试使用 keras 建立一个带有注意力的文档分类模型(论文 Hierarchical Attention Networks for Document Classifications 中模型的一部分)。以下代码是测试代码。我创建了一个 birnn 和一个自定义注意力层,参考https://github.com/person-lee/LSTM_ATTENTION_CLASSIFY/blob/master/utils.pyhttps://github.com/richliao/textClassifier/blob/master/textClassifierHATT .py。但是我收到了一个错误(请参阅下面的详细信息)。

代码是:

from keras.models import Model
from keras.layers import Input
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import GRU
from keras.layers.wrappers import Bidirectional, TimeDistributed
from keras.layers.core import Dropout, Dense, Lambda, Masking
from keras.layers import merge
from keras.engine.topology import Layer

from keras import backend as K
from keras import initializers
import keras
class AttentionLayer(Layer):
    '''
    Attention layer. 
    '''
    def __init__(self, init='glorot_uniform', **kwargs):
        super(AttentionLayer, self).__init__(**kwargs)
        self.supports_masking = True
        self.init = initializers.get(init)

    def build(self, input_shape):
        input_dim = input_shape[-1]
        self.Uw = self.init((input_dim, ))
        self.trainable_weights = [self.Uw]
        super(AttentionLayer, self).build(input_shape)  

    def compute_mask(self, input, mask):
        return mask

    def call(self, x, mask=None):
        eij = K.tanh(K.squeeze(K.dot(x, K.expand_dims(self.Uw)), axis=-1))
        ai = K.exp(eij)
        weights = ai/K.expand_dims(K.sum(ai, axis=1),1)

        weighted_input = x*K.expand_dims(weights,2)
        return K.sum(weighted_input, axis=1)

    def get_output_shape_for(self, input_shape):
        newShape = list(input_shape)
        newShape[-1] = 1
        return tuple(newShape)

sentence_input = Input(shape=(None,5))
# embedded_sequences = embedding_layer(sentence_input)
l_lstm = Bidirectional(GRU(10, return_sequences=True),merge_mode='concat')(sentence_input)
# l_dense = TimeDistributed(Dense(200))(l_lstm)
l_att = AttentionLayer()(l_lstm)
cls = Dense(10, activation='softmax')(l_att)
sentEncoder = Model(sentence_input, cls)

sentEncoder.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['acc'])
import numpy as np
x_train = np.array([[1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5],
                    [1,2,3,4,5]])
y_train = np.array([1,2,3,4,5,6,7,8,9,0])
y_train = keras.utils.to_categorical(y_train, 10)
x_train = np.expand_dims(x_train,0)
y_train = np.expand_dims(y_train,0)

sentEncoder.fit(x=x_train,y=y_train,validation_split=0.1)

并得到以下错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-13-3f6bb30d8618> in <module>()
----> 1 sentEncoder.fit(x=x_train,y=y_train,validation_split=0.1)

~/.conda/envs/21/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
   1011         else:
   1012             ins = x + y + sample_weights
-> 1013         self._make_train_function()
   1014         f = self.train_function
   1015 

~/.conda/envs/21/lib/python3.6/site-packages/keras/engine/training.py in _make_train_function(self)
    495                     training_updates = self.optimizer.get_updates(
    496                         params=self._collected_trainable_weights,
--> 497                         loss=self.total_loss)
    498                 updates = (self.updates +
    499                            training_updates +

~/.conda/envs/21/lib/python3.6/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name +
     90                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

~/.conda/envs/21/lib/python3.6/site-packages/keras/optimizers.py in get_updates(self, loss, params)
    262                 new_p = p.constraint(new_p)
    263 
--> 264             self.updates.append(K.update(p, new_p))
    265         return self.updates
    266 

~/.conda/envs/21/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py in update(x, new_x)
    968         The variable `x` updated.
    969     """
--> 970     return tf.assign(x, new_x)
    971 
    972 

~/.conda/envs/21/lib/python3.6/site-packages/tensorflow/python/ops/state_ops.py in assign(ref, value, validate_shape, use_locking, name)
    282         ref, value, use_locking=use_locking, name=name,
    283         validate_shape=validate_shape)
--> 284   return ref.assign(value, name=name)
    285 
    286 

AttributeError: 'Tensor' object has no attribute 'assign'

我不知道出了什么问题。我用谷歌搜索并询问了擅长这方面的人,但没有弄清楚。bidirectional是不是因为 有人知道出了什么问题吗?

4

2 回答 2

2

我想这是数据集和标签的形状问题。

于 2018-08-21T13:17:28.717 回答
-1

我遇到了同样的问题,我解决了。原因是 K.update(p, new_p),'p' 类型不应该是张量类型,当你使用 K.update(p, new_p) 时,'p' 类型应该是 tf.Variable 并且 'new_p' 类型应该是张量类型,我希望它能解决你的问题。

于 2019-09-19T04:59:29.020 回答