【发布时间】:2019-06-14 18:49:10
【问题描述】:
我是 Keras 和编写神经网络模型的初学者,实际上我正在尝试编写用于文本生成目的的 LSTM,但没有成功。我做错了什么?
我读到了这个问题:here 和其他文章,但有一些我无法得到的东西,对不起,如果我看起来很愚蠢。
目标
我的目的是生成固定长度的英文文章(1500 现在)。
假设我有一个 20k 记录数据集,包含不同长度的序列(基本上是文章),我为所有文章 (MAX_SEQUENCE_LENGTH=1500) 设置了一个固定长度并将它们标记化,得到一个矩阵 (X,我的训练数据) 看起来像:
[[ 0 0 0 ... 88 664 206]
[ 0 0 0 ... 1 93 140]
[ 0 0 0 ... 3 173 2283]
...
[ 50 2761 4 ... 167 148 156]
[ 0 0 0 ... 10 77 206]
[ 0 0 0 ... 167 148 156]]
形状为20000x1500
我的 LSTM 的输出应该是一个 1 x MAX_SEQUENCE_LENGTH 标记数组。
我的模型是这样的:
def generator_model(sequence_input, embedded_sequences, output_shape):
layer = LSTM(16,return_sequences = True)(embedded_sequences)
layer = LSTM(32,return_sequences = True)(layer)
layer = Flatten()(layer)
output = Dense(output_shape, activation='softmax')(layer)
generator = Model(sequence_input, output)
return generator
与:sequence_input = Input(batch_shape=(1, 1,1500), dtype='int32')embedded_sequences = embedding_layer(sequence_input)output_shape = MAX_SEQUENCE_LENGTH
LSTM 应该在 20k x MAX_SEQUENCE_LENGTH 形状 (X) 的训练集上使用 model.fit() 进行训练。
当我调用model.predict(seed) 时,得到一个具有1 x MAX_SEQUENCE_LENGTH 形状的令牌数组作为输出,而seed 是一个随机噪声数组。
编译、拟合和预测
以下部分的cmets:
. generator.compile 有效,模型在帖子的edit 部分给出。
. generator.fit 编译,epochs=1 参数用于测试目的,将是 BATCH_NUM
.现在我对我给generator.fit 的y 有一些疑问,现在我给出一个0 的矩阵作为目标输出,如果我用与X.shape[0] 不同的形状生成它,它会抛出错误,这意味着它需要为X 中的每条记录添加一个标签。但是如果我给他一个0 的矩阵作为target 的model.fit,它不会只预测0 的数组吗?
.尽管我使用noise_generator() 或noise_integer_generator(),但给出的错误总是相同的,我相信这是因为它不喜欢我给出的y_shape 参数
embedding_layer = load_embeddings(word_index)
sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,))
embedded_sequences = embedding_layer(sequence_input)
generator = generator_model(sequence_input, embedded_sequences, X.shape[1])
print(generator.summary())
generator.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
Xnoise = generate_integer_noise(MAX_SEQUENCE_LENGTH)
y_shape = np.zeros((X.shape[0],), dtype=int)
generator.fit(X, y_shape, epochs=1)
acc = generator.predict(Xnoise, verbose=1)
但实际上我收到以下错误
ValueError: Error when checking input: expected input_1 to have shape (1500,) but got array with shape (1,)
当我打电话时:
Xnoise = generate_noise(samples_number=MAX_SEQUENCE_LENGTH)
generator.predict(Xnoise, verbose=1)
我给出的噪音是一个1 x 1500 数组,但它似乎期待一个(1500,) 矩阵,所以我的输出的形状设置一定有某种错误。
我的模型是否适合我的目的?还是我写了一些我看不到的非常愚蠢的东西?
感谢您给我的帮助,我很感激!
编辑
更新日志:
v1.
###
- Changed model structure, now return_sequences = True and using shape instead of batch_shape
###
- Changed
sequence_input = Input(batch_shape=(1,1,1500), dtype='int32')
to
sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,))
###
- Changed the error the model is giving
v2.
###
- Changed generate_noise() code
###
- Added generate_integer_noise() code
###
- Added full sequence with the model compile, fit and predict
###
- Added model.fit summary under the model summary, in the tail of the post
generate_noise()代码:
def generate_noise(samples_number, mean=0.5, stdev=0.1):
noise = np.random.normal(mean, stdev, (samples_number, MAX_SEQUENCE_LENGTH))
print(noise.shape)
return noise
哪个打印:(1500,)
generate_integer_noise()代码:
def generate_integer_noise(samples_number):
noise = []
for _ in range(0, samples_number):
noise.append(np.random.randint(1, MAX_NB_WORDS))
Xnoise = np.asarray(noise)
return Xnoise
我的函数load_embeddings()如下:
def load_embeddings(word_index, embeddingsfile='Embeddings/glove.6B.%id.txt' %EMBEDDING_DIM):
embeddings_index = {}
f = open(embeddingsfile, 'r', encoding='utf8')
for line in f:
values = line.split(' ') #split the line by spaces
word = values[0] #each line starts with the word
coefs = np.asarray(values[1:], dtype='float32') #the rest of the line is the vector
embeddings_index[word] = coefs #put into embedding dictionary
f.close()
print('Found %s word vectors.' % len(embeddings_index))
embedding_matrix = np.zeros((len(word_index) + 1, EMBEDDING_DIM))
for word, i in word_index.items():
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all-zeros.
embedding_matrix[i] = embedding_vector
embedding_layer = Embedding(len(word_index) + 1,
EMBEDDING_DIM,
weights=[embedding_matrix],
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
return embedding_layer
模型总结:
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 1500) 0
_________________________________________________________________
embedding_1 (Embedding) (None, 1500, 300) 9751200
_________________________________________________________________
lstm_1 (LSTM) (None, 1500, 16) 20288
_________________________________________________________________
lstm_2 (LSTM) (None, 1500, 32) 6272
_________________________________________________________________
flatten_1 (Flatten) (None, 48000) 0
_________________________________________________________________
dense_1 (Dense) (None, 1500) 72001500
=================================================================
Total params: 81,779,260
Trainable params: 72,028,060
Non-trainable params: 9,751,200
_________________________________________________________________
model.fit() 总结(使用 999 大小的数据集进行测试,而不是 20k 大小):
999/999 [==============================] - 62s 62ms/step - loss: 0.5491 - categorical_accuracy: 0.9680
【问题讨论】:
-
现在
generate_noise或sequence_input = Input(batch_shape=(1, 1,1500), dtype='int32')batch_shape中的某处似乎有错误,应将其更改为(1, 1500)。你能提供generate_noise函数和Xnoise.shape的代码吗?我猜Xnoise除了第一个维度之外的所有维度都应该等于batch_shape[1:]。 -
ofc,使用请求的代码编辑了原始帖子!
-
好的,有一些不清楚的地方:1)你如何适合你的模型? 2)有
return_sequences或stateful=True吗?我猜是前者。那么您不需要指定batch_shape,但可以使用shape。另外,目标的所需形状是什么?(?, 1500),我说的对吗? -
另外,你打算如何强制
embedding_layer处理浮点值(高斯噪声),而不是整数?也许你应该对整数进行采样。 -
我重写了一个答案,我还建议您再编辑一次答案,并在使用之前将所有定义准确一次。 - 更新日志是个好主意!
标签: python keras neural-network lstm