这是我的输入数据:
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 的多类分类)
[[1 0 0]
[0 1 0]
[1 0 0]
...
[1 0 0]
[1 0 0]
[0 1 0]]
这是我一步一步想到的,如果我错了请纠正我:
正在转换我的输入文本
data['text']
到一袋索引(序列)vocabulary_size = 20000 tokenizer = Tokenizer(num_words = vocabulary_size) tokenizer.fit_on_texts(data['text']) sequences = tokenizer.texts_to_sequences(data['text']) data = pad_sequences(sequences, maxlen=50)
发生了什么是我的data['text'].shape
这是形状 (19579, )
正在转换为形状为 (19579, 50)
的索引数组,其中每个单词都被在 tokenizer.word_index.items()
中找到的索引替换
正在加载
glove 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),
因此,我们现在拥有的是每个 100 维单词的单词向量。
使用手套词向量创建嵌入矩阵
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
所以我们现在有一个 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_glove.add(Dropout(0.5))
,这是为了关闭一些概率为0.5的隐藏单元,避免模型过于复杂。但我不知道为什么我们需要 Conv1D(64, 5, activation='relu')
, MaxPooling1D(pool_size=4)
以及这如何进入我的 model_glove.add(LSTM(100))
单位..
最佳答案
理解卷积
的最简单方法是将其视为一种映射,它告诉神经网络哪些特征(在图像识别的情况下是像素,您将在其中使用 2D 卷积;或给定文本单词之前或之后的单词,您将在其中使用一维卷积)在附近。如果没有这个,网络就无法知道给定单词之前或之后的单词比距离更远的单词更相关。它通常还会导致信息以更密集的格式呈现,从而大大减少参数数量(在您的情况下从 200 万减少到 3 万)。我发现这个答案很好地解释了它如何工作的技术性:https://stackoverflow.com/a/52353721/141789
Max pooling
是一种对数据进行下采样的方法。它通常在卷积之后直接使用并实现两件事:
- 它再次减少了参数的数量。在您的情况下,它将代表四个值和一个值(四个值中的最大值)。它通过采用前四个值,然后采用大小为 4 的“步幅”并采用接下来的四个值等来实现这一点。换句话说,池之间不会重叠。 (这是 keras 默认情况下所做的,但您也可以将步幅设置为
2
例如) - 其次,因为它采用
max
值,理论上通过采用最大值而不是例如采用平均值来“增强”池之间的对比。
最大池不是“学习”的;这只是一个简单的算术计算。这就是参数数量为零的原因。 dropout
也是如此。
LSTM
需要形状为 (样本数、时间步数、特征数)
的三维输入。执行之前的卷积和最大池化步骤后,您已将初始嵌入的表示形式减少到 number of timesteps = 11
和 number of features = 64
。第一个值 number of samples = None
是您计划使用的 batch size
的占位符。通过使用 100 个单元
(也称为 隐藏状态
)初始化 LSTM,您正在参数化 LSTM“内存”的大小:本质上是其输入、输出的累积忘记时间之门。
关于python - 了解用于 NLP 文本分类的 LSTM 和 RNN 中的词嵌入、卷积层和最大池化层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53623432/