我想定义我自己的 Lstm 模型如下:
from keras import backend as K from keras.callbacks import ModelCheckpoint from keras.layers.core import Dense, Activation, Flatten, Dropout from keras.layers import Input,Concatenate, Average, Maximum from keras.layers.normalization import BatchNormalization from keras.layers import LSTM, Bidirectional from keras.models import Model from keras.optimizers import Adam class LSTMModel(object): def __init__(self, config): self.num_batch = config['num_batch'] self.maxlen = config['maxlen'] self.embedding_dims = config['embedding_dims'] self.lstm_dims = config['lstm_dims'] self.hidden_dims = config['hidden_dims'] self.epochs = config['epochs'] self.classes = config['classes'] self.optimizer = config['optimizer'] def load_data(self): (X_train, y_train), (X_test, y_test) = \ imdb.load_data(num_words=self.max_features, seed=11) X_train = sequence.pad_sequences(X_train, maxlen=self.maxlen) X_test = sequence.pad_sequences(X_test, maxlen=self.maxlen) return (X_train, y_train), (X_test, y_test) def build_model(self, loss, P=None): input = Input(shape=(self.maxlen , self.embedding_dims)) rnn_outputs, forward_h, forward_c, backward_h, backward_c =\ Bidirectional(LSTM(self.lstm_dims, return_sequences = True, return_state = True, kernel_initializer='uniform'))(input) avg_pool = K.mean(rnn_outputs, axis = 1) max_pool = K.max(rnn_outputs, axis = 1) print(avg_pool) print(max_pool) x = Concatenate()([avg_pool, max_pool]) print(x) #Add a dense layer x = Dense(self.hidden_dims, kernel_initializer = 'he_normal')(x) x = Activation('relu')(x) x = BatchNormalization(momentum = 0.5)(x) x = Dropout(0.5)(x) output = Dense(self.classes, kernel_initializer = 'he_normal')(x) if loss in yes_bound: output = BatchNormalization(axis=1)(output) if loss in yes_softmax: output = Activation('softmax')(output) model = Model(inputs=input, outputs=output) self.compile(model, loss, P) if __name__ == "__main__": config = { "maxlen": 100, "embedding_dims": 31, "lstm_dims":20, "hidden_dims": 80, "classes": 21, "epochs": 50, "num_batch": 24, "optimizer": None } model = LSTMModel(config) model.build_model('crossentropy')
但是,我遇到一个错误:
AttributeError: 'NoneType' object has no attribute '_inbound_nodes'
详细信息如下:
File "F:\models.py", line 169, in build_model model = Model(inputs=input, outputs=output) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\legacy\interfaces.py", line 91, in wrapper return func(*args, **kwargs) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 93, in __init__ self._init_graph_network(*args, **kwargs) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 237, in _init_graph_network self.inputs, self.outputs) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1353, in _map_graph_network tensor_index=tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1340, in build_map node_index, tensor_index) File "E:\SoftwareInstall\anaconda3.5.2.0\lib\site-packages\keras\engine\network.py", line 1312, in build_map node = layer._inbound_nodes[node_index] AttributeError: 'NoneType' object has no attribute '_inbound_nodes'
你的错误 AttributeError: 'NoneType' object has no attribute '_inbound_nodes' 主要是由 Keras 层的连接或构建方式的问题引起的。在你提供的代码中,可能有以下几个问题导致这个错误。
Bidirectional(LSTM)
你在定义 Bidirectional(LSTM) 时,使用了 return_state=True 和 return_sequences=True,这导致 Bidirectional(LSTM) 会返回四个输出:rnn_outputs, forward_h, forward_c, backward_h, backward_c。但是,你并没有正确使用这些输出中的任何一个,且你可能想要的只是 rnn_outputs。
return_state=True
return_sequences=True
rnn_outputs, forward_h, forward_c, backward_h, backward_c
rnn_outputs
你可以修改 Bidirectional(LSTM) 层的定义,确保它的输出能够正确地连接到后续层。考虑到你的代码,假设你只关心 rnn_outputs,你可以简单地将其修改为:
rnn_outputs = Bidirectional(LSTM(self.lstm_dims, return_sequences=True))(input)
K.mean
K.max
你在计算 avg_pool 和 max_pool 时使用了 K.mean 和 K.max,这些是 Keras 后端的操作。它们的输入应该是层输出的张量,因此你应确保这些操作与 rnn_outputs 正确连接。
avg_pool
max_pool
修改你的代码来确保 rnn_outputs 是一个可以应用 K.mean 和 K.max 操作的张量:
avg_pool = K.mean(rnn_outputs, axis=1) max_pool = K.max(rnn_outputs, axis=1)
在输出层,你将 activation='softmax' 与 loss='crossentropy' 配对,这通常是没问题的,但你还需要确保输出层的定义是合适的。你可能想使用 activation='softmax' 进行多类别分类。
activation='softmax'
loss='crossentropy'
output = Dense(self.classes, activation='softmax', kernel_initializer='he_normal')(x)
from keras import backend as K from keras.callbacks import ModelCheckpoint from keras.layers.core import Dense, Activation, Flatten, Dropout from keras.layers import Input, Concatenate from keras.layers.normalization import BatchNormalization from keras.layers import LSTM, Bidirectional from keras.models import Model from keras.optimizers import Adam from keras.preprocessing import sequence from keras.datasets import imdb class LSTMModel(object): def __init__(self, config): self.num_batch = config['num_batch'] self.maxlen = config['maxlen'] self.embedding_dims = config['embedding_dims'] self.lstm_dims = config['lstm_dims'] self.hidden_dims = config['hidden_dims'] self.epochs = config['epochs'] self.classes = config['classes'] self.optimizer = config['optimizer'] def load_data(self): (X_train, y_train), (X_test, y_test) = \ imdb.load_data(num_words=10000, seed=11) # You need to specify max_features if needed. X_train = sequence.pad_sequences(X_train, maxlen=self.maxlen) X_test = sequence.pad_sequences(X_test, maxlen=self.maxlen) return (X_train, y_train), (X_test, y_test) def build_model(self, loss, P=None): input = Input(shape=(self.maxlen , self.embedding_dims)) # Bidirectional LSTM layer rnn_outputs = Bidirectional(LSTM(self.lstm_dims, return_sequences=True))(input) # Apply mean and max pooling avg_pool = K.mean(rnn_outputs, axis=1) max_pool = K.max(rnn_outputs, axis=1) # Concatenate the two pooled outputs x = Concatenate()([avg_pool, max_pool]) # Add a dense layer x = Dense(self.hidden_dims, kernel_initializer='he_normal')(x) x = Activation('relu')(x) x = BatchNormalization(momentum=0.5)(x) x = Dropout(0.5)(x) # Output layer output = Dense(self.classes, activation='softmax', kernel_initializer='he_normal')(x) model = Model(inputs=input, outputs=output) self.compile(model, loss, P) def compile(self, model, loss, P=None): if self.optimizer is None: optimizer = Adam() else: optimizer = self.optimizer model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy']) if __name__ == "__main__": config = { "maxlen": 100, "embedding_dims": 31, "lstm_dims": 20, "hidden_dims": 80, "classes": 21, "epochs": 50, "num_batch": 24, "optimizer": None } model = LSTMModel(config) model.build_model('categorical_crossentropy') # Assuming this is the loss for classification
output
loss
categorical_crossentropy
Adam
通过这些修正,应该可以解决你遇到的 AttributeError: 'NoneType' object has no attribute '_inbound_nodes' 错误。