昇思25天学习打卡营第18天|RNN实现情感分类

相关知识

情感分类

指输入一段话或句子,返回该段话的正向或复兴的情感分类。

text embedding

指将文本转化成向量的方法。这里的文本指词、句子、文档等文本序列。
词向量化后会将词转为二进制(独热编码)或高维实数向量,句子和文档向量化则将句子或文档转为数值向量。具体方法包括,平均每个词的词向量(Word2Vec、Doc2Vec),或使用Bert或GPT来捕捉句子的语义和上下文信息。

IMDB数据集

数据集链接:Sentiment Analysis (stanford.edu)
该数据集包含了50000条偏向明显的电影评论,其中25000条是训练集,另外为测试集。label为postive和negative。

数据集中给出了大小89527的字典文件“imdb.vocab”方便做embedding。在词典中的单词embedding时则为单词的序列号,不在词典中的设为0.

GloVe

GloVe是获取单词向量表示的无监督学习算法。它可以把单词表达成一个实数组成的向量,这些向量捕捉到了单词之间的语义特性,如相似性,类比性等。它的训练使用语料库中汇总的全球词-词共同出现的统计数据,展现了词向量空间的线性子结构。
要点1:共现词频矩阵
x_i定义为任意词出现在x附近的次数
P_ij得到的是给定词x_i的环境中出现x_j的频率,也称共先概率。词与词之间的共现概率比值可以直接或间接的表示出两个词对给定词的相关性。
glove期望能通过三个词的词向量表达共现关系比。

LSTM

循环神经网络 recurrent neural network,以序列数据为输入,在序列的演进方向上进行递归,且所有的循环单元都按照链式连接的神经网络。RNN在不断循环计算中更新。而在序列较长时,尾部就会丢失序列首部的信息,造成了梯度消失的问题。LSTM通过门控系统来控制信息的保存和丢弃,从而能更好的捕获长距离的关系。

实验

数据加载

class IMDBData():
# 两个极性标签  label_map = {"pos": 1,"neg": 0}def __init__(self, path, mode="train"):self.mode = modeself.path = pathself.docs, self.labels = [], []self._load("pos")self._load("neg")
# 加载为可迭代对象def _load(self, label):pattern = re.compile(r"aclImdb/{}/{}/.*\.txt$".format(self.mode, label))# 将数据加载至内存with tarfile.open(self.path) as tarf:tf = tarf.next()while tf is not None:if bool(pattern.match(tf.name)):# 对文本进行分词、去除标点和特殊字符、小写处理self.docs.append(str(tarf.extractfile(tf).read().rstrip(six.b("\n\r")).translate(None, six.b(string.punctuation)).lower()).split())self.labels.append([self.label_map[label]])tf = tarf.next()def __getitem__(self, idx):return self.docs[idx], self.labels[idx]def __len__(self):return len(self.docs)
# 使用Generatordataset加载数据集
def load_imdb(imdb_path):imdb_train = ds.GeneratorDataset(IMDBData(imdb_path, "train"), column_names=["text", "label"], shuffle=True, num_samples=10000)imdb_test = ds.GeneratorDataset(IMDBData(imdb_path, "test"), column_names=["text", "label"], shuffle=False)return imdb_train, imdb_test

加载词向量

# 加载glove
def load_glove(glove_path):glove_100d_path = os.path.join(cache_dir, 'glove.6B.100d.txt')if not os.path.exists(glove_100d_path):glove_zip = zipfile.ZipFile(glove_path)glove_zip.extractall(cache_dir)embeddings = []tokens = []with open(glove_100d_path, encoding='utf-8') as gf:for glove in gf:word, embedding = glove.split(maxsplit=1)tokens.append(word)embeddings.append(np.fromstring(embedding, dtype=np.float32, sep=' '))# 增加两个embedding
# 分别针对词表中没有对应单词
# 及输入长度不一致打包成batch时填充的短文本embeddings.append(np.random.rand(100))embeddings.append(np.zeros((100,), np.float32))vocab = ds.text.Vocab.from_list(tokens, special_tokens=["<unk>", "<pad>"], special_first=False)embeddings = np.array(embeddings).astype(np.float32)return vocab, embeddings

数据集预处理

这里将所有的token都处理成indexid,并让文本序列统一长度,不足的补齐,超出的截断。

# 查询
lookup_op = ds.text.Lookup(vocab, unknown_token='<unk>')
# 补齐
pad_op = ds.transforms.PadEnd([500], pad_value=vocab.tokens_to_ids('<pad>'))
type_cast_op = ds.transforms.TypeCast(ms.float32)
# 对训练集和测试集进行处理
imdb_train = imdb_train.map(operations=[lookup_op, pad_op], input_columns=['text'])
imdb_train = imdb_train.map(operations=[type_cast_op], input_columns=['label'])imdb_test = imdb_test.map(operations=[lookup_op, pad_op], input_columns=['text'])
imdb_test = imdb_test.map(operations=[type_cast_op], input_columns=['label'])
# 手动分割训练验证
imdb_train, imdb_valid = imdb_train.split([0.7, 0.3])
# 指定batch大小,并丢弃剩余的
imdb_train = imdb_train.batch(64, drop_remainder=True)
imdb_valid = imdb_valid.batch(64, drop_remainder=True)

模型构建

整体结构为 nn.Embedding -> nn.RNN(特征提取) -> nn.Dense(全连接层)

class RNN(nn.Cell):def __init__(self, embeddings, hidden_dim, output_dim, n_layers,bidirectional, pad_idx):super().__init__()vocab_size, embedding_dim = embeddings.shape
# 将之前的词表设为embedding层self.embedding = nn.Embedding(vocab_size, embedding_dim, embedding_table=ms.Tensor(embeddings), padding_idx=pad_idx)
# 设定LSTM层self.rnn = nn.LSTM(embedding_dim,hidden_dim,num_layers=n_layers,bidirectional=bidirectional,batch_first=True)weight_init = HeUniform(math.sqrt(5))bias_init = Uniform(1 / math.sqrt(hidden_dim * 2))
# 设定全连接层self.fc = nn.Dense(hidden_dim * 2, output_dim, weight_init=weight_init, bias_init=bias_init)def construct(self, inputs):embedded = self.embedding(inputs)_, (hidden, _) = self.rnn(embedded)hidden = ops.concat((hidden[-2, :, :], hidden[-1, :, :]), axis=1)output = self.fc(hidden)return outputdef forward_fn(data, label):logits = model(data)loss = loss_fn(logits, label)return lossgrad_fn = ms.value_and_grad(forward_fn, None, optimizer.parameters)def train_step(data, label):loss, grads = grad_fn(data, label)optimizer(grads)return lossdef train_one_epoch(model, train_dataset, epoch=0):model.set_train()total = train_dataset.get_dataset_size()loss_total = 0step_total = 0with tqdm(total=total) as t:t.set_description('Epoch %i' % epoch)for i in train_dataset.create_tuple_iterator():loss = train_step(*i)loss_total += loss.asnumpy()step_total += 1t.set_postfix(loss=loss_total/step_total)t.update(1)hidden_size = 256
output_size = 1
num_layers = 2
bidirectional = True
lr = 0.001
pad_idx = vocab.tokens_to_ids('<pad>')model = RNN(embeddings, hidden_size, output_size, num_layers, bidirectional, pad_idx)# 使用二分类交叉熵损失函数
loss_fn = nn.BCEWithLogitsLoss(reduction='mean')
optimizer = nn.Adam(model.trainable_params(), learning_rate=lr)

模型训练

def forward_fn(data, label):logits = model(data)loss = loss_fn(logits, label)return lossgrad_fn = ms.value_and_grad(forward_fn, None, optimizer.parameters)def train_step(data, label):loss, grads = grad_fn(data, label)optimizer(grads)return lossdef train_one_epoch(model, train_dataset, epoch=0):model.set_train()total = train_dataset.get_dataset_size()loss_total = 0step_total = 0with tqdm(total=total) as t:t.set_description('Epoch %i' % epoch)for i in train_dataset.create_tuple_iterator():loss = train_step(*i)loss_total += loss.asnumpy()step_total += 1t.set_postfix(loss=loss_total/step_total)t.update(1)

效果评估

def binary_accuracy(preds, y):"""计算每个batch的准确率"""# 对预测值进行四舍五入rounded_preds = np.around(ops.sigmoid(preds).asnumpy())correct = (rounded_preds == y).astype(np.float32)acc = correct.sum() / len(correct)return accdef evaluate(model, test_dataset, criterion, epoch=0):total = test_dataset.get_dataset_size()epoch_loss = 0epoch_acc = 0step_total = 0model.set_train(False)with tqdm(total=total) as t:t.set_description('Epoch %i' % epoch)for i in test_dataset.create_tuple_iterator():predictions = model(i[0])loss = criterion(predictions, i[1])epoch_loss += loss.asnumpy()acc = binary_accuracy(predictions, i[1])epoch_acc += accstep_total += 1t.set_postfix(loss=epoch_loss/step_total, acc=epoch_acc/step_total)t.update(1)return epoch_loss / totalnum_epochs = 2
best_valid_loss = float('inf')
ckpt_file_name = os.path.join(cache_dir, 'sentiment-analysis.ckpt')for epoch in range(num_epochs):train_one_epoch(model, imdb_train, epoch)valid_loss = evaluate(model, imdb_valid, loss_fn, epoch)
# 将loss最小的结果保存if valid_loss < best_valid_loss:best_valid_loss = valid_lossms.save_checkpoint(model, ckpt_file_name)

模型加载与测试

param_dict = ms.load_checkpoint(ckpt_file_name)
ms.load_param_into_net(model, param_dict)
imdb_test = imdb_test.batch(64)
evaluate(model, imdb_test, loss_fn)

模型预测

score_map = {1: "Positive",0: "Negative"
}def predict_sentiment(model, vocab, sentence):model.set_train(False)tokenized = sentence.lower().split()indexed = vocab.tokens_to_ids(tokenized)tensor = ms.Tensor(indexed, ms.int32)tensor = tensor.expand_dims(0)prediction = model(tensor)return score_map[int(np.round(ops.sigmoid(prediction).asnumpy()))]

总结

本章基于glove,使用LSTM完成情感分类任务。

打卡凭证

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3248689.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC注解全解析:构建高效Web应用的终极指南 (下)

一. 引言 在上篇文章中&#xff0c;我们介绍了几个重要的SpringMVC注解&#xff1a; SpringBootApplication&#xff1a;Spring Boot项目的启动类注解。RequestMapping&#xff1a;用于映射URL到控制器类或方法&#xff0c;支持多种请求方式。RequestParam&#xff1a;用于绑…

科研绘图系列:R语言分割小提琴图(Split-violin)

介绍 分割小提琴图(Split-violin plot)是一种数据可视化工具,它结合了小提琴图(violin plot)和箱线图(box plot)的特点。小提琴图是一种展示数据分布的图形,它通过在箱线图的两侧添加曲线来表示数据的密度分布,曲线的宽度表示数据点的密度。而分割小提琴图则是将小提…

41.ILA IP核集成逻辑分析仪在线调试工具

&#xff08;1&#xff09;逻辑分析仪使用场景&#xff1a; 仿真不全面数据交互存在异步情况板卡互联可靠性问题 (2)ILA使用方法&#xff1a; 使用IP核创建ILA调试环境使用Debug标记创建IP核使用路径标记核位置调试菜单创建ILA测试环境 (3)IP核调用过程&#xff1a; 例化模…

基于ssh的链接异常解决方法

VSCode、PyCharm链接异常 一.可能的原因 1.如果实例的系统盘重置或更换镜像&#xff0c;那么SSH的指纹会发生变化&#xff0c;于是SSH时会报错REMOTE HOST IDENTIFICATION HAS CHANGED 2.如果本地ssh config文件权限不对&#xff0c;会由于ssh时无法写入配置报错&#xff08;…

【BUG】已解决:IndexError: list index out of range

已解决&#xff1a;IndexError: list index out of range 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社区主…

长难句打卡7.15

The trend was naturally most obvious in those areas of science based especially on a mathematical or laboratory training, and can be illustrated in terms of the development of geology in the United Kingdom 这一趋势自然在以数学或实验室训练为基础的科学领域里…

探寻大模型回答9.9和9.11犯错的根本原因

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

养猫新手不会挑智能猫砂盆?2024最新挑选干货分享!

不得不说智能猫砂盆真的帮了我很大的忙&#xff0c;四年以来我陆陆续续养了很多的猫咪&#xff0c;但是因为需要上班&#xff0c;所以有时候也对铲屎的工作有些力不从心&#xff0c;后面听了朋友的建议&#xff0c;去入手了智能猫砂盆&#xff0c;不得不说买智能猫砂盆也非常的…

Java 8的变革:函数式编程和Lambda表达式探索

文章目录 一、函数接口二、Lambda表达式简介三、Lambda表达式外部参数四、Lambda范例五、Runnable Lambda表达式 一、函数接口 函数接口是一个具有单个抽象方法的接口&#xff0c;接口设计主要是为了支持 Lambda 表达式和方法引用&#xff0c;使得 Java 能更方便地实现函数式编…

【排序算法】—— 计数排序

一、简介 计数排序&#xff0c;顾名思义就是记录数据出现的次数进行排序&#xff0c;时间复杂度为O(NK)&#xff0c;空间复杂度为O(N)。只能用于整型&#xff0c;对于比较集中重复率比较高数据更为适用。 二、排序原理 比如对接下来这些数进行排序 arr[11] { 8,6,4,1,6,2,9,…

国产化低功耗HDMI转VGA方案,大量出货产品,广泛应用在显示器以及广告机产品

芯片描述&#xff1a; 兼具高性能和低成本效益的优点&#xff0c;是一款可以将高清视频 HDMI1.4 数字信号转换成 VGA 模拟信号输出的芯片。不需要提供外部电源&#xff0c;ICNM7301 就可以在正常模式下使用&#xff1b;ICNM7301 广 泛适用于各种市场系统和显示应用体系&#x…

Bash 学习摘录

文章目录 1、变量和参数的介绍&#xff08;1&#xff09;变量替换$(...) &#xff08;2&#xff09;特殊的变量类型export位置参数shift 2、引用&#xff08;1&#xff09;引用变量&#xff08;2&#xff09;转义 3、条件判断&#xff08;1&#xff09;条件测试结构&#xff08…

vue自定义折叠Tree,自定义折叠树

使用组件 <TreeNode v-for"(node, index) in nodes" :key"index" :node"node" />JSON数据 let nodes[{"id": 2030,"show_id": "MC1813024492270223360","detail_type": 1,"title": &…

Geometric Transformer for Fast and Robust Point Cloud Registration 论文解读

目录 一、导言 二、先导知识 1、超点匹配 2、KPConv 三、相关工作 1、基于对应的方法 2、直接配准方法 3、深度鲁棒估计 四、GeoTransformer模型 1、特征提取 2、超点匹配 几何自注意力模块 特征交叉注意力 计算高斯相关性 对应点采样 3、点匹配 4、局部到全局…

花开半夏,我决意仿一款答题小程序

不是清凉罢挥扇&#xff0c;自缘手倦歇些时。 ——杨万里&#xff08;宋&#xff09; 走过春的绚烂&#xff0c;路过初夏的清凉&#xff0c;我们迎来了炎炎夏日。蛙声阵阵&#xff0c;蝉鸣声声&#xff0c;稻花如白练&#xff0c;荷花别样红。 花开半夏&#xff0c;我决意仿一款…

陕西技术交易大会璀璨起航,卓翼飞思无人智能领域研究成果备受瞩目

智启未来&#xff0c;链动四方。万众瞩目的陕西省技术交易大会于7月17-18日在西安璀璨启航&#xff01;大会聚焦智能感知及其上下游产业链&#xff0c;旨在促进四链深度融合&#xff0c;推动技术创新与产业发展。卓翼智能作为产业链中“智能感知应用端”的杰出企业代表&#xf…

【刷题专项】— 模拟

1、替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 首先找到需要替换的 ? &#xff0c;位置然后遍历26个字母与 ? 的左右两边的是否相同&#xff0c;不同的话就替换最后返回即可代码&#xff1a; public String modifyString(String s) {char[] c…

MySQL运维实战之Clone插件(10.1)使用Clone插件

作者&#xff1a;俊达 clone插件介绍 mysql 8.0.17版本引入了clone插件。使用clone插件可以对本地l或远程的mysql实例进行clone操作。clone插件会拷贝innodb存储引擎表&#xff0c;clone得到的是原数据库的一个一致性的快照&#xff0c;可以使用该快照数据来启动新的实例。cl…

Android View的绘制流程

1.不管是View的添加&#xff0c;还是调用View的刷新方法invalidate()或者requestLayout()&#xff0c;绘制都是从ViewRootImpl的scheduleTraversals()方法开始 void scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled true;mTraversalBarrier mHandler…

【论文速读】| TCSR-SQL:面向表内容感知的自检索文本到SQL方法

本次分享论文&#xff1a;TCSR-SQL: Towards Table Content-aware Text-to-SQL with Self-retrieval 基本信息 原文作者&#xff1a;Wenbo Xu, Liang Yan, Peiyi Han, Haifeng Zhu, Chuanyi Liu, Shaoming Duan, Cuiyun Gao, Yingwei Liang 作者单位&#xff1a;哈尔滨工业大…