Tensorflow2.4从头训练Word Embedding实现文本分类

目录
  • 前言
  • 具体介绍
    • 1. 三种文本向量化方法
    • 2. 获取数据
    • 3. 处理数据
    • 4. 搭建、训练模型
    • 5. 导出训练好的词嵌入向量

前言

本文主要使用 cpu 版本的 tensorflow 2.4 版本完成文本的 word embedding 训练,并且以此为基础完成影评文本分类任务。

具体介绍

1. 三种文本向量化方法

通常在深度学习模型中我们的输入都是以向量形式存在的,所以我们处理数据过程的重要一项任务就是将文本中的 token (一个 token 可以是英文单词、一个汉字、一个中文词语等,需要自己规定)转换成对应的向量,本文会给出三种常见文本向量化的策略。

(1)One-Hot Encodings 。其实很好理解,假如我们的数据是“我是人”,因为有 3 个不同的汉字,我会给每个汉字一个对应的索引,然后我会创建一个长度为 3 的向量,假如我给每个汉字赋予的索引为“我->0”“是->1”“人->2”,那么每个字对应的 One-Hot Encodings 为 [1,0,0]、[0,1,0]、[0,0,1] 。那么“我是人”的这个句子的向量表示就可以将这三个向量拼接起来即可。这种方法的优点明显,方便理解和实现,但是缺点也很明显,效率非常低。One-Hot Encodings 所产生的的向量都是稀疏的。假如词汇表中有 1000 个单词,要对每个单词进行向量化编码,其中几乎 99% 的位置都为零。

(2)encode each word with a unique num 。我们可以使用唯一的数字对每个单词进行编码。还是上面的例子,我们给每个字分配一个对应的整数,假如分配结果为 “我->1”“是->2”“人->3”,我就能将句子“我是人”这句话就可以编码为一个稠密向量,如 [1,2,3]。此时的向量是一个稠密向量(所有位置都有有意义的整数填充)。但是这种方法有个缺点,编码的数字是可以人为任意设置,它不能捕获汉字之间的任何语义关系,也无法从数字上看出对应的近义词之间的关系。

(3)Word Embeddings 。词嵌入是一种将单词编码为有效稠密向量的方法,其中相似的单词具有相似相近的向量编码。词嵌入是浮点类型的稠密向量,向量的长度需要人为指定。我们不必像上面两种方法手动去设置编码中的向量值,而是将他们都作为可训练的参数,通过给模型喂大量的数据,不断的训练来捕获单词之间的细粒度语义关系,常见的词向量维度可以设置从 8 维到 1024 维范围中的任意整数。理论上维度越高词嵌入的语义越丰富但是训练成本越高。如我们上面的例子,我们设置词嵌入维度为 4 ,最后通过训练得到的词嵌入可能是 “我->[-3.2, 1.5, -4,6, 3.4]”“是-> [0.2, 0.6, -0.6, 1.5]”“人->[3.4, 5.3, -7.2, 1.5]”。

2. 获取数据

(1)本次我们要用到的是数据是 Large Movie Review Dataset ,我们需要使用 tensorflow 的内置函数从网络上下载到本地磁盘,为了简化数据,我们将训练数据目录中的 unsup 子目录都删除,最后取出 20000 个训练样本作为训练集,取出 5000 个训练样本作为验证集。

import io
import os
import re
import shutil
import string
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Embedding, GlobalAveragePooling1D
from tensorflow.keras.layers import TextVectorization
batch_size = 512
seed = 1
url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"
dataset = tf.keras.utils.get_file("aclImdb_v1.tar.gz", url,  untar=True, cache_dir='.', cache_subdir='')
dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')
train_dir = os.path.join(dataset_dir, 'train')
remove_dir = os.path.join(train_dir, 'unsup')
shutil.rmtree(remove_dir)
train_datas = tf.keras.utils.text_dataset_from_directory( 'aclImdb/train', batch_size=batch_size, validation_split=0.2, subset='training', seed=seed)
val_datas = tf.keras.utils.text_dataset_from_directory( 'aclImdb/train', batch_size=batch_size, validation_split=0.2, subset='validation', seed=seed)

(2)这里展示出 2 条样本,每个样本都有一个标签和一个文本描述,标签 1 表示评论是 positive , 标签 0 表示评论是: negative 。

1 b'The first time I saw this film, I was in shock for days afterwards. Its painstaking and absorbing treatment of the subject holds the attention, helped by good acting and some really intriguing music. The ending, quite simply, had me gasping. First rate!'
0 b"This is quite possibly the worst movie of all time. It stars Shaquille O'Neil and is about a rapping genie. Apparently someone out there thought that this was a good idea and got suckered into dishing out cash to produce this wonderful masterpiece. The movie gets 1 out of 10."

3. 处理数据

(1)为了保证在加载数据的时候不会出现 I/O 不会阻塞,我们在从磁盘加载完数据之后,使用 cache 会将数据保存在内存中,确保在训练模型过程中数据的获取不会成为训练速度的瓶颈。如果说要保存的数据量太大,可以使用 cache 创建磁盘缓存提高数据的读取效率。另外我们还使用 prefetch 在训练过程中可以并行执行数据的预获取。

AUTOTUNE = tf.data.AUTOTUNE
train_datas = train_datas.cache().prefetch(buffer_size=AUTOTUNE)
val_datas = val_datas.cache().prefetch(buffer_size=AUTOTUNE)

(2)将训练数据中的标签去掉,只保留文本描述,然后使用 TextVectorization 对数据进行预处理,先转换层小写英文,然后再将无用的字符剔除,并且我们规定了每个文本的最大长度为 100 个单词,超过的文本部分会被丢弃。最后将训练数据中的词都放入一个最大为 10000 的词汇表中,其中有一个特殊的表示 OOV 的 [UNK] ,也就说来自训练数据中的词只有 9999 个,使用 vectorize_layer 为每个单词进行 int 向量化,其实就是在文章开头提到的第二种向量化策略。

def handle(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), '')
vocab_size = 10000
sequence_length = 100
vectorize_layer = TextVectorization(standardize=handle,
                                    max_tokens=vocab_size,
                                    output_mode='int',
                                    output_sequence_length=sequence_length)
text_datas = train_datas.map(lambda x, y: x)
vectorize_layer.adapt(text_datas)

4. 搭建、训练模型

我们此次搭建的模型是一个“Continuous bag of words" 风格的模型。

(1)第一层是已经上面初始化好的 vectorize_layer ,它可以将文本经过预处理,然后将分割出来的单词都赋予对应的整数。

(2)第二层是一个嵌入层,我们定义了词嵌入维度为 32,也就是为每一个词对应的整数都转换为一个 32 维的向量来进行表示,这些向量的值是可以在模型训练时进行学习的权重参数。通过此层输出的维度为:(batch_size, sequence_length, embedding_dim)。

(3)第三层是一个 GlobalAveragePooling1D 操作,因为每个样本的维度为 (sequence_length, embedding_dim) ,该操作可以按照对 sequence_length 维度求平均值来为每个样本返回一个固定长度的输出向量,最后输出的维度为:(batch_size, embedding_dim)。

(4)第四层是一个输出 32 维向量的全连接层操作,并且使用 relu 激活函数进行非线性变化。

(5)最后一层是一个输出 1 维向量的全连接层操作,表示该样本的属于 positive 的概率。

(6)优化器选择 Adam ,损失函数为 BinaryCrossentropy ,评估指标为 accuracy

embedding_dim=32
model = Sequential([
  vectorize_layer,
  Embedding(vocab_size, embedding_dim, name="embedding"),
  GlobalAveragePooling1D(),
  Dense(32, activation='relu'),
  Dense(1)
])
model.compile(optimizer='adam', loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),  metrics=['accuracy'])
model.fit(train_datas, validation_data=val_datas, epochs=20, callbacks=[tensorboard_callback])

训练过程打印:

Epoch 1/20
40/40 [==============================] - 3s 52ms/step - loss: 0.6898 - accuracy: 0.4985 - val_loss: 0.6835 - val_accuracy: 0.5060
Epoch 2/20
40/40 [==============================] - 2s 50ms/step - loss: 0.6654 - accuracy: 0.4992 - val_loss: 0.6435 - val_accuracy: 0.5228
...
Epoch 19/20
40/40 [==============================] - 2s 49ms/step - loss: 0.1409 - accuracy: 0.9482 - val_loss: 0.4532 - val_accuracy: 0.8210
Epoch 20/20
40/40 [==============================] - 2s 48ms/step - loss: 0.1327 - accuracy: 0.9528 - val_loss: 0.4681 - val_accuracy: 0.8216

5. 导出训练好的词嵌入向量

这里我们取出已经训练好的词嵌入,然后打印出前三个单词以及词向量,因为索引 0 的词是空字符,所以直接跳过了,只显示了两个单词的内容。我们可以将所有训练好的词嵌入向量都写入本地磁盘的文件,供以后使用。

weights = model.get_layer('embedding').get_weights()[0]
vocab = vectorize_layer.get_vocabulary()
for i, word in enumerate(vocab[:3]):
    if i == 0:
        continue
    vecoter = weights[i]
    print(word,"||", ','.join([str(x) for x in vecoter]))

单词和对应词嵌入向量:

[UNK] || 0.020502748,-0.038312573,-0.036612183,-0.050346173,-0.07899615,-0.03143682,-0.06429587,0.07334388,-0.01887771,-0.08744612,-0.021639654,0.04726765,0.042426057,0.2240213,0.022607388,-0.08052631,0.023943739,0.05245169,-0.017815227,0.053340062,-0.033523336,0.057832733,-0.007486237,-0.16336738,0.022891225,0.12611994,-0.11084395,-0.0076115266,-0.03733231,-0.010371257,-0.045643456,-0.05392711
the || -0.029460065,-0.0021714368,-0.010394105,-0.03353872,-0.097529344,-0.05249973,-0.03901586,0.009200298,-0.085409686,-0.09302798,-0.07607663,0.046305165,-0.010357974,0.28357282,0.009442638,-0.036655612,0.063269086,0.06721396,0.063007854,0.03185595,-0.014642656,0.089468665,-0.014918188,-0.15671577,0.043026615,0.17086154,-0.0461816,0.021180542,-0.045269016,-0.101499856,-0.03948177,0.028299723

以上就是Tensorflow2.4从头训练Word Embedding实现文本分类的详细内容,更多关于Tensorflow Word Embedding的资料请关注我们其它相关文章!

(0)

相关推荐

  • TensorFlow.js实现AI换脸使用示例详解

    目录 前言 步骤 1:准备工作 步骤 2:加载模型 步骤 3:加载图片 步骤 4:提取面部关键点 步骤 5:应用变形 写在最后 前言 相信很多小伙伴对TensorFlow.js早已有所耳闻,它是一个基于JavaScript的深度学习库,可以在Web浏览器中运行深度学习模型.AI换脸是一种基于深度学习的图像处理技术,将一张人脸照片的表情.头发.嘴唇等特征转移到另一张人脸照片上,从而实现换脸效果.本文将介绍如何使用TensorFlow.js实现AI换脸 步骤 1:准备工作 在开始之前,需要确保已经安

  • 使用TensorFlow创建生成式对抗网络GAN案例

    目录 导入必要的库和模块 定义训练循环 最后定义主函数 导入必要的库和模块 以下是使用TensorFlow创建一个生成式对抗网络(GAN)的案例: 首先,我们需要导入必要的库和模块: import tensorflow as tf from tensorflow.keras import layers import matplotlib.pyplot as plt import numpy as np 然后,我们定义生成器和鉴别器模型.生成器模型将随机噪声作为输入,并输出伪造的图像.鉴别器模型则

  • 深度学习Tensorflow2.8 使用 BERT 进行文本分类

    目录 前言 1. python 库准备 2. BERT 是什么? 3. 获取并处理 IMDB 数据 4. 初识 TensorFlow Hub 中的 BERT 处理器和模型 5. 搭建模型 6. 训练模型 7. 测试模型 8. 保存模型 9. 重新加载模型并进行预测 前言 本文使用 cpu 版本的 Tensorflow 2.8 ,通过搭建 BERT 模型完成文本分类任务. 1. python 库准备 为了保证能正常运行本文代码,需要保证以下库的版本: tensorflow==2.8.4 tenso

  • 使用Tensorflow hub完成目标检测过程详解

    目录 前言 导入必要的库 准备数据和模型 目标检测 前言 本文主要介绍使用 tensorflow hub 中的 CenterNet HourGlass104 Keypoints 模型来完成简单的目标检测任务.使用到的主要环境是: tensorflow-cpu=2.10 tensorflow-hub=0.11.0 tensorflow-estimator=2.6.0 python=3.8 protobuf=3.20.1 导入必要的库 首先导入必要的 python 包,后面要做一些复杂的安装和配置工

  • Tensorflow 2.4 搭建单层和多层 Bi-LSTM 模型

    目录 前言 实现过程 1. 获取数据 2. 处理数据 3. 单层 Bi-LSTM 模型 4. 多层 Bi-LSTM 模型 前言 本文使用 cpu 版本的 TensorFlow 2.4 ,分别搭建单层 Bi-LSTM 模型和多层 Bi-LSTM 模型完成文本分类任务. 确保使用 numpy == 1.19.0 左右的版本,否则在调用 TextVectorization 的时候可能会报 NotImplementedError . 实现过程 1. 获取数据 (1)我们本文用到的数据是电影的影评数据,每

  • Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)

    Spire.Cloud.SDK for Java提供了TextRangesApi接口可通过addTextRange()添加文本.deleteTextRange()删除文本.updateTextRangeText()替换文本.updateTextRangeFormat()格式化文本等.本文将从以上方法介绍如何来实现对文本的操作.可参考以下步骤进行准备: 一.导入jar文件 创建Maven项目程序,通过maven仓库下载导入.以IDEA为例,新建Maven项目,在pom.xml文件中配置maven仓

  • 利用Java读取Word表格中文本和图片的方法实例

    目录 1. 程序环境准备 Jar导入步骤及方法: 方法1:手动导入. 方法2:Maven仓库导入. 2. Java代码 3. 文本.图片读取效果 总结 本文通过Java程序来展示如何读取Word表格,包括读取表格中的文本和图片.下面是具体实现的步骤和方法. 1. 程序环境准备 代码编译工具:IntelliJ IDEA Jdk版本:1.8.0 测试文档:Word .docx 2013 Jar包:free spire.doc.jar 3.9.0 用于测试的Word文档如下: Jar导入步骤及方法:

  • Python使用循环神经网络解决文本分类问题的方法详解

    本文实例讲述了Python使用循环神经网络解决文本分类问题的方法.分享给大家供大家参考,具体如下: 1.概念 1.1.循环神经网络 循环神经网络(Recurrent Neural Network, RNN)是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络. 卷积网络的输入只有输入数据X,而循环神经网络除了输入数据X之外,每一步的输出会作为下一步的输入,如此循环,并且每一次采用相同的激活函数和参数.在每次循环中,x0乘以系数U得到s0,再经过系数W输入

  • 使用pytorch和torchtext进行文本分类的实例

    文本分类是NLP领域的较为容易的入门问题,本文记录我自己在做文本分类任务以及复现相关论文时的基本流程,绝大部分操作都使用了torch和torchtext两个库. 1. 文本数据预处理 首先数据存储在三个csv文件中,分别是train.csv,valid.csv,test.csv,第一列存储的是文本数据,例如情感分类问题经常是用户的评论review,例如imdb或者amazon数据集.第二列是情感极性polarity,N分类问题的话就有N个值,假设值得范围是0~N-1. 下面是很常见的文本预处理流

  • Pytorch实现基于CharRNN的文本分类与生成示例

    1 简介 本篇主要介绍使用pytorch实现基于CharRNN来进行文本分类与内容生成所需要的相关知识,并最终给出完整的实现代码. 2 相关API的说明 pytorch框架中每种网络模型都有构造函数,在构造函数中定义模型的静态参数,这些参数将对模型所包含weights参数的维度进行设置.在运行时,模型的实例将接收动态的tensor数据并调用forword,在得到模型输出之后便可以和真实的标签数据进行误差计算,并通过优化器进行反向传播以调整模型的参数.下面重点介绍NLP常用到的模型和相关方法. 2

  • Python通过朴素贝叶斯和LSTM分别实现新闻文本分类

    目录 一.项目背景 二.数据处理与分析 三.基于机器学习的文本分类–朴素贝叶斯 1. 模型介绍 2. 代码结构 3. 结果分析 四.基于深度学习的文本分类–LSTM 1. 模型介绍 2. 代码结构 3. 结果分析 五.小结 一.项目背景 本项目来源于天池⼤赛,利⽤机器学习和深度学习等知识,对新闻⽂本进⾏分类.⼀共有14个分类类别:财经.彩票.房产.股票.家居.教育.科技.社会.时尚.时政.体育.星座.游戏.娱乐. 最终将测试集的预测结果上传⾄⼤赛官⽹,可查看排名.评价标准为类别f1_score的

  • python编写朴素贝叶斯用于文本分类

    朴素贝叶斯估计 朴素贝叶斯是基于贝叶斯定理与特征条件独立分布假设的分类方法.首先根据特征条件独立的假设学习输入/输出的联合概率分布,然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y. 具体的,根据训练数据集,学习先验概率的极大似然估计分布 以及条件概率为 Xl表示第l个特征,由于特征条件独立的假设,可得 条件概率的极大似然估计为 根据贝叶斯定理 则由上式可以得到条件概率P(Y=ck|X=x). 贝叶斯估计 用极大似然估计可能会出现所估计的概率为0的情况.后影响到后验概率结果

  • python使用RNN实现文本分类

    本文实例为大家分享了使用RNN进行文本分类,python代码实现,供大家参考,具体内容如下 1.本博客项目由来是oxford 的nlp 深度学习课程第三周作业,作业要求使用LSTM进行文本分类.和上一篇CNN文本分类类似,本此代码风格也是仿照sklearn风格,三步走形式(模型实体化,模型训练和模型预测)但因为训练时间较久不知道什么时候训练比较理想,因此在次基础上加入了继续训练的功能. 2.构造文本分类的rnn类,(保存文件为ClassifierRNN.py) 2.1 相应配置参数因为较为繁琐,

  • tensorflow学习教程之文本分类详析

    前言 这几天caffe2发布了,支持移动端,我理解是类似单片机的物联网吧应该不是手机之类的,试想iphone7跑CNN,画面太美~ 作为一个刚入坑的,甚至还没入坑的人,咱们还是老实研究下tensorflow吧,虽然它没有caffe好上手.tensorflow的特点我就不介绍了: 基于Python,写的很快并且具有可读性. 支持CPU和GPU,在多GPU系统上的运行更为顺畅. 代码编译效率较高. 社区发展的非常迅速并且活跃. 能够生成显示网络拓扑结构和性能的可视化图. tensorflow(tf)

  • Python如何使用神经网络进行简单文本分类

    深度学习无处不在.在本文中,我们将使用Keras进行文本分类. 准备数据集 出于演示目的,我们将使用  20个新闻组  数据集.数据分为20个类别,我们的工作是预测这些类别.如下所示: 通常,对于深度学习,我们将划分训练和测试数据. 导入所需的软件包 Python import pandas as pd import numpy as np import pickle from keras.preprocessing.text import Tokenizer from keras.models

随机推荐