1 前言

接着上次的tf2+cnn+中文文本分类优化系列(1),本次进行优化:使用多个卷积核进行特征抽取。之前是使用filter_size=2进行2-gram特征的识别,本次使用filter_size=[3,4,5]三个不同的卷积核抽取三个不同的gram特征,这样就能通过卷积获取更多的词特征。其实,本次主要看cnn在做中文文本分类中single kernel与multi kernel的对比。

2 前期处理

数据集仍是复旦大学开源的文本数据集,label种类为20。所用的包如下:

import tensorflow as tf

from tensorflow.keras import layers

from tensorflow.keras.callbacks import ReduceLROnPlateau

import numpy as np

import collections

import matplotlib.pyplot as plt

import codecs

import re

import os

一些参数设定如下:

class TextConfig():

embedding_size=100 #词的维度

vocab_size=6000 #词表的大小

seq_length=300 #文本长度

num_classes=20 #类别数量

num_filters=128 #卷积核数量

filter_sizes=[3,4,5] #多个卷积核大小

keep_prob=0.5 #dropout

lr= 1e-3 #学习率

is_training=True

num_epochs=10 #epochs

batch_size=64 #batch_size

train_dir=r'E:\data\train.txt' #train data

test_dir=r'E:\data\test.txt' #test data

vocab_dir=r'E:\data\vocab.txt' #vocabulary

接着构建词表,并将文本token化:

def read_file(file_dir):

"""

读入数据文件,将每条数据的文本和label存入各自列表中

"""

re_han = re.compile(u"([\u4E00-\u9FD5a-zA-Z]+)") #去掉标点符号和数字类型的字符

with codecs.open(file_dir,'r',encoding='utf-8') as f:

for line in f:

label,text=line.split('\t')

content=[]

for w in text:

if re_han.match(w):

content.append(w)

yield content,label

def build_vocab(file_dirs,vocab_dir,vocab_size=6000):

"""

利用训练集和测试集的数据生成字级的词表

"""

all_data = []

for filename in file_dirs:

for content,_ in read_file(filename):

all_data.extend(content)

counter=collections.Counter(all_data)

count_pairs=counter.most_common(vocab_size-1)

words,_=list(zip(*count_pairs))

words=['']+list(words)

with codecs.open(vocab_dir,'w',encoding='utf-8') as f:

f.write('\n'.join(words)+'\n')

def convert_examples_to_tokens(input_dir,vocab_dir,seq_length):

"""

将文本按字级别进行token化,按后截断的方式进行padding;

"""

words=codecs.open(vocab_dir,'r',encoding='utf-8').read().strip().split('\n')

word_to_id=dict(zip(words,range(len(words))))

categories = ['Art', 'Literature', 'Education', 'Philosophy', 'History', 'Space', 'Energy', 'Electronics',

'Communication', 'Computer','Mine','Transport','Enviornment','Agriculture','Economy',

'Law','Medical','Military','Politics','Sports']

cat_to_id=dict(zip(categories,range(len(categories))))

input_ids,label_ids=[],[]

for content,label in read_file(input_dir):

input_ids.append([word_to_id[x] if x in word_to_id else 0 for x in content ])

label_ids.append(cat_to_id[label])

input_ids =tf.keras.preprocessing.sequence.pad_sequences(input_ids, value=0,padding='post', maxlen=seq_length)

label_ids=np.array(label_ids)

return (input_ids,label_ids)

该部分跟之前的基本是一样的,只是参数中filter_sizes变成一个列表

3 模型构建

不同单个卷积核,在使用多个卷积核时,要进行遍历,然后将每次卷积+池化的结构进行拼接。

def cnn_model(cfg):

"""

定义一个实现多个卷积核的layer,然后进行Flatten,dropout,softmax层;

"""

def convolution():

inn = layers.Input(shape=(cfg.seq_length, cfg.embedding_size, 1))

cnns = []

for size in cfg.filter_sizes:

conv = layers.Conv2D(filters=cfg.num_filters, kernel_size=(size, cfg.embedding_size),

strides=1, padding='valid', activation='relu',

kernel_regularizer=tf.keras.regularizers.l2(0.001))(inn)

pool = layers.MaxPool2D(pool_size=(cfg.seq_length - size + 1, 1), padding='valid')(conv)

pool = layers.BatchNormalization()(pool)

cnns.append(pool)

outt = layers.concatenate(cnns)

model = tf.keras.Model(inputs=inn, outputs=outt)

return model

model = tf.keras.Sequential([

layers.Embedding(input_dim=cfg.vocab_size, output_dim=cfg.embedding_size,

input_length=cfg.seq_length),

layers.Reshape((cfg.seq_length, cfg.embedding_size, 1)),

convolution(),

layers.Flatten(),

layers.Dropout(cfg.keep_prob),

layers.Dense(cfg.num_classes, activation='softmax')

])

model.compile(optimizer=tf.keras.optimizers.Adam(cfg.lr),

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])

print(model.summary())

return model

其中 function convolution就是定义的一个多个卷积核形成的layer,在卷积中使用了2维卷积,所以在embedding后增加了一个维度:layers.Reshape((cfg.seq_length, cfg.embedding_size, 1))

4 训练

在训练中,本次我们调用了ReduceLROnPlateau定义一个学习率衰减策略:在val_loss超过2个epoch没减少,则学习率按lr=lr*0.6进行下调。

if __name__ == "__main__":

cfg=TextConfig()

model=cnn_model(cfg)

if not os.path.exists(cfg.vocab_dir):

build_vocab(cfg.train_dir, cfg.vocab_dir, cfg.vocab_size)

#载入训练数据,并进行样本打乱;

train_x,train_y=convert_examples_to_tokens(cfg.train_dir,cfg.vocab_dir,cfg.seq_length)

indices=np.random.permutation(np.arange(len(train_x)))

train_x=train_x[indices]

train_y=train_y[indices]

#定义学习率衰减策略

reduce_lr = ReduceLROnPlateau(monitor='val_loss',factor=0.6, patience=2, min_lr=0.0001)

history=model.fit(train_x,train_y,epochs=cfg.num_epochs,batch_size=cfg.batch_size,

verbose=1,validation_split=0.1, callbacks=[reduce_lr])

5 结果对比

在测试集上损失和准确率

模型

test_loss

test_accuracy

single kernel(之前)

0.573

0.833

multi kernel(本次)

0.505

0.888

可以看出,本次多个卷积核有5.5%效果的提升,还是很明显的,也证实了多个卷积核能抽取更多相关的N-gram特征,进而影响识别效果。

各个label的f1-score 指标对比

75f04adca51b

从上图可以看出,在多个卷积核识别下,“Literature”label从原先的0提升到0.21,其他指标也得到一定的提升。

训练过程对比

75f04adca51b

image.png

从训练的损失和验证集的准确率来看,multi kernel都是优于single kernel的。

6 结语

通过本次的实验可以得出,在使用cnn做text classification任务,多个卷积核已是标配。至于用多少个卷积核,一般是取3个,具体也看数据场景,但更多的话会增大模型复杂度而对效果提升不大。在本次实验下,仍有优化空间,下次从词的角度进行优化。

更多文章可关注笔者公众号:自然语言处理算法与实践

linux tf2 中文,tf2+cnn+中文文本分类优化系列(2)相关推荐

  1. 文本分类(下) | 卷积神经网络(CNN)在文本分类上的应用

    正文共3758张图,4张图,预计阅读时间18分钟. 1.简介 原先写过两篇文章,分别介绍了传统机器学习方法在文本分类上的应用以及CNN原理,然后本篇文章结合两篇论文展开,主要讲述下CNN在文本分类上的 ...

  2. 使用CNN做文本分类——将图像2维卷积换成1维

    使用CNN做文本分类from __future__ importdivision, print_function, absolute_importimporttensorflow as tfimpor ...

  3. CNN在文本分类的应用(内有代码实现) 论文Convolutional Neural Networks for Sentence Classification

    一.CNN文本分类简介 文本分类是NLP领域的一个重要子任务,文本分类的目标是自动的将文本打上已经定义好的标签,常见的文本分类任务有: 用户评论的情感识别 垃圾邮件过滤 用户查询意图识别 新闻分类 由 ...

  4. 论文复现:用 CNN 进行文本分类

    前一篇文章中我们学习了 CNN 的基础结构,并且知道了它是计算机视觉领域的基础模型,其实 CNN 不仅仅可以用于计算机视觉,还可以用于处理自然语言处理问题,今天就来看看如何用 CNN 处理文本分类任务 ...

  5. 【论文复现】使用CNN进行文本分类

    今天要写的是关于NLP领域的一个关键问题:文本分类. 相对应的论文是:Convolutional Neural Networks for Sentence Classification 参考的博客为: ...

  6. 深度学习原理与框架-CNN在文本分类的应用 1.tf.nn.embedding_lookup(根据索引数据从数据中取出数据) 2.saver.restore(加载sess参数)...

    1. tf.nn.embedding_lookup(W, X) W的维度为[len(vocabulary_list), 128], X的维度为[?, 8],组合后的维度为[?, 8, 128] 代码说 ...

  7. 详解CNN实现中文文本分类过程

    摘要:本文主要讲解CNN实现中文文本分类的过程,并与贝叶斯.决策树.逻辑回归.随机森林.KNN.SVM等分类算法进行对比. 本文分享自华为云社区<[Python人工智能] 二十一.Word2Ve ...

  8. 基于CNN中文文本分类实战

    一.前言 之前写过一篇基于循环神经网络(RNN)的情感分类文章,这次我们换种思路,采用卷积神经网络(CNN)来进行文本分类任务.倘若对CNN如何在文本上进行卷积的可以移步博主的快速入门CNN在NLP中 ...

  9. 【NLP】TensorFlow实现CNN用于中文文本分类

    代码基于 dennybritz/cnn-text-classification-tf 及 clayandgithub/zh_cnn_text_classify 参考文章 了解用于NLP的卷积神经网络( ...

最新文章

  1. 导入之后再执行一个方法_种花生再撒点儿石灰,掌握这两个方法之后,提高产量基本没问题!...
  2. 有一个工程师男(女)朋友是什么样的体验?
  3. Ajax — 第五天
  4. SQL的主键和外键约束 小记
  5. 学习机软件测试,IBM P630 POWER4 AIX小型机适合软件测试及学习机
  6. avalon源码分析(转)
  7. 31muduo_net库源码分析(七)
  8. 学习笔记:Oracle的trace文件可见性
  9. Python学习-9.Python函数定义
  10. Spring Security 工作原理概览
  11. 关于小凡模拟器设置完后找不到所要配置文件的问题
  12. Windows安装curl及基本命令
  13. 高通平台抓取ramdump并用qcap解析
  14. python数字大小写转换代码_把金额小写转换成大写的Python代码
  15. java cmyk和rgb的转换_CMYK和RGB怎么转换
  16. B.系数(mod意义下的系数转化+lucas)
  17. SpringCloudAlibaba(一)SpringCloudAlibaba简介
  18. [转]倾斜摄影单体化实现方案
  19. 眼动数据分析基础_02
  20. 微人事(vhr)开源项目部署

热门文章

  1. 有源雷达与无源雷达、主动雷达与被动雷达
  2. Matlab:创建字符串数组
  3. C语言基础 判断周几
  4. HTML层叠样式表(CSS)
  5. csgo服务器搭建文件,CSGO服务器架设.doc
  6. 苹果数据泄漏:内鬼频出,这是库克的错吗?
  7. 超级实用——用word与谷歌翻译将英文PDF文档翻译成中文,免费无限制之美
  8. 带宽与码元的关系_带宽、速率和码元宽度问题
  9. 犹太人的经典成功智慧
  10. 对于tcp的一点点解读,不止是三次握手、四次挥手