NLP学习笔记(三):模型训练之深度学习方案详解(关键词:深度学习,词向量,RNN,LSTM)

更新时间:2023-06-23 22:22:44 阅读: 评论:0

NLP学习笔记(三):模型训练之深度学习⽅案详解(关键词:深度学习,词向量,RNN,LSTM)
0. 前⾔
接上⼀节,我们在预处理完成后,使⽤简单的词袋模型(CountVectorizer, TfidfVectorizer)来创建了特征,并使⽤常⽤的机器学习算法随机森林(RandomForest)、逻辑回归(LogisticReggression)、朴素贝叶斯(NaiveBayes)进⾏训练,同时使⽤⽹格搜索(GridSearchCV)进⾏调参。这就是我们上次创建的⼀个思路简单的baline。
英语单词发音软件
这次我们在预处理的基础上使⽤深度学习的⽅法进⾏训练,关于NLP中常见的深度学习⽅案,在不同类型的问题中我们可能会使⽤到CNN,RNN等,⽹上常见的LSTM/GRU等模型,它们都是RNN的变体(本质上还是RNN)。关于RNN、LSTM的详细说明,可看。
我们可能经常在⽹上看到Word Embedding这个词,字⾯翻译是词嵌⼊,但是我们⼀般理解是词向量。
1. NLP深度学习模型使⽤与介绍
⽹上常⽤的是keras(TensorFlow as backend),它的接⼝使⽤⽐TensorFlow更加⽅便,想⽤Keras使⽤GPU跑代码的话,博主的情况是之前就预装了GPU版的TensorFlow,所以直接装keras后运⾏就是使⽤的GPU,关于其他⽅案没有了解过。没有GPU的同学⽤CPU也可以跑,只不过要将下⾯的CuDNNLSTM
广州化妆培训学校换为LSTM。其他算法也是同理。
from import Tokenizer
from keras.preprocessing.quence import pad_quences
from keras.layers import Embedding, Flatten, Den, Input, Dropout, BatchNormalization
英语专业就业
from keras.layers import CuDNNLSTM, Bidirectional, GlobalMaxPool1D
dels import Sequential, Model
from keras.optimizers import Adam
我们⾸先进⾏初始化设置:
vocab_size = 5000
max_len = 300
tokenizer = Tokenizer(num_words = vocab_size)
这⾥vocab_size和我们之前提到的max_features是同⼀个东西,都是字典⼤⼩,其实经过之前的结果,感觉这个值还可以设置的再⼤⼀点也没关系,只不过为了和前⾯进⾏⽐较,这⾥还是设置成5000。
max_len是为后⾯做铺垫先设置的⼀个值,接下来会介绍。
官⽅介绍:
Tokenizer是⼀个⽤于向量化⽂本,或将⽂本转换为序列(即单词在字典中的下标构成的列表,从1算起)的类。
有点抽象,我们接着看。
tokenizer.fit_on_texts(clean_train_reviews)
train_quences = s_to_quences(clean_train_reviews)
test_quences = s_to_quences(clean_test_reviews)
这⾥的⼜出现了fit,和之前的fit()本质上是相同的,为什么不在测试集上使⽤可以参考这篇博⽂
text_to_quences⽅法来了,刚刚不是感觉有点抽象么,我们来看看到底是什么情况。
clean_train_reviews
['stuff going moment mj started listening music watching odd documentary watched wiz watched moonwalker maybe want get certain insight guy thought reall train_quences
[[404, 70, 419, 506, 2456, 115, 54, 873, 516, 178, 178, 165, 78, 14, 662, 2457, 117, 92, 10, 499, 4074, 165, 22,
210, 581, 2333, 1194, 71, 4826, 71, 635, 2, 253, 70, 11, 302, 1663, 486, 1144, 3265, 411, 793, 3342, 17, 441,
600, 1500, 15, 4424, 1851, 998, 146, 342, 1442, 743, 2424, 4, 418, 70, 637, 69, 237, 94, 541, 120, 1, 323, 8, 47, 20, 323, 167, 10, 207, 633, 635, 2, 116, 291, 382, 121, 3315, 1501, 574, 734, 923, 822, 1239, 1408, 360, 221,
15, 576, 2274, 734, 27, 340, 16, 41, 1500, 388, 165, 3962, 115, 627, 499, 79, 4, 1430, 380, 2163, 114, 1919,
2503, 574, 17, 60, 100, 4875, 260, 1268, 15, 574, 493, 744, 637, 631, 3, 394, 164, 446, 114, 615, 3266, 1160,
684, 48, 1175, 224, 1, 16, 4, 3, 507, 62, 25, 16, 640, 133, 231, 95, 600, 3439, 1864, 1, 128, 342, 1442, 247, 3,
865, 16, 42, 1487, 997, 2333, 12, 549, 386, 717, 12, 41, 16, 158, 362, 4392, 3388, 41, 87, 225, 438, 207, 254,
117, 3, 316, 1356], ... ]
这样就可以很清楚的看出来,单词都被转化为了字典中对应的下标了,并且返回⼀个列表。
train_df_features = pad_quences(train_quences, maxlen = max_len)
test_df_features = pad_quences(test_quences, maxlen = max_len)
这⾥就⽤到了刚刚提到的max_len,这是因为我们假设每个评论有300个词左右(实际可以做个平均值测试,⼤概250),然后对序列化后
的数据,如果它们不够300个,就进⾏补零操作。如果超出的话,就进⾏截断。
这样我们原始数据的特征就构造完成了,我们来看⼀下
提交英语
train_df_features.shape
train_df_features
(25000, 300)
Out[33]:
array([[  0,    0,    0, ...,    3,  316, 1356],
[  0,    0,    0, ...,  623, 4628, 1251],
[  0,    0,    0, ...,  535,  700, 1175],
...,
[  0,    0,    0, ...,  10,  14,  207],
[  0,    0,    0, ...,  218, 1903,  16],
[  0,    0,    0, ..., 1108,  109,  350]])
接下来我们就开始创建模型了,在Keras中,有⽐较⽅便的创建模型的API,通常使⽤的⼤概有两种:
推销自己⼀、使⽤dels.Model()
dels import Model
能够⽐较⾃由的创建需要的模型,书写格式如下:
from keras.layers import Input, Den
a = Input(shape=(32,))
university of toronto
jindoub = Den(32)(a)
model = Model(inputs=a, outputs=b)
最后编译⼀下
ne, weighted_metrics=None, target_tensors=None)这⾥没有设定参数,读者可根据⾃⼰需要进⾏设置。
⼆、使⽤dels.Sequential()
在NLP中,这也是常⽤的⼀种建模⽅式,从它的名字就可看出适合于建⽴时序模型。
常⽤表达:
dels import Sequential
from keras.layers import Den, Activation
model = Sequential([
Den(32, input_shape=(784,)),
Activation('relu'),
Den(10),
Activation('softmax'),
])
或者使⽤add():
dels import Sequential
from keras.layers import Den, Activation
model = Sequential()
model.add(Den(32, input_dim=784))
model.add(Activation('relu'))
最后同样也是编译
# 针对多分类问题
loss='categorical_crosntropy',
metrics=['accuracy'])
# 针对⼆分类问题
crazy的意思
loss='binary_crosntropy',
metrics=['accuracy'])
# 针对均⽅差回归问题
loss='m')
好,题外话不多说了,我们开始创建我们的深度学习模型,我们就使⽤Model()来创建好了
barrister
from import Tokenizer
from keras.preprocessing.quence import pad_quences
from keras.layers import Embedding, Flatten, Den, Input, Dropout, BatchNormalization
from keras.layers import CuDNNLSTM, Bidirectional, GlobalMaxPool1D
dels import Sequential, Model
from keras.optimizers import Adam
inp = Input(shape = (max_len, ))
x = Embedding(input_dim = vocab_size, output_dim = embed_size, input_length = max_len)(inp)
x = Bidirectional(CuDNNLSTM(32, return_quences = True))(x)
x = GlobalMaxPool1D()(x)
x = Den(16, activation = 'relu')(x)
x = Dropout(0.05)(x)
x = Den(1, activation = "sigmoid")(x)
model = Model(inputs = inp, outputs = x)
⼀句⼀句来分析,⾸先是Input(),⾥⾯的shape指的是每次输⼊的序列长度,我们之前将每个评论进⾏规整成了max_len这么长,⽽我们每次输⼊⼀个评论进⼊模型,所以shape = (max_len, )
第⼆句Embedding()层,这⼀层就是词向量化层,其中input_dim必须是我们设置的字典的⼤⼩(也可以说是特征的数量),output_dim 是我们向量化后的词向量维度。关于词向量,⽹上有很多资料但是很乱,国内⽐较好的资料推荐来斯惟的博⼠论⽂基于神经⽹络的词和⽂档语义向量表⽰⽅法研究,国外的资料推荐XinRong的word2vec Parameter Learning Explained。input_length依然是我们输⼊的序列长度,所以还是刚刚的max_len。
第三句Bidirectional(CuDNNLSTM())⾸先CuDNNLSTM简单说来就是LSTM的GPU版本,如果没有GPU版本的话将其换为LSTM就可以了(记住import也要改)。加上Bidirectional就是双向LSTM,想详细了解可以查找论⽂,这⾥就不多解释了。32这个参数是units,指的是输出的output维度。return_quences是否将上⼀个输出返回,⼀般我们是选择True,毕竟RNN的特性需要体现嘛,信息“循环”利⽤。
第四句GlobalMaxPool1D()顾名思义就是最⼤池化层。
第五句Den()就是全连接层。
第六句Dropout()就是在输⼊任意drop掉那么多⽐例的数据,作⽤是预防过拟合。
肯定会有读者在想,为啥是这个顺序的建模,为啥⽤那些activation呢?在这⾥博主能⼒不⾜,只能这么解释,前⼈尝试过很多⽅案,这种⽅案应该算是效果⽐较好的。
最后记住编译⼀下 pile()。
好了,我们打印下看看参数的维度
print(model.summary())
Layer (type)                Output Shape              Param #
=================================================================
input_4 (InputLayer)        (None, 300)              0
_________________________________________________________________
embedding_3 (Embedding)      (None, 300, 200)          1000000
_________________________________________________________________
bidirectional_3 (Bidirection (None, 300, 64)          59904
_________________________________________________________________
global_max_pooling1d_2 (Glob (None, 64)                0
_________________________________________________________________
den_3 (Den)              (None, 16)                1040
郑州国际学校
_________________________________________________________________
dropout_2 (Dropout)          (None, 16)                0
_________________________________________________________________
den_4 (Den)              (None, 1)                17
=================================================================
Total params: 1,060,961
Trainable params: 1,060,961
Non-trainable params: 0
上⾯的None就是batch_size啦,是我们每次输⼊的训练数据的数量。
embedding那⾥的1000000是我们需要训练的词向量矩阵包含的参数个数,其维度为5000x200。别忘了5000是我们设置的字典的⼤⼩。
bidirectional那⾥的64,是因为我们设置的LSTM的输出维度为32,但是双向之后就需要乘以2了。
这⾥双向LSTM的参数个数怎么计算的呢,LSTM的参数个数由4 * [(x_dim + y_dim) * y_dim + y_dim]计算
可以上图中间那个celll⾥有四个⼩黄框,⾥⾯写的是激活函数。其实每个都相当于⼀个MLP,我们可以拆解开看。
进⼊第⼀个sigmoid前的h(t - 1)与Xt,这两个向量进⾏concatenate,就是直接相连(⽐如⼀个维度为(10, )的向量连上⼀个维度(20, )的向量,就得到⼀个维度(30, )的向量),Xt对应的维度为x_dim,⽽h(t - 1)对应的维度为y_dim,我们希望这个“MLP”输出的ft维度为
y_dim,所以中间的矩阵Wf维度即为(x_dim + y_dim) *y_dim,再算上bias后,即为(x_dim + y_dim) *y_dim + y_dim了,⽽我们⼀共有四个⼩黄框,所以将这个值乘以4就是参数的数量了。
这⾥x_dim为输⼊的向量维度,这⾥是200,y_dim为输出的向量维度,为32,最后双向再上⾯公式乘以2就得到了59904。但是⼀般我们不⽤算这么精确,只需要知道⼀个⼤概数量级就可以了,⽐如可以简化成4*x_dim*y_dim(未使⽤双向时)。
全连接层的参数个数,也就是相当于要知道矩阵维度,我们输⼊64,输出16,那肯定这个矩阵就是(
64,16)嘛,这样就1024个参数了,最后还有16个bios,加起来⼀共1040个。

本文发布于:2023-06-23 22:22:44,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/155328.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模型   参数   学习   维度   向量   深度   没有
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图