【发布时间】:2021-09-28 16:38:53
【问题描述】:
我正在处理一个文本分类项目,其数据框有 7 个特征(列)和 1 个标签列(多 class==> 总共有 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)
根据 cmets 讨论更新代码部分:
所以我将层数减少到 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>]
【问题讨论】:
-
您是否尝试过重塑输入并沿轴连接?
-
@B.Kocis 没有。你能建议怎么做吗?
-
你有 7 个输入层。所以,
x_train应该包含您的 7 个输入数据。将x_train的定义添加到您的问题中。错误提示x_train仅提供 1 个输入数据。 -
@Kaveh
X_train.shape的输出是(11652, 7)(也更新了问题) -
它期望第一个维度为 7
标签: python keras scikit-learn text-classification