【发布时间】:2022-01-23 19:22:17
【问题描述】:
我基本上是在运行 Francois Chollet 的 Python 深度学习第 11 章中的代码。 这是一个二元情感分类。对于每个句子,标签是 0 或 1。 在运行本书中的模型后,我尝试对其中一个“验证”语句进行预测。 完整代码是一个公开的 kaggle 笔记本,可以在这里找到: https://www.kaggle.com/louisbunuel/deep-learning-with-python 这是笔记本的一部分: https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/chapter11_part02_sequence-models.ipynb
我唯一添加的是从标记化的 tensorflow 数据集中“提取”标记化的句子,以便我可以看到输出示例。我期待一个从 0 到 1 的数字(确实是概率),但我得到了一个从 0 到 1 的数字数组,句子中的每个单词都有一个。换句话说,看起来模型没有为每个句子分配标签,而是为每个单词分配标签。
谁能解释我做错了什么?这是我从张量流数据集中“提取”句子的方式吗?
这是来自 book/github 的代码,在 notebook 中
!curl -O https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
!tar -xf aclImdb_v1.tar.gz
!rm -r aclImdb/train/unsup
import os, pathlib, shutil, random
from tensorflow import keras
batch_size = 32
base_dir = pathlib.Path("aclImdb")
val_dir = base_dir / "val"
train_dir = base_dir / "train"
for category in ("neg", "pos"):
os.makedirs(val_dir / category)
files = os.listdir(train_dir / category)
random.Random(1337).shuffle(files)
num_val_samples = int(0.2 * len(files))
val_files = files[-num_val_samples:]
for fname in val_files:
shutil.move(train_dir / category / fname,
val_dir / category / fname)
train_ds = keras.utils.text_dataset_from_directory(
"aclImdb/train", batch_size=batch_size
)
val_ds = keras.utils.text_dataset_from_directory(
"aclImdb/val", batch_size=batch_size
)
test_ds = keras.utils.text_dataset_from_directory(
"aclImdb/test", batch_size=batch_size
)
text_only_train_ds = train_ds.map(lambda x, y: x)
准备整数序列数据集
from tensorflow.keras import layers
max_length = 600
max_tokens = 20000
text_vectorization = layers.TextVectorization(
max_tokens=max_tokens,
output_mode="int",
output_sequence_length=max_length,
)
text_vectorization.adapt(text_only_train_ds)
int_train_ds = train_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_val_ds = val_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_test_ds = test_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
embedding_layer = layers.Embedding(input_dim=max_tokens, output_dim=256)
inputs = keras.Input(shape=(None,), dtype="int64")
embedded = layers.Embedding(input_dim=max_tokens, output_dim=256)(inputs)
x = layers.Bidirectional(layers.LSTM(32))(embedded)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs, outputs)
model.compile(optimizer="rmsprop",
loss="binary_crossentropy",
metrics=["accuracy"])
model.summary()
callbacks = [
keras.callbacks.ModelCheckpoint("embeddings_bidir_gru.keras",
save_best_only=True)
]
model.fit(int_train_ds, validation_data=int_val_ds, epochs=2, callbacks=callbacks)
model = keras.models.load_model("embeddings_bidir_gru.keras")
print(f"Test acc: {model.evaluate(int_test_ds)[1]:.3f}")
我对代码的“补充”就是这部分。模型跑完后,我取出这样一句话:
ds = int_val_ds.take(1) # int_val_ds is the dataframe that is already vectorized to numbers
for sentence, label in ds: # example is (sentence, label)
print(sentence.shape, label)
>> (32, 600) tf.Tensor([1 1 1 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 0 0 1 0 0 0], shape=(32,), dtype=int32)
所以它是一组 32 个句子,有 36 个对应的标签 如果我看一个元素的形状
sentence[2].shape
>> TensorShape([600])
如果我输入
model.predict(sentence[2])
>> array([[0.49958456],
[0.50042397],
[0.50184965],
[0.4992085 ],...
[0.50077164]], dtype=float32)
包含 600 个元素。我期待一个介于 0 和 1 之间的数字。出了什么问题?
【问题讨论】:
-
显示 nlp keras 模型
-
我加了,谢谢。
-
您是否将序列填充到输入形状
-
尝试重塑你的输入数组:model.predict(tf.reshape(sentence[2] , [1 , 600] );
-
谢谢,它成功了。你写的是评论还是答案?我是新来的,我不知道所有的来龙去脉。我问是因为我看不到投票的按钮。
标签: python tensorflow nlp text-classification