使用深度学习进行语义分析

前言

上篇文章《使用机器学习对图片进行分类》对服装图片进行分类,本篇文章开始对文字进行分类,判断一条评论是正面评论还是负面评论。

语义分析

这篇文章将训练一个语义分析模型,它用来区分一条电影评论是正面的还是负面的,二分模型是一个非常重要且应用广泛的机器学习课题。使用的数据集包含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层对数据进行清洗,主要包含标准化,分割,数字化三个步骤。

  1. 标准化:去除文本中的标点、
    等格式信息。
  2. 分割:将一句话分割成为一个一个的单词。
  3. 数字化:将单词转化为数字,方便神经网络进行处理。

定义一个字符串处理函数

def custom_standardization(input_data):    lowercase = tf.strings.lower(input_data)    stripped_html = tf.strings.regex_replace(lowercase, '
', ' ') return tf.strings.regex_replace(stripped_html, '[%s]' % re.escape(string.punctuation), '')

定义一个TextVectorization层,将字符串处理函数传递进去

max_features = 10000sequence_length = 250vectorize_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 adapttrain_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.AUTOTUNEtrain_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个隐藏单元,连接单一输出节点。

模型

损失函数和优化器

model.compile(loss=losses.BinaryCrossentropy(from_logits=True),              optimizer='adam',              metrics=tf.metrics.BinaryAccuracy(threshold=0.0))

训练模型

epochs = 10history = 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]]
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章