这是我的输入数据:
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)
正在发生的是,形状为(19579, )
的data['text'].shape
被转换为形状为(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
所以我们现在对20000个单词中的每个单词都有100个维度的vector
。
这是架构:
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))
单元的。。
理解convolution
最简单的方法是将其视为一个映射,告诉神经网络哪些特征(在图像识别的情况下,像素,在那里你将使用2D卷积;或者在文本的给定单词之前或之后的单词,在这里你将使用1D卷积(在附近。如果没有这一点,网络就无法知道某个单词之前或之后的单词比更远的单词更相关。它通常还导致信息以更密集的格式呈现,从而大大减少了参数的数量(在您的情况下,从200万减少到3万(。我发现这个答案解释了它如何很好地工作的技术性:https://stackoverflow.com/a/52353721/141789
Max pooling
是一种对数据进行下采样的方法。它通常直接在卷积之后使用,并实现两件事:
- 它再次减少了参数的数量。在您的情况下,它将用一个值(四个值中的最大值(表示四个值。它通过取前四个值,然后取四个大小的"步长",再取下四个值等来实现这一点。换句话说,池之间不会有重叠。(默认情况下keras就是这样做的,但也可以将步幅设置为
2
( - 其次,由于它采用了
max
值,因此在理论上,通过采用最大值而不是平均值来"锐化"池之间的对比度
未"学习"最大池化;这只是一个简单的算术运算。这就是为什么参数的数量为零的原因。CCD_ 18也是如此。
CCD_ 19期望形状为CCD_ 20的三维输入。在执行了前面的卷积和最大池化步骤后,您已经将初始嵌入的表示形式简化为number of timesteps = 11
和number of features = 64
。第一个值number of samples = None
是您计划使用的batch size
的占位符。通过用100 units
(也称为hidden states
(初始化LSTM,您可以参数化LSTM的"内存"大小:本质上是其输入、输出和遗忘门随时间的累积。