keras - 层模型_131 需要 7 个输入,但它收到 1 个输入张量

时间:2021-07-21 09:34:00

标签: python keras scikit-learn text-classification

我正在处理一个文本分类项目,其数据框有 7 个特征(列)和 1 个标签列(多类 ==> 总共有 6 个可能的标签)

我所有的数据都是文本。

因为我想保持我的列分开,所以我最终得到了以下代码:

input_message = Input(shape=(128,))
x = Embedding(vocab_size, 64)(input_message)
x = Flatten()(x)
x = Dense(64, activation="relu")(x)
x = Dense(32, activation="relu")(x)
x = Dense(4, activation="relu")(x)
model_message = Model(inputs=input_message, outputs=x)

input_description = Input(shape=(128,))
x = Embedding(vocab_size, 64)(input_description)
x = Flatten()(x)
x = Dense(64, activation="relu")(x)
x = Dense(32, activation="relu")(x)
x = Dense(4, activation="relu")(x)
model_description = Model(inputs=input_description, outputs=x)

input_errors = Input(shape=(2,))
x = Embedding(2, 1)(input_errors)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_errors = Model(inputs=input_errors, outputs=x)

input_panics = Input(shape=(2,))
x = Embedding(2, 1)(input_panics)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_panics = Model(inputs=input_panics, outputs=x)

input_images = Input(shape=(2,))
x = Embedding(2, 1)(input_images)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_images = Model(inputs=input_images, outputs=x)

input_committer = Input(shape=(16,))
x = Embedding(16, 1)(input_committer)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_committer = Model(inputs=input_committer, outputs=x)

input_reporter = Input(shape=(6,))
x = Embedding(6, 1)(input_reporter)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_reporter = Model(inputs=input_reporter, outputs=x)

combined = Concatenate()([model_message.output, model_description.output, model_errors.output, 
                          model_panics.output, model_images.output, model_committer.output, model_reporter.output])

z = Dense(6, activation='softmax')(combined)
model = Model(inputs=[model_message.input, model_description.input, 
                      model_errors.input, model_panics.input, model_images.input, 
                      model_committer.input, model_reporter.input], outputs=z)



model.compile(
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer=keras.optimizers.RMSprop(),
    metrics=["accuracy"],
)
model.summary()

history = model.fit(X_train, y_train, batch_size=64, epochs=2, validation_split=0.2)

运行时出现以下错误:

ValueError: Layer model_131 expects 7 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, 7) dtype=string>]

下面是model.summary()的输出:

Model: "model_131"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_128 (InputLayer)          [(None, 128)]        0                                            
__________________________________________________________________________________________________
input_129 (InputLayer)          [(None, 128)]        0                                            
__________________________________________________________________________________________________
embedding_99 (Embedding)        (None, 128, 64)      640000      input_128[0][0]                  
__________________________________________________________________________________________________
embedding_100 (Embedding)       (None, 128, 64)      640000      input_129[0][0]                  
__________________________________________________________________________________________________
flatten_70 (Flatten)            (None, 8192)         0           embedding_99[0][0]               
__________________________________________________________________________________________________
flatten_71 (Flatten)            (None, 8192)         0           embedding_100[0][0]              
__________________________________________________________________________________________________
input_130 (InputLayer)          [(None, 2)]          0                                            
__________________________________________________________________________________________________
input_131 (InputLayer)          [(None, 2)]          0                                            
__________________________________________________________________________________________________
input_132 (InputLayer)          [(None, 2)]          0                                            
__________________________________________________________________________________________________
input_133 (InputLayer)          [(None, 16)]         0                                            
__________________________________________________________________________________________________
input_134 (InputLayer)          [(None, 6)]          0                                            
__________________________________________________________________________________________________
dense_189 (Dense)               (None, 64)           524352      flatten_70[0][0]                 
__________________________________________________________________________________________________
dense_192 (Dense)               (None, 64)           524352      flatten_71[0][0]                 
__________________________________________________________________________________________________
embedding_101 (Embedding)       (None, 2, 1)         2           input_130[0][0]                  
__________________________________________________________________________________________________
embedding_102 (Embedding)       (None, 2, 1)         2           input_131[0][0]                  
__________________________________________________________________________________________________
embedding_103 (Embedding)       (None, 2, 1)         2           input_132[0][0]                  
__________________________________________________________________________________________________
embedding_104 (Embedding)       (None, 16, 1)        16          input_133[0][0]                  
__________________________________________________________________________________________________
embedding_105 (Embedding)       (None, 6, 1)         6           input_134[0][0]                  
__________________________________________________________________________________________________
dense_190 (Dense)               (None, 32)           2080        dense_189[0][0]                  
__________________________________________________________________________________________________
dense_193 (Dense)               (None, 32)           2080        dense_192[0][0]                  
__________________________________________________________________________________________________
flatten_72 (Flatten)            (None, 2)            0           embedding_101[0][0]              
__________________________________________________________________________________________________
flatten_73 (Flatten)            (None, 2)            0           embedding_102[0][0]              
__________________________________________________________________________________________________
flatten_74 (Flatten)            (None, 2)            0           embedding_103[0][0]              
__________________________________________________________________________________________________
flatten_75 (Flatten)            (None, 16)           0           embedding_104[0][0]              
__________________________________________________________________________________________________
flatten_76 (Flatten)            (None, 6)            0           embedding_105[0][0]              
__________________________________________________________________________________________________
dense_191 (Dense)               (None, 4)            132         dense_190[0][0]                  
__________________________________________________________________________________________________
dense_194 (Dense)               (None, 4)            132         dense_193[0][0]                  
__________________________________________________________________________________________________
dense_195 (Dense)               (None, 1)            3           flatten_72[0][0]                 
__________________________________________________________________________________________________
dense_196 (Dense)               (None, 1)            3           flatten_73[0][0]                 
__________________________________________________________________________________________________
dense_197 (Dense)               (None, 1)            3           flatten_74[0][0]                 
__________________________________________________________________________________________________
dense_198 (Dense)               (None, 1)            17          flatten_75[0][0]                 
__________________________________________________________________________________________________
dense_199 (Dense)               (None, 1)            7           flatten_76[0][0]                 
__________________________________________________________________________________________________
concatenate_17 (Concatenate)    (None, 13)           0           dense_191[0][0]                  
                                                                 dense_194[0][0]                  
                                                                 dense_195[0][0]                  
                                                                 dense_196[0][0]                  
                                                                 dense_197[0][0]                  
                                                                 dense_198[0][0]                  
                                                                 dense_199[0][0]                  
__________________________________________________________________________________________________
dense_200 (Dense)               (None, 6)            84          concatenate_17[0][0]             
==================================================================================================
Total params: 2,333,273
Trainable params: 2,333,273
Non-trainable params: 0
__________________________________________________________________________________________________
Epoch 1/2

我无法理解这意味着什么。

我知道模型需要 7 个输入(它们也被传递给它),那么为什么它声称只接收 1 个?

顺便说一句,X_train.shape 的输出是 (11652, 7)

根据评论讨论更新代码部分:

所以我将层数减少到 2 层,结果是这样的:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import Model
from tensorflow.keras.layers import Input, Embedding, Dense, Concatenate, Flatten
from sklearn.preprocessing import LabelEncoder, OrdinalEncoder
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
from keras.layers.merge import concatenate
from keras.preprocessing.text import Tokenizer as Tok
from tensorflow.keras.preprocessing.sequence import pad_sequences

vocab_size = 1000
embedding_dim = 16
max_length = 128
trunc_type='post'
padding_type='post'
oov_tok = "<OOV>"


# prepare input data
def prepare_inputs(X_train, X_test):
    oe = OrdinalEncoder()
    oe.fit(X_train)
    X_train_enc = oe.fit_transform(X_train)
    X_test_enc = oe.fit_transform(X_test)
    return X_train_enc, X_test_enc
 
# prepare free text input
def prepare_free_text_inputs(X_train, X_test):
    training_sentences = X_train['message'] + ' ' + X_train['description']
    testing_sentences = X_test['message'] + ' ' + X_test['description']
    tokenizer = Tok(num_words=vocab_size, oov_token=oov_tok)
    tokenizer.fit_on_texts(training_sentences)
    word_index = tokenizer.word_index
    
    training_sequences = tokenizer.texts_to_sequences(training_sentences)
    training_padded = pad_sequences(training_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)
    
    testing_sequences = tokenizer.texts_to_sequences(testing_sentences)
    testing_padded = pad_sequences(testing_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)
    return training_padded, testing_padded
    
    
# prepare target
def prepare_targets(y_train, y_test):
    le = LabelEncoder()
    le.fit(y_train)
    y_train_enc = le.transform(y_train)
    y_test_enc = le.transform(y_test)
    return y_train_enc, y_test_enc
 

# prepare free_text input data
X_train_tokenized, X_test_tokenized = prepare_free_text_inputs(X_train, X_test)

# prepare categorical input data
X_train_ord, X_test_ord = prepare_inputs(X_train.iloc[:, 2:], X_test.iloc[:, 2:])

X_train_enc = pd.concat([pd.DataFrame(X_train_tokenized), pd.DataFrame(X_train_ord)], axis=1)
X_test_enc = pd.concat([pd.DataFrame(X_test_tokenized), pd.DataFrame(X_test_ord)], axis=1)

# prepare output data
y_train_enc, y_test_enc = prepare_targets(y_train, y_test)

print('Train', X_train_enc.shape, y_train_enc.shape)
print('Test', X_test.shape, y_test.shape)

input_free_text = Input(shape=(128,))
x = Embedding(vocab_size, 64)(input_free_text)
x = Flatten()(x)
x = Dense(64, activation="relu")(x)
x = Dense(32, activation="relu")(x)
x = Dense(4, activation="relu")(x)
model_free_text = Model(inputs=input_free_text, outputs=x)

input_categorical = Input(shape=(5,))
x = Embedding(5, 1)(input_categorical)
x = Flatten()(x)
x = Dense(1, activation="relu")(x)
model_categorical = Model(inputs=input_categorical, outputs=x)

combined = Concatenate()([model_free_text.output, model_categorical.output])

z = Dense(6, activation='softmax')(combined)
model = Model(inputs=[model_free_text.input, model_categorical.input], outputs=z)


model.compile(
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer=keras.optimizers.RMSprop(),
    metrics=["accuracy"],
)

model.summary()
keras.utils.plot_model(model, "model.png", show_shapes=True)
history = model.fit(y_train_enc, y_train_enc, batch_size=64, epochs=2, validation_split=0.2)

仍然有类似的错误:

ValueError: Layer model_235 expects 2 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'ExpandDims:0' shape=(None, 1) dtype=int64>]

1 个答案:

答案 0 :(得分:0)

然后回答我自己的问题:

事实证明我没有正确处理 fit 模型方法。 我不知道它也可以得到多个输入。 这就是我最终要做的(基于更新的问题代码):

history = model.fit(x=[X_train_tokenized, X_train_ord], y=y_train_enc, 
                    validation_data=([X_test_tokenized, X_test_ord], y_test_enc), 
                    batch_size=64, epochs=10)

test_scores = model.evaluate(x=[X_test_tokenized, X_test_ord], y=y_test_enc, verbose=0)