python transformer_文本分类实战(八)—— Transformer模型

本文档介绍了如何使用Transformer模型进行文本分类。首先,概述了整个系列的内容,接着详细介绍了数据集、Transformer模型结构和参数配置。然后,展示了如何生成训练数据,包括数据预处理、词汇映射和数据集划分。最后,讨论了Transformer模型的构建、训练过程以及评估指标。
摘要由CSDN通过智能技术生成

1 大纲概述

文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类。总共有以下系列:

jupyter notebook代码均在textClassifier仓库中,python代码在NLP-Project中的text_classfier中。

2 数据集

数据集为IMDB 电影影评,总共有三个数据文件,在/data/rawData目录下,包括unlabeledTrainData.tsv,labeledTrainData.tsv,testData.tsv。在进行文本分类时需要有标签的数据(labeledTrainData),数据预处理如文本分类实战(一)—— word2vec预训练词向量中一样,预处理后的文件为/data/preprocess/labeledTrain.csv。

3 Transformer 模型结构

Transformer模型来自于论文Attention Is All You Need,关于Transformer具体的介绍见这篇。Transformer模型具体结构如下图:

Transformer结构有两种:Encoder和Decoder,在文本分类中只使用到了Encoder,Decoder是生成式模型,主要用于自然语言生成的。

4 参数配置

importosimportcsvimporttimeimportdatetimeimportrandomimportjsonimportwarningsfrom collections importCounterfrom math importsqrtimportgensimimportpandas as pdimportnumpy as npimporttensorflow as tffrom sklearn.metrics importroc_auc_score, accuracy_score, precision_score, recall_score

warnings.filterwarnings("ignore")

#配置参数

classTrainingConfig(object):

epoches= 10evaluateEvery= 100checkpointEvery= 100learningRate= 0.001

classModelConfig(object):

embeddingSize= 200filters= 128 #内层一维卷积核的数量,外层卷积核的数量应该等于embeddingSize,因为要确保每个layer后的输出维度和输入维度是一致的。

numHeads = 8 #Attention 的头数

numBlocks = 1 #设置transformer block的数量

epsilon = 1e-8 #LayerNorm 层中的最小除数

keepProp = 0.9 #multi head attention 中的dropout

dropoutKeepProb= 0.5 #全连接层的dropout

l2RegLambda = 0.0

classConfig(object):

sequenceLength= 200 #取了所有序列长度的均值

batchSize = 128dataSource= "../data/preProcess/labeledTrain.csv"stopWordSource= "../data/english"numClasses= 1 #二分类设置为1,多分类设置为类别的数目

rate= 0.8 #训练集的比例

training=TrainingConfig()

model=ModelConfig()#实例化配置参数对象

config = Config()

5 生成训练数据

1)将数据加载进来,将句子分割成词表示,并去除低频词和停用词。

2)将词映射成索引表示,构建词汇-索引映射表,并保存成json的数据格式,之后做inference时可以用到。(注意,有的词可能不在word2vec的预训练词向量中,这种词直接用UNK表示)

3)从预训练的词向量模型中读取出词向量,作为初始化值输入到模型中。

4)将数据集分割成训练集和测试集

#数据预处理的类,生成训练集和测试集

classDataset(object):def __init__(self, config):

self.config=config

self._dataSource=config.dataSource

self._stopWordSource=config.stopWordSource

self._sequenceLength= config.sequenceLength #每条输入的序列处理为定长

self._embeddingSize =config.model.embeddingSize

self._batchSize=config.batchSize

self._rate=config.rate

self._stopWordDict={}

self.trainReviews=[]

self.trainLabels=[]

self.evalReviews=[]

self.evalLabels=[]

self.wordEmbedding=None

self.labelList=[]def_readData(self, filePath):"""从csv文件中读取数据集"""df=pd.read_csv(filePath)if self.config.numClasses == 1:

labels= df["sentiment"].tolist()elif self.config.numClasses > 1:

labels= df["rate"].tolist()

review= df["review"].tolist()

reviews= [line.strip().split() for line inreview]returnreviews, labelsdef_labelToIndex(self, labels, label2idx):"""将标签转换成索引表示"""labelIds= [label2idx[label] for label inlabels]returnlabelIdsdef_wordToIndex(self, reviews, word2idx):"""将词转换成索引"""reviewIds= [[word2idx.get(item, word2idx["UNK"]) for item in review] for review inreviews]returnreviewIdsdef_genTrainEvalData(self, x, y, word2idx, rate):"""生成训练集和验证集"""reviews=[]for review inx:if len(review) >=self._sequenceLength:

reviews.append(review[:self._sequenceLength])else:

reviews.append(review+ [word2idx["PAD"]] * (self._sequenceLength -len(review)))

trainIndex= int(len(x) *rate)

trainReviews= np.asarray(reviews[:trainIndex], dtype="int64")

trainLabels= np.array(y[:trainIndex], dtype="float32")

evalReviews= np.asarray(reviews[trainIndex:], dtype="int64")

evalLabels= np.array(y[trainIndex:], dtype="float32")returntrainReviews, trainLabels, evalReviews, evalLabelsdef_genVocabulary(self, reviews, labels):"""生成词向量和词汇-索引映射字典,可以用全数据集"""allWords= [word for review in reviews for word inreview]#去掉停用词

subWords = [word for word in allWords if word not inself.stopWordDict]

wordCount= Counter(subWords) #统计词频

sortWordCount = sorted(wordCount.items(), key=lambda x: x[1], reverse=True)#去除低频词

words = [item[0] for item in sortWordCount if item[1] >= 5]

vocab, wordEmbedding=self._getWordEmbedding(words)

self.wordEmbedding=wordEmbedding

word2idx=dict(zip(vocab, list(range(len(vocab)))))

uniqueLabel=list(set(labels))

label2idx=dict(zip(uniqueLabel, list(range(len(uniqueLabel)))))

self.labelList=list(range(len(uniqueLabel)))#将词汇-索引映射表保存为json数据,之后做inference时直接加载来处理数据

with open("../data/wordJson/word2idx.json", "w", encoding="utf-8") as f:

json.dump(word2idx, f)

with open("../data/wordJson/label2idx.json", "w", encoding="utf-8") as f:

json.dump(label2idx, f)returnword2idx, label2idxdef_getWordEmbedding(self, words):"""按照我们的数据集中的单词取出预训练好的word2vec中的词向量"""wordVec= gensim.models.KeyedVectors.load_word2vec_format("../word2vec/word2Vec.bin", binary=True)

vocab=[]

wordEmbedding=[]#添加 "pad" 和 "UNK",

vocab.append("PAD")

vocab.append("UNK")

wordEmbedding.append(np.zeros(self

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值