使用深度学习进行语义分析(使用深度学习进行语义分析)
前言
上篇文章《使用机器学习对图片进行分类》对服装图片进行分类,本篇文章开始对文字进行分类,判断一条评论是正面评论还是负面评论。
语义分析
这篇文章将训练一个语义分析模型,它用来区分一条电影评论是正面的还是负面的,二分模型是一个非常重要且应用广泛的机器学习课题。使用的数据集包含50000条电影评论,其中25000条用于训练,另外25000条用于测试。
从官网上进行下载,代码可以查看github网站上wangrl2016/multimedia/tutorials/TensorFlow/text_analysis.py文件
dataset = tf.keras.utils.get_file("aclImdb_v1", url,
untar=True, cache_dir=temp_dir,
cache_subdir='')
随机查看其中一条评论
I'm a male, not given to women's movies, but this is really a well done special story.
加载数据集
对于二分模型来说,需要建立train/pos/, train/neg/两个文件夹,train/pos/存放积极的评论,train/neg/存放消极的评论。
使用TensorFlow自带的工具将数据集分为三个部分:train,validation,test
raw_train_ds = tf.keras.utils.text_dataset_from_directory(
train_dir,
batch_size=batch_size,
validation_split=0.2,
subset='training',
seed=seed)
raw_val_ds = tf.keras.utils.text_dataset_from_directory(
train_dir,
batch_size=batch_size,
validation_split=0.2,
subset='validation',
seed=seed)
raw_test_ds = tf.keras.utils.text_dataset_from_directory(
test_dir,
batch_size=batch_size)
从train数据集中拿出20%用于validation
Found 25000 files belonging to 2 classes.
Using 20000 files for training.
Found 25000 files belonging to 2 classes.
Using 5000 files for validation.
Found 25000 files belonging to 2 classes.
可以通过遍历的方式查看数据集的内容
for text_batch, label_batch in raw_train_ds.take(1):
for i in range(3):
print("Review", text_batch.numpy()[i])
print("Label", label_batch.numpy()[i])
数据清洗
使用TextVectorization层对数据进行清洗,主要包含标准化,分割,数字化三个步骤。
- 标准化:去除文本中的标点、<br>等格式信息。
- 分割:将一句话分割成为一个一个的单词。
- 数字化:将单词转化为数字,方便神经网络进行处理。
定义一个字符串处理函数
def custom_standardization(input_data):
lowercase = tf.strings.lower(input_data)
stripped_html = tf.strings.regex_replace(lowercase, '<br />', ' ')
return tf.strings.regex_replace(stripped_html,
'[%s]' % re.escape(string.punctuation),
'')
定义一个TextVectorization层,将字符串处理函数传递进去
max_features = 10000
sequence_length = 250
vectorize_layer = layers.TextVectorization(
standardize=custom_standardization,
max_tokens=max_features,
output_mode='int',
output_sequence_length=sequence_length)
通过adapt方法将加载的数据集传入到TextVectorization层,只需要文本信息
# Make a text-only dataset (without labels), then call adapt
train_text = raw_train_ds.map(lambda x, y: x)
vectorize_layer.adapt(train_text)
将清洗后的数据利用函数打印出来,展示一个电影评论的输出
单词转化为文字
可以看到每个单词都被替换成为一个数字,通过get_vocabulary()查看每个数字对应的单词。
1287 ---> silent
313 ---> night
配置缓存
在加载数据的过程中为了减少I/O操作可以将数据加载到缓存中
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
test_ds = test_ds.cache().prefetch(buffer_size=AUTOTUNE)
创建模型
model = tf.keras.Sequential([
layers.Embedding(max_features 1, embedding_dim),
layers.Dropout(0.2),
layers.GlobalAveragePooling1D(),
layers.Dropout(0.2),
layers.Dense(1)])
Embedding层:以数字化的评论作为输入,查询该层内置的数组,并向输出中增加一个维度。
GlobalAveragePooling1D层:通过平均值返回一个固定长度的数组,便于处理输入长度不相等的情况。
Dense层:内部有16个隐藏单元,连接单一输出节点。
模型
损失函数和优化器
modelpile(loss=losses.BinaryCrossentropy(from_logits=True),
optimizer='adam',
metrics=tftrics.BinaryAccuracy(threshold=0.0))
训练模型
epochs = 10
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs)
评估模型
模型接近90%的正确率,通过model.fit函数返回训练过程中的历史记录,可以看到训练过程中的损失率变化,逐步降低。
训练损失
导出模型
在上面的示例中,TextVectorization是放在模型之前,其实也可以将其放在模型之中
export_model = tf.keras.Sequential([
vectorize_layer,
model,
layers.Activation('sigmoid')
])
将数据清洗层TextVectorization放在模型之前或者之中都有各自的优点,如果放在之前可以使用CPU异步处理这些数据,放在之中就可以利用GPU获取更好的性能。
推断新数据
后续就可以使用这个模型对电影评价进行分类
examples = [
"The movie was great!",
"The movie was okay.",
"The movie was terrible..."
]
通过模型的预测如下
[[0.6073785 ]
[0.42903066]
[0.34582636]]
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com