中文新闻文本标题分类(基于飞桨、Text CNN)

目录

一、设计方案概述

二、具体实现

三、结果及分析 

四、总结

一、设计方案概述

主要网络模型设计:

设计所使用网络模型为TextCNN,由于其本身就适用于短中句子,在标题分类这一方面应该能发挥其优势。

TextCNN是Yoon Kim在2014年提出的模型,开创了用CNN编码n-gram特征的先河

图1-1

模型结构如图,图像中的卷积都是二维的,而TextCNN则使用「一维卷积」,即filter_size * embedding_dim,有一个维度和embedding相等。这样就能抽取filter_size个gram的信息。以1个样本为例,整体的前向逻辑是:

对词进行embedding,得到[seq_length, embedding_dim]

用N个卷积核,得到N个seq_length-filter_size+1长度的一维feature map

对feature map进行max-pooling(因为是时间维度的,也称max-over-time pooling),得到N个1x1的数值,拼接成一个N维向量,作为文本的句子表示

将N维向量压缩到类目个数的维度,过Softmax

网络结构图:

图1-2

在TextCNN的实践中,有很多地方可以优化。

Filter尺寸:这个参数决定了抽取n-gram特征的长度,这个参数主要跟数据有关,平均长度在50以内的话,用10以下就可以了,否则可以长一些。在调参时可以先用一个尺寸grid search,找到一个最优尺寸,然后尝试最优尺寸和附近尺寸的组合

Filter个数:这个参数会影响最终特征的维度,维度太大的话训练速度就会变慢。使用100-600之间即可

CNN的激活函数:选择Identity、ReLU、tanh

正则化:指对CNN参数的正则化,可以使用dropout或L2,但能起的作用很小,可以试下小的dropout率(<0.5),L2限制大一点

Pooling方法:根据情况选择mean、max、k-max pooling,大部分时候max表现就很好,因为分类任务对细粒度语义的要求不高,只抓住最大特征就好了。

Embedding表:中文选择char或word级别的输入,也可以两种都用,会提升些效果。如果训练数据充足(10w+),也可以从头训练

蒸馏BERT的logits,利用领域内无监督数据。

加深全连接:加到3、4层左右效果会更好。

TextCNN是很适合中短文本场景的强baseline,但不太适合长文本,因为卷积核尺寸通常不会设很大,无法捕获长距离特征。同时max-pooling也存在局限,会丢掉一些有用特征。

简单流程图:

图1-3

二、具体实现

完整代码:

import os
from multiprocessing import cpu_count
import numpy as np
import paddle
import paddle.fluid as fluid
import matplotlib.pyplot as plt
paddle.enable_static()
data_root_path='./data/'#创建数据集
def create_data_list(data_root_path):with open(data_root_path + 'test_list.txt', 'w') as f:passwith open(data_root_path + 'train_list.txt', 'w') as f:passwith open(os.path.join(data_root_path, 'dict_txt.txt'), 'r', encoding='utf-8') as f_data:dict_txt = eval(f_data.readlines()[0])with open(os.path.join(data_root_path, 'data/Train.txt'), 'r', encoding='utf-8') as f_data:lines = f_data.readlines()i = 0for line in lines:title = line.split('\t')[-1].replace('\n', '')l = line.split('\t')[0]labs = ""if i % 10 == 0:with open(os.path.join(data_root_path, 'test_list.txt'), 'a', encoding='utf-8') as f_test:for s in title:lab = str(dict_txt[s])labs = labs + lab + ','labs = labs[:-1]labs = labs + '\t' + l + '\n'f_test.write(labs)else:with open(os.path.join(data_root_path, 'train_list.txt'), 'a', encoding='utf-8') as f_train:for s in title:lab = str(dict_txt[s])labs = labs + lab + ','labs = labs[:-1]labs = labs + '\t' + l + '\n'f_train.write(labs)i += 1print("数据列表生成完成!")#把下载得数据生成一个字典
def create_dict(data_path, dict_path):dict_set = set()# 统计有多少种类别,分别对应的id,并显示出来以供后面的预测应用id_and_className = {}# 读取已经下载得数据with open(data_path, 'r', encoding='utf-8') as f:lines = f.readlines()# 把数据生成一个元组for line in lines:lineList = line.split('\t')title = lineList[-1].replace('\n', '')classId = lineList[0]if classId not in id_and_className.keys():id_and_className[classId] = lineList[1]for s in title:dict_set.add(s)# 把元组转换成字典,一个字对应一个数字dict_list = []i = 0for s in dict_set:dict_list.append([s, i])i += 1# 添加未知字符dict_txt = dict(dict_list)end_dict = {"<unk>": i}dict_txt.update(end_dict)# 把这些字典保存到本地中with open(dict_path, 'w', encoding='utf-8') as f:f.write(str(dict_txt))print("数据字典生成完成!")print('类Id及其类别名称:', id_and_className)
# 获取字典的长度
def get_dict_len(dict_path):with open(dict_path, 'r', encoding='utf-8') as f:line = eval(f.readlines()[0])return len(line.keys())
def data_mapper(sample):data, label = sampledataList=[]for e in data.split(','):if e=='':print('meet blank')else:dataList.append(np.int64(e))return dataList, int(label)# 创建数据读取器train_reader
def train_reader(train_list_path):def reader():with open(train_list_path, 'r') as f:lines = f.readlines()# 打乱数据np.random.shuffle(lines)# 开始获取每张图像和标签for line in lines:data, label = line.split('\t')yield data, labelreturn paddle.reader.xmap_readers(data_mapper, reader, cpu_count(), 1024)
#  创建数据读取器test_reader
def test_reader(test_list_path):def reader():with open(test_list_path, 'r') as f:lines = f.readlines()for line in lines:data, label = line.split('\t')yield data, labelreturn paddle.reader.xmap_readers(data_mapper, reader, cpu_count(), 1024)#   网络定义
def CNN_net(data, dict_dim, class_dim=14, emb_dim=128, hid_dim=128, hid_dim2=98):emb = fluid.layers.embedding(input=data,size=[dict_dim, emb_dim])conv_1 = fluid.nets.sequence_conv_pool(input=emb,num_filters=hid_dim,filter_size=3,act="tanh",pool_type="max")conv_2 = fluid.nets.sequence_conv_pool(input=emb,num_filters=hid_dim,filter_size=4,act="tanh",pool_type="max")conv_3 = fluid.nets.sequence_conv_pool(input=emb,num_filters=hid_dim2,filter_size=4,act="tanh",pool_type="max")fc1 = fluid.layers.fc(input=[conv_1, conv_2,conv_3], size=128, act='softmax')bn = fluid.layers.batch_norm(input=fc1, act='relu')fc2 = fluid.layers.fc(input= bn, size=64, act='softmax')bn1 = fluid.layers.batch_norm(input=fc2, act='relu')fc3 = fluid.layers.fc(input= bn1, size=class_dim, act='softmax')return fc3# 定义绘制训练过程的损失值和准确率变化趋势的方法draw_train_process
all_train_iter=0
all_train_iters=[]
all_train_costs=[]
all_train_accs=[]
def draw_train_process(title,iters,costs,accs,label_cost,lable_acc):plt.title(title, fontsize=24)plt.xlabel("iter", fontsize=20)plt.ylabel("cost/acc", fontsize=20)plt.plot(iters, costs,color='red',label=label_cost)plt.plot(iters, accs,color='green',label=lable_acc)plt.legend()plt.grid()plt.show()# 把生产的数据列表都放在自己的总类别文件夹中
data_path = os.path.join(data_root_path, 'data/Train.txt')
dict_path = os.path.join(data_root_path, "dict_txt.txt")
# 创建数据字典
create_dict(data_path, dict_path)
# 创建数据列表
create_data_list(data_root_path)words = fluid.layers.data(name='words', shape=[1], dtype='int64', lod_level=1)
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
# 获取数据字典长度
dict_dim = get_dict_len('data/dict_txt.txt')
# 获取卷积神经网络
# 获取分类器
model = CNN_net(words, dict_dim)
# 获取损失函数和准确率
cost = fluid.layers.cross_entropy(input=model, label=label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=model, label=label)# 获取预测程序
test_program = fluid.default_main_program().clone(for_test=True)
# 定义优化方法
optimizer = fluid.optimizer.AdagradOptimizer(learning_rate=0.002)
opt = optimizer.minimize(avg_cost)# 创建一个执行器,CPU训练速度比较慢
# 定义使用CPU还是GPU,使用CPU时use_cuda = False,使用GPU时use_cuda = True
use_cuda =  False
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
#place = fluid.CPUPlace()
#place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())
train_reader = paddle.batch(reader=train_reader('./data/train_list.txt'), batch_size=128)
test_reader = paddle.batch(reader=test_reader('./data/test_list.txt'), batch_size=128)
feeder = fluid.DataFeeder(place=place, feed_list=[words, label])EPOCH_NUM=5
model_save_dir = './infer_model/'
# 开始训练for pass_id in range(EPOCH_NUM):# 进行训练for batch_id, data in enumerate(train_reader()):train_cost, train_acc = exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost, acc])all_train_iter = all_train_iter + 100all_train_iters.append(all_train_iter)all_train_costs.append(train_cost[0])all_train_accs.append(train_acc[0])if batch_id % 100 == 0:print('Train Pass:%d, Batch:%d, Cost:%0.5f, Acc:%0.5f' % (pass_id, batch_id, train_cost[0], train_acc[0]))# 进行测试test_costs = []test_accs = []for batch_id, data in enumerate(test_reader()):test_cost, test_acc = exe.run(program=test_program,feed=feeder.feed(data),fetch_list=[avg_cost, acc])test_costs.append(test_cost[0])test_accs.append(test_acc[0])# 计算平均预测损失在和准确率test_cost = (sum(test_costs) / len(test_costs))test_acc = (sum(test_accs) / len(test_accs))print('Test:%d, Cost:%0.5f, ACC:%0.5f' % (pass_id, test_cost, test_acc))if not os.path.exists(model_save_dir):os.makedirs(model_save_dir)
fluid.io.save_inference_model(model_save_dir,feeded_var_names=[words.name],target_vars=[model],executor=exe)
print('训练模型保存完成!')
draw_train_process("training", all_train_iters, all_train_costs, all_train_accs, "trainning cost", "trainning acc")

说明:本次网络仿照TextCNN样式设计,相关参数可自行调试选出最优数值,预测模块已被删除,训练集的选择是经处理的训练集

训练集地址:中文新闻文本标题分类 - 飞桨AI Studio (baidu.com)

三、结果及分析 

5轮训练:

图2-1

图2-2

图2-3

图2-4

图2-5

图2-6

图2-7

分析:从数值变化上来看,从0到0.9所花的训练较少,趋向很快,由于数据集为THUCNews(740000多条数据)新闻标题,作为输入数据的它并没有图片大,所以CNN网络处理的速度一般较快,cpu运行所用时间约1.5-2.5个小时,改用GPU的话速度应该会更快。测试的数值呈线性,并没有发现随着训练的增加而出现数值下降倾向。

从图像(图2-7)上看,一目了然,随着训练量的增加,准确率上升、误差减少,趋向稳定后,准确率在0.9之间波动,而误差(损失值)0.1-0.4之间波动。

四、总结

处理NLP任务首先需要选择合适的网络模型,比如TextCNN、TextRNN、LSTM、GRU、BiLSTM、RCNN、EntNet等等。当然,有些NLP任务也可以用机器学习方法去解决,至于哪种任务用哪种方法,需要根据实际情况去选择。解决一个NLP的任务可能有多种方案,但是哪一个方案更合适需要我们不断地去分析尝试。比如,二次文本分类,可以尝试着去组合多种网络,以求达到最优效果。确定NLP任务后,首先需要对数据进行分析,任务具体是干什么需要什么功能,并且要深入地分析理解数据,知道数据的含义,这样可以帮助制定解决方案,同时也有利于进行数据预处理。数据要采取什么样的处理方式,需要对数据进行深入地分析后才能知道。确定好处理方式后,预处理数据。这一步和前面的数据分析关系很强,很多预处理操作都是基于对数据的分析而来,一般对文本预处理包含分词、去除停用词、训练词向量、文本序列化等等,当然,对于有的任务还包含同义词替换、训练词权重等等。再接着就是搭建模型,具体使用什么模型得根据具体任务来定。最后就是优化模型,常用的操作有调参、更改网络结构、针对评价指标优化等等。

参考:文本分类算法总结 - 知乎 (zhihu.com)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“无法登陆到你的账户”的问题解决方案

电脑打开后&#xff0c;winR打开命令窗口 输入&#xff1a;netplwiz 点击添加 ​​​​​​​点击添加方框内 点击本地账户 输入你要创建的账号那些&#xff1a; 我当时已经创建好了&#xff0c;就是user. 然后需要将该用户设置为管理员权限即可。 重回回到&#xff0c;此时你…

聚观早报 | 美国又一家银行要暴雷;腾讯T13技术黄希彤被曝遭裁员

今日要闻&#xff1a;暴跌 62%&#xff01;美国又一家银行要暴雷&#xff1b;三星上半年量产第三代 4nm 工艺&#xff1b;腾讯T13技术大佬黄希彤被曝遭裁员&#xff1b;华为 P60 系列将于 3 月 23 日发布&#xff1b;苹果公司CEO库克减薪40% 暴跌 62%&#xff01;美国又一家银…

蓝筹股连环爆雷!这些蓝筹股哪些最容易爆雷?(最全名单)

幸福的股民总是相似的&#xff0c;不幸的股民去而各有各的不幸。天雷滚滚的2019年报季尚不去不远&#xff0c;不少股民们尚未从那场暗雷中疗伤正骨&#xff0c;2020年中报的雷声又开始拉响。 7月14日&#xff0c;有着“药中茅台”之称的东阿阿胶半年度业绩公布&#xff0c;作为…

我问自己代言,甄嬛篇

你只看到本宫的寿康宫 却没看到本宫的凌云峰 你有你的气度 本宫有本宫的本事 你嘲笑本宫菀菀类卿 本宫可怜你留得住人留不住心 你可以轻视本宫的存在 本宫会让你见识糙米薏仁汤的口感 回宫 注定是一段孤独的旅程 路上少不了三姑六婆 但 那又怎样&#xff1f;即使是滑胎 也要滑的…

淘宝618每日一猜6月6日答案-甄嬛在横店哪里参加的选秀?

淘宝6月6日每日一猜答案是什么&#xff1f;&#xff0c;接下来也会给大家来介绍一下6月6日淘宝大赢家每日一猜的答案。 淘宝每日一猜6月6日答案分享 活动问题&#xff1a;甄嬛在横店哪里参加的选秀 活动答案&#xff1a;【交泰殿】 还有打开手机淘宝&#xff0c;搜索“能省就…

吴忠军 - 《甄嬛传》宜修到死都不知道,这个和甄嬛无关的人帮了甄嬛一个大忙...

《甄嬛传》在甄嬛把华妃扳倒后&#xff0c;皇后便甩开手开始对付甄嬛了&#xff0c;比起华妃和甄嬛的眼里皇后是最好对付的&#xff0c;因为皇后手中掌握扳倒甄嬛的法宝&#xff0c;这便是皇后的亲姐姐纯元&#xff0c;皇后设计甄嬛穿错纯元故衣后&#xff0c;不仅是皇上大发雷…

专利战争:IT界的甄嬛传

分享到 本文来自腾讯大讲堂(DJT.QQ.COM)&#xff0c;转载请注明出处。      近期热播电视剧“甄嬛传”完美收官&#xff0c;剧中女猪脚甄嬛的经历堪称一部女人的奋斗史诗&#xff0c;一方面要讨皇上的欢心&#xff0c;一方面又要跟华妃、皇后等后宫各方势力做斗争&…

熹贵妃竟是这种隐藏属性,从MBTI来看甄嬛“三姐妹”的爱恨情仇?

就在不久前的5月17日&#xff0c;农历四月十七&#xff0c;是熹贵妃的农历生日&#xff0c;这一天为了给嬛嬛庆生&#xff0c;朋友圈微博等各大平台&#xff0c;可热闹了起来&#xff0c;这盛况堪比那年果郡王为嬛嬛庆生&#xff5e; 如今&#xff0c;距《甄嬛传》首播已经有1…

《后宫•甄嬛传》火爆背后的秘密

“I pity the empress. Poor empress.” “我很同情皇后&#xff0c;她很可怜。” “Do you think Zhen Huan really loves the emperor?” “你认为甄嬛真的爱皇帝吗&#xff1f;” From campuses to offices, from shopping malls to the streets, talk about Legend of Zhe…

李东学计算机在哪学的,被人遗忘的果郡王,从《甄嬛传》出来的李东学如今只能奋进的旋律...

作者/ 卡茜 编辑/ 冯寅杰 (本文原载于《创业人》杂志 原标题《李东学&#xff1a;《甄嬛传》让我沉迷于演戏》) 183公分的海拔跟“高”贴合无误&#xff0c;俊朗轮廓与“帅”亲密无间&#xff0c;招牌式如阳笑容把“谦和”、“绅士”逐字融入。他自己却说真正的“高富帅”应该是…

《甄嬛传》被日本网友热赞

近期《甄嬛传》开始在日本电视台播出&#xff0c;日本网友说&#xff1a;“孙俪美得让人惊叹&#xff0c;但又是脚踏实地的美&#xff0c;不像如今演艺圈的美女&#xff0c;都带着点小太妹的坏坏的美一样&#xff0c;我喜欢她这种稳重大气的美。 转载于:https://www.cnblogs.co…

《甄嬛传》影评(整理)

这部戏似乎将人物的性格变化以及人物之间的互动把握得很好&#xff0c;让人觉得这部戏里每个人物都栩栩如生&#xff0c;似乎就是生活中之人。我比较讨厌看一部戏中&#xff0c;很明显地将人物分为正面和反面角色。这部戏中&#xff0c;自然也会有正面和反面角色&#xff0c;但…

推荐电视剧 后宫甄嬛传 2012

后宫甄嬛传 百科名片 《后宫甄嬛传》海报 电视剧《后宫甄嬛传》改编自流潋紫所著的同名小说。由郑晓龙导演&#xff0c;孙俪、陈建斌、蔡少芬等人主演&#xff0c;由北京电视艺术中心制作。该剧是一部宫廷情感大戏&#xff0c;更注重描写"后宫女人"的真实情感&am…

《甄嬛传》解读--后宫女人的心酸血泪史之腹黑学

最近看了一部电视剧&#xff0c;叫做《甄嬛传》&#xff0c;虽然它的主体讲述的是雍正皇帝后宫的故事&#xff0c;但是故事里面的人物性格各个鲜明&#xff0c;在他们的身上总是能够或多或少的看到一丝丝自己的影子&#xff0c;当然我不是说要大家去争男人争宠什么的。 这部76集…

甄嬛传趣玩系统数据可视化分析

文章目录 前言一、角色情况基本概览二、1723-1730年大事件统计三、主要角色事件统计分析四、发生事件频繁角色统计总结 前言 本文在完成SQL Server和vb.net结合创建的甄嬛传趣玩数据管理系统为基础的前提下&#xff0c;继续采用vs 2019中商业智能模块中的Reporting Services进…

chatgpt赋能python:用Python轻松给手机用户发送短信——优秀的工具在手,无限可能!

用Python轻松给手机用户发送短信——优秀的工具在手&#xff0c;无限可能&#xff01; 作为一个有10年Python编程经验的工程师&#xff0c;我想分享一下如何用Python给手机用户发送短信。Python是目前非常流行的编程语言之一&#xff0c;它可以轻松地完成很多任务。而给用户发…

汪子熙趣味成语接龙游戏的设计初衷

我国的汉语博大精深&#xff0c;其中数以万计的四字成语更是汉语中一颗颗璀璨的明珠&#xff0c;凝聚着中华民族几千年文明的精华。从小接触这些成语&#xff0c;对于小学生积累语汇&#xff0c;提高文学素养&#xff0c;和学习文言文方面有着很大的帮助。 本作品以益智游戏的…

计算机英语翻译的典故,中国成语故事英文版带翻译【六篇】

【导语】中国的成语博大精深&#xff0c;这也可以从侧面中看出我国古代的文化真的是源远流长&#xff0c;影响潜移默化。下面是无忧考网分享的中国成语故事英文版带翻译【六篇】。欢迎阅读参考&#xff01; 【篇一】中国成语故事英文版带翻译 熟能生巧 Although Chen Yaozi was…

【电子学会】2021年09月图形化四级 -- 成语接龙

成语接龙 小猫从“一鸣惊人"开始岀题,以“人”字开头接下一个成语,如果输入的不是四字成语或者输入成语的第一个字不是上一个成语的最后一个字,游戏结束。 1. 准备工作 (1)保留舞台默认白色背景及小猫角色; (2)建立名为“词语接龙”的列表。 2. 功能实现 (1…

上海计算机一级考试选择题必背,上海基础口译大全:50句必背的成语翻译

1. 爱屋及乌 Love me, love my dog. 2. 百闻不如一见 One look is worth a thousand words.Seeing is believing. 3. 比上不足&#xff0c;比下有余 to fall short of the best, but be better than the worst 4. 笨鸟先飞 A slow sparrow should make an early start. 5. 不遗…