双向 RNN - “NoneType”对象没有属性“_inbound_nodes”;错误

发布于 2025-01-11 10:07:29 字数 4847 浏览 0 评论 0原文

我想建立一个执行 POS(词性标记)任务的循环模型。
它获取输入句子并输出每个单词的标签:

DT  NN  VBD DT  NN
the dog ate the cat

我想使用“双向卷积”想法:
输入(前进方式)->循环层->转换层
输入(向后方式)->循环层->转换层
然后将两者连接起来,
通过 Dense and Time-Distributed 层获取输出:

model_image


这是主要内容。

我编写了如下代码:

def make_model(input):
    Embeded_input = L.Embedding(len(all_words),32,name='a')(input) # batch, 10002, 32
    RNN = keras.models.Sequential()
    RNN.add(L.GRU(64, return_sequences=True, recurrent_dropout=0.3,name='b'))
    RNN.add(L.LSTM(64, return_sequences=True, recurrent_dropout=0.1,name='c'))

    forward1 = RNN(Embeded_input)
    backward1 = RNN(Embeded_input[:,::-1,:])

    CNN = keras.models.Sequential()
    CNN.add(L.Conv1D(32, 3, padding='same', activation='relu',name='d'))
    CNN.add(L.Conv1D(32, 3, padding='same', activation='relu',name='e'))

    forward2 = CNN(forward1)
    backward2 = CNN(backward1)

    concat = L.concatenate([forward2, backward2],name='f')

    stepwise_dense = L.Dense(len(all_tags),activation='softmax',name='g')
    stepwise_dense = L.TimeDistributed(stepwise_dense,name='h')
    OUTPUT = stepwise_dense(concat)

    return OUTPUT

inputs = L.Input((None,), dtype='int32', name='input')
outputs = make_model(inputs)
 
model = keras.models.Model(inputs=inputs, outputs=outputs, name='POS_improved_07')

model.summary()

并从第二个最新行获取错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-76-cf1cead269f5> in <module>()
     27 outputs = BIRNN(input)
     28 
---> 29 model = keras.models.Model(inputs=inputs, outputs=outputs, name='POS_improved_07')
     30 
     31 model.summary()

8 frames
/tensorflow-1.15.2/python3.7/keras/engine/network.py in build_map(tensor, finished_nodes, nodes_in_progress, layer, node_index, tensor_index)
   1391             ValueError: if a cycle is detected.
   1392         """
-> 1393         node = layer._inbound_nodes[node_index]
   1394 
   1395         # Prevent cycles.

AttributeError: 'NoneType' object has no attribute '_inbound_nodes'

ps。 输入来自哪里

import nltk
import numpy as np
nltk.download('brown')
nltk.download('universal_tagset')
data = nltk.corpus.brwon.tagged_sents(tagset='universal')
all_tags = ['#EOS#','#UNK#','ADV', 'NOUN', 'ADP', 'PRON', 'DET', '.', 'PRT', 'VERB', 'X', 'NUM', 'CONJ', 'ADJ']

data = np.array([[(word.lower(),tag) for word,tag in sentence] for sentence in data ])

,然后

from collections import Counter
word_counts = Counter()
for sentence in data:
    words,tags = zip(*sentence)
    word_counts.update(words)

all_words = ['#EOS#','#UNK#']+list(list(zip(*word_counts.most_common(10000)))[0]) # len=10002

使用generate_batches:

def to_matrix(lines,token_to_id,max_len=None,pad=0,dtype='int32',time_major=False):
    """Converts a list of names into rnn-digestable matrix with paddings added after the end"""
    
    max_len = max_len or max(map(len,lines))
    matrix = np.empty([len(lines),max_len],dtype)
    matrix.fill(pad)

    for i in range(len(lines)):
        line_ix = list(map(token_to_id.__getitem__,lines[i]))[:max_len]
        matrix[i,:len(line_ix)] = line_ix

    return matrix.T if time_major else matrix

from keras.utils.np_utils import to_categorical
BATCH_SIZE=32
def generate_batches(sentences,batch_size=BATCH_SIZE,max_len=None,pad=0):
    assert isinstance(sentences,np.ndarray),"Make sure sentences is a numpy array"
    
    while True:
        indices = np.random.permutation(np.arange(len(sentences)))
        for start in range(0,len(indices)-1,batch_size):
            batch_indices = indices[start:start+batch_size]
            batch_words,batch_tags = [],[]
            for sent in sentences[batch_indices]:
                words,tags = zip(*sent)
                batch_words.append(words)
                batch_tags.append(tags)

            batch_words = to_matrix(batch_words,word_to_id,max_len,pad)
            batch_tags = to_matrix(batch_tags,tag_to_id,max_len,pad)

            batch_tags_1hot = to_categorical(batch_tags,len(all_tags)).reshape(batch_tags.shape+(-1,))
            yield batch_words,batch_tags_1hot        

模型将被训练为:

model.compile('adam','categorical_crossentropy')

model.fit_generator(generate_batches(train_data),
                    len(train_data)/BATCH_SIZE,
                    callbacks=[
                               EvaluateAccuracy(),
                               save_in_drive(model_filename, MODEL_SAVE_FOLDER_PATH)
                               ],
                    epochs=5)

I wanna build a Recurrence model which do POS(Part Of Speech tagging) task.
It gets input sentence and outputs tags of each words:

DT  NN  VBD DT  NN
the dog ate the cat

I wanna use 'bidirectional convolution' idea:
input(forward way) -> Recurrence layer -> Conv layer
input(backward way) -> Recurrence layer -> Conv layer
and then do concatenate both,
get the output through the Dense and Time-Distributed layer:

model_image


Here's the main.

I wrote the code like:

def make_model(input):
    Embeded_input = L.Embedding(len(all_words),32,name='a')(input) # batch, 10002, 32
    RNN = keras.models.Sequential()
    RNN.add(L.GRU(64, return_sequences=True, recurrent_dropout=0.3,name='b'))
    RNN.add(L.LSTM(64, return_sequences=True, recurrent_dropout=0.1,name='c'))

    forward1 = RNN(Embeded_input)
    backward1 = RNN(Embeded_input[:,::-1,:])

    CNN = keras.models.Sequential()
    CNN.add(L.Conv1D(32, 3, padding='same', activation='relu',name='d'))
    CNN.add(L.Conv1D(32, 3, padding='same', activation='relu',name='e'))

    forward2 = CNN(forward1)
    backward2 = CNN(backward1)

    concat = L.concatenate([forward2, backward2],name='f')

    stepwise_dense = L.Dense(len(all_tags),activation='softmax',name='g')
    stepwise_dense = L.TimeDistributed(stepwise_dense,name='h')
    OUTPUT = stepwise_dense(concat)

    return OUTPUT

inputs = L.Input((None,), dtype='int32', name='input')
outputs = make_model(inputs)
 
model = keras.models.Model(inputs=inputs, outputs=outputs, name='POS_improved_07')

model.summary()

and get the Error from the second latest line:

AttributeError                            Traceback (most recent call last)
<ipython-input-76-cf1cead269f5> in <module>()
     27 outputs = BIRNN(input)
     28 
---> 29 model = keras.models.Model(inputs=inputs, outputs=outputs, name='POS_improved_07')
     30 
     31 model.summary()

8 frames
/tensorflow-1.15.2/python3.7/keras/engine/network.py in build_map(tensor, finished_nodes, nodes_in_progress, layer, node_index, tensor_index)
   1391             ValueError: if a cycle is detected.
   1392         """
-> 1393         node = layer._inbound_nodes[node_index]
   1394 
   1395         # Prevent cycles.

AttributeError: 'NoneType' object has no attribute '_inbound_nodes'

ps.
where input comes from

import nltk
import numpy as np
nltk.download('brown')
nltk.download('universal_tagset')
data = nltk.corpus.brwon.tagged_sents(tagset='universal')
all_tags = ['#EOS#','#UNK#','ADV', 'NOUN', 'ADP', 'PRON', 'DET', '.', 'PRT', 'VERB', 'X', 'NUM', 'CONJ', 'ADJ']

data = np.array([[(word.lower(),tag) for word,tag in sentence] for sentence in data ])

and then

from collections import Counter
word_counts = Counter()
for sentence in data:
    words,tags = zip(*sentence)
    word_counts.update(words)

all_words = ['#EOS#','#UNK#']+list(list(zip(*word_counts.most_common(10000)))[0]) # len=10002

with generate_batches:

def to_matrix(lines,token_to_id,max_len=None,pad=0,dtype='int32',time_major=False):
    """Converts a list of names into rnn-digestable matrix with paddings added after the end"""
    
    max_len = max_len or max(map(len,lines))
    matrix = np.empty([len(lines),max_len],dtype)
    matrix.fill(pad)

    for i in range(len(lines)):
        line_ix = list(map(token_to_id.__getitem__,lines[i]))[:max_len]
        matrix[i,:len(line_ix)] = line_ix

    return matrix.T if time_major else matrix

from keras.utils.np_utils import to_categorical
BATCH_SIZE=32
def generate_batches(sentences,batch_size=BATCH_SIZE,max_len=None,pad=0):
    assert isinstance(sentences,np.ndarray),"Make sure sentences is a numpy array"
    
    while True:
        indices = np.random.permutation(np.arange(len(sentences)))
        for start in range(0,len(indices)-1,batch_size):
            batch_indices = indices[start:start+batch_size]
            batch_words,batch_tags = [],[]
            for sent in sentences[batch_indices]:
                words,tags = zip(*sent)
                batch_words.append(words)
                batch_tags.append(tags)

            batch_words = to_matrix(batch_words,word_to_id,max_len,pad)
            batch_tags = to_matrix(batch_tags,tag_to_id,max_len,pad)

            batch_tags_1hot = to_categorical(batch_tags,len(all_tags)).reshape(batch_tags.shape+(-1,))
            yield batch_words,batch_tags_1hot        

the model will be trained as:

model.compile('adam','categorical_crossentropy')

model.fit_generator(generate_batches(train_data),
                    len(train_data)/BATCH_SIZE,
                    callbacks=[
                               EvaluateAccuracy(),
                               save_in_drive(model_filename, MODEL_SAVE_FOLDER_PATH)
                               ],
                    epochs=5)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文