Python 理解用于NLP文本分类的LSTMs和RNNs中的单词嵌入、卷积层和最大池层
这是我的输入数据:Python 理解用于NLP文本分类的LSTMs和RNNs中的单词嵌入、卷积层和最大池层,python,tensorflow,nlp,lstm,word-embedding,Python,Tensorflow,Nlp,Lstm,Word Embedding,这是我的输入数据: data['text'].head() 0 process however afforded means ascertaining di... 1 never occurred fumbling might mere mistake 2 left hand gold snuff box which capered hill cu... 3 lovely spring looked windsor terrace sixteen f...
data['text'].head()
0 process however afforded means ascertaining di...
1 never occurred fumbling might mere mistake
2 left hand gold snuff box which capered hill cu...
3 lovely spring looked windsor terrace sixteen f...
4 finding nothing else even gold superintendent ...
Name: text, dtype: object
这是一个热编码标签(多类分类,其中类数=3)
以下是我认为一步一步发生的事情,如果我错了,请纠正我:
数据['text']
转换为一袋索引(序列)
数据['text']。shape
的shape(19579,)
被转换成shape(19579,50)
的索引数组,其中每个单词都被标记器中的索引所替换。word\u index.items()
手套100d
字向量
embeddings_index = dict()
f = open('/Users/abhishekbabuji/Downloads/glove.6B/glove.6B.100d.txt')
for line in f:
values = line.split()
word = values[0]
coefs = np.asarray(values[1:], dtype='float32')
embeddings_index[word] = coefs
f.close()
print(embedding_index)
{'the': array([-0.038194, -0.24487 , 0.72812 , -0.39961 , 0.083172, 0.043953,
-0.39141 , 0.3344 , -0.57545 , 0.087459, 0.28787 , -0.06731 ,
0.30906 , -0.26384 , -0.13231 , -0.20757 , 0.33395 , -0.33848 ,
-0.31743 , -0.48336 , 0.1464 , -0.37304 , 0.34577 , 0.052041,
0.44946 , -0.46971 , 0.02628 , -0.54155 , -0.15518 , -0.14107 ,
-0.039722, 0.28277 , 0.14393 , 0.23464 , -0.31021 , 0.086173,
0.20397 , 0.52624 , 0.17164 , -0.082378, -0.71787 , -0.41531 ,
0.20335 , -0.12763 , 0.41367 , 0.55187 , 0.57908 , -0.33477 ,
-0.36559 , -0.54857 , -0.062892, 0.26584 , 0.30205 , 0.99775 ,
-0.80481 , -3.0243 , 0.01254 , -0.36942 , 2.2167 , 0.72201 ,
-0.24978 , 0.92136 , 0.034514, 0.46745 , 1.1079 , -0.19358 ,
-0.074575, 0.23353 , -0.052062, -0.22044 , 0.057162, -0.15806 ,
-0.30798 , -0.41625 , 0.37972 , 0.15006 , -0.53212 , -0.2055 ,
-1.2526 , 0.071624, 0.70565 , 0.49744 , -0.42063 , 0.26148 ,
-1.538 , -0.30223 , -0.073438, -0.28312 , 0.37104 , -0.25217 ,
0.016215, -0.017099, -0.38984 , 0.87424 , -0.72569 , -0.51058 ,
-0.52028 , -0.1459 , 0.8278 , 0.27062 ], dtype=float32),
vocabulary_size = 20000
embedding_matrix = np.zeros((vocabulary_size, 100))
for word, index in tokenizer.word_index.items():
if index > vocabulary_size - 1:
break
else:
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
embedding_matrix[index] = embedding_vector
向量,对于20000个单词中的每一个,都有100维。
以下是架构:
model_glove = Sequential()
model_glove.add(Embedding(vocabulary_size, 100, input_length=50, weights=[embedding_matrix], trainable=False))
model_glove.add(Dropout(0.5))
model_glove.add(Conv1D(64, 5, activation='relu'))
model_glove.add(MaxPooling1D(pool_size=4))
model_glove.add(LSTM(100))
model_glove.add(Dense(3, activation='softmax'))
model_glove.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model_glove.summary())
我明白了
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_7 (Embedding) (None, 50, 100) 2000000
_________________________________________________________________
dropout_7 (Dropout) (None, 50, 100) 0
_________________________________________________________________
conv1d_7 (Conv1D) (None, 46, 64) 32064
_________________________________________________________________
max_pooling1d_7 (MaxPooling1 (None, 11, 64) 0
_________________________________________________________________
lstm_7 (LSTM) (None, 100) 66000
_________________________________________________________________
dense_7 (Dense) (None, 3) 303
=================================================================
Total params: 2,098,367
Trainable params: 98,367
Non-trainable params: 2,000,000
_________________________________________________________________
上述架构的输入将是培训数据
array([[ 0, 0, 0, ..., 4867, 22, 340],
[ 0, 0, 0, ..., 12, 327, 2301],
[ 0, 0, 0, ..., 255, 388, 2640],
...,
[ 0, 0, 0, ..., 17, 15609, 15242],
[ 0, 0, 0, ..., 9517, 9266, 442],
[ 0, 0, 0, ..., 3399, 379, 5927]], dtype=int32)
形状的(19579,50)
和标签作为一个热编码
我的问题是,当我的(19579,50)
通过以下每一行时,我的理解到底发生了什么:
model_glove = Sequential()
model_glove.add(Embedding(vocabulary_size, 100, input_length=50, weights=[embedding_matrix], trainable=False))
model_glove.add(Dropout(0.5))
model_glove.add(Conv1D(64, 5, activation='relu'))
model_glove.add(MaxPooling1D(pool_size=4))
我理解为什么我们需要model_globe.add(Dropout(0.5))
,这是为了关闭一些概率为0.5的隐藏单元,以避免模型过于复杂。但是我不知道为什么我们需要Conv1D(64,5,activation='relu')
,maxpoolg1d(pool_size=4)
,以及这是如何进入我的模型手套的。add(LSTM(100))
单元。理解卷积的最简单方法是将其视为告诉神经网络哪些特征的映射(图像识别中的像素,使用2D卷积;或文本中给定单词之前或之后的单词,使用1D卷积)如果没有这一点,网络就无法知道给定单词之前或之后的单词比远得多的单词更相关。这通常还会导致信息以更密集的格式呈现,从而大大减少参数的数量(在你的案例中,从200万降到3万)。我发现这个答案解释了它如何运作的技术性:
Max pooling
是一种对数据进行降采样的方法。它通常在卷积之后直接使用,实现两个目的:
它再次减少了参数的数量。在您的情况下,它将用一个值(四个值中的最大值)表示四个值。它通过取前四个值,然后取大小为四的“步幅”,然后取下四个值等来实现这一点。换句话说,池之间不会有重叠。(这是keras默认的功能,但您也可以将步幅设置为2
)
其次,因为它采用了max
值,因此理论上,通过采用最大值而不是平均值来“增强”池之间的对比度
最大池不是“学习”的;它只是一个简单的算术计算。这就是为什么参数的数量为零。对于退出
,也是如此
LSTM
需要一个形状的三维输入(样本数、时间步数、特征数)
。执行了前面的卷积和最大池步骤后,您已将初始嵌入的表示形式减少为时间步数=11
和功能数=64
。第一个值样本数=无
是计划使用的批量大小的占位符使用100个单位的LSTM
(也称为隐藏状态
)可以参数化LSTM的“内存”大小:本质上是其输入、输出和遗忘门随时间的累积
array([[ 0, 0, 0, ..., 4867, 22, 340],
[ 0, 0, 0, ..., 12, 327, 2301],
[ 0, 0, 0, ..., 255, 388, 2640],
...,
[ 0, 0, 0, ..., 17, 15609, 15242],
[ 0, 0, 0, ..., 9517, 9266, 442],
[ 0, 0, 0, ..., 3399, 379, 5927]], dtype=int32)
model_glove = Sequential()
model_glove.add(Embedding(vocabulary_size, 100, input_length=50, weights=[embedding_matrix], trainable=False))
model_glove.add(Dropout(0.5))
model_glove.add(Conv1D(64, 5, activation='relu'))
model_glove.add(MaxPooling1D(pool_size=4))