【问题标题】:TensorFlow LSTM length outputTensorFlow LSTM 长度输出
【发布时间】:2021-06-12 18:42:18
【问题描述】:

所以基本上我有一个 LSTM 模型,它接收一堆数字(这些数字实际上是我转换成数字的音符。如果你想知道的话,我的目标是创建计算机生成的音乐)。我遇到的问题是我不知道如何做出预测。我希望计算机输出的是一个数字列表(或字符串或任何可能的数字),这些数字遵循它在训练过程中提出的任何规则。在以前的项目中,我只知道如何输出 1 个预测数字,给计算机一些数据进行预测,但我想要一个全新的列表,而不给计算机一个起始值。最好计算机一次可以生成一个以上的数字。

这是我目前拥有的代码。它现在不起作用:

n_steps = 1
X, y = split_sequence(data, n_steps)
X = X.reshape((X.shape[0], X.shape[1], 1))
X = tf.cast(X, dtype='float32')

model = Sequential()
model.add(LSTM(256, activation='relu', return_sequences=True))
#model.add(Dropout(0.2)) # I am not sure what this is, but it doesn't break my code
model.add(LSTM(128, activation='relu', return_sequences=True))
#model.add(Dropout(0.2))
model.add(LSTM(128))
#model.add(Dropout(0.2))
model.add(Dense(1, activation='linear'))
model.compile(optimizer='adam', loss='mse', metrics=['mae'])

model.fit(X, y, epochs=10, batch_size=2, verbose=2)


prediction = model.predict(X) # I want to output a list of numbers
print(prediction)

现在,我的预测正在输出一个非常长的列表,其中包含相同的值,我认为这是一个预测。它看起来像这样:

[[62.449333]
 [62.449333]
 [62.449333]
 ...
 [62.449333]
 [62.449333]
 [62.449333]]

我想要一个不是预测的列表,而更像是全新数字列表的 GAN 输出。另外,我不确定为什么这个预测会输出很长的列表。

数据看起来像这样,为了简洁起见,它被缩短了:

[64, 76, 64, 75, 64, 76, 64, 75, 64, 76, 64, 71, 64, 74, 64, 72, 69, 64, 45, 64, 52]

当 n_steps = 1 时,x 列车如下所示:

[[64], [76], [64], [75], [64], [76], [64], [75], [64], [76], [64], [71], [64], [74]]

y 看起来像这样,每个都是相应 x 列车的预期输出:

[76, 64, 75, 64, 76, 64, 75, 64, 76, 64, 71, 64, 74, 64]

任何帮助将不胜感激!

【问题讨论】:

  • LSTM 的输入形状为 [batch, timesteps, feature],而您提供的是单个数字。
  • Softmax激活用于多类分类,我相信这是一个回归任务。
  • 是的,我将其更改为线性并在那里解决了一些问题。我在 LSTM 中输入一个数字是什么意思?
  • 表示需要将输入改为:model.add(LSTM((256,), activation='relu', return_sequences=True))
  • 我们可以查看您的训练数据吗?你的 x 输入和 y 输出标签是什么样的?

标签: python tensorflow machine-learning lstm


【解决方案1】:

我认为您的模型结构很好,但数据需要一些工作。您的 LSTM 仅设置为输出 1 个值,您可以在最后一个 LSTM 层没有return_sequences=True 时看到该值。您的 y 标签有多个值这一事实一定会混淆模型。

我认为你应该保持这种行为,但编辑你的输入/输出数据如下:

如果您的数据中有一个序列是:

[64, 76, 64, 75, 64, 76, 64, 75, 64, 76, 64, 71, 64, 74, 64, 72, 69, 64, 45, 64, 52]

那么你的训练示例和标签应该是:

x[0] = [64]
y[1] = [76]

x[1] = [64, 76]
y[1] = [64]

x[2] = [64, 76, 64]
y[2] = [75]

序列的每一步都可以是一个单独的训练样本,但每个 y 标签只能是一个输出。

您的线性输出可以工作,但我认为这可能更适合作为 softmax 输出的分类问题。最后的密集层应该有你的模型可以输出的可能音符的数量。您还必须用 0 值填充这些序列,以便所有 x 输入值的长度相同,因此 x 值实际上是:

x[0] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64]
x[1] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 75]

等等。数组的长度是您的最大序列长度。

在进行预测时,请使用循环。您可以给模型一个单值 inut 序列,然后将预测的音符附加到输入序列并再次将其反馈给模型:

seed_note = [64] # initial note to give the model
next_notes = 10 # how many notes to predict

for _ in range(next_notes):
    token_list = pad_sequences(seed_note, maxlen=max_sequence_len, padding='pre') # pad sequence with 0s
    predicted = np.argmax(model.predict(token_list), axis=-1) # get best prediction for next note
    seed_note += [predicted]
    
print(seed_text)

【讨论】:

  • 这是非常有用的信息,但我认为可能存在一个小误解。我的 y 标签是 1 个长列表,每个标签都是集合中的一个整数,而不是一堆长列表。此外,在不更改 x 和 y 数据但将输出激活更改为“softmax”的情况下,我只会得到一堆 1 作为输出。这应该发生还是我必须在softmax输出工作之前更改我的数据?谢谢!
  • 另外,如何导入'max_sequence_len'?
  • 我假设您给定的数据[64, 76, 64, 75, 64, 76, 64, 75, 64, 76, 64, 71, 64, 74, 64, 72, 69, 64, 45, 64, 52] 是您希望模型学习的歌曲/曲调的一个示例。如果您有多首歌曲,则必须按照我的描述将它们中的每首处理成 x 输入和 y 输出,其中一首歌曲可以提供多个训练示例。
  • 当你有分类数据时使用 softmax 激活。结果输出是一个单热向量,每个类别的概率都是正确的预测,这些概率被归一化为总和 1。只有 1 个输出的 softmax 将不起作用。如果你有 100 个可能的音符,你的密集层应该有 100 个神经元。
  • max_sequence_len 是您定义的。你可以从你的数据中得到它。您提供的示例数据长度为 21 个整数,因此您可以设置 max_sequence_len = 21,除非您的数据集中有更长的歌曲。只需将其设置为最长歌曲的长度即可。
【解决方案2】:

我的理解是 1)你想输出一个不同预测的列表(即你担心每个预测都取相同的值)。 2) 你想要一个浮点数列表而不是一个包含浮点数的列表。

向后工作:

2,当使用神经网络和 model.predict() 进行预测时,它会在输入多个 x_test 样本时输出一个列表数组 - 这很容易通过使用 ndarray.flatten() 解决,因此在您的情况下:prediction = model.predict(X).flatten()

1,我首先会调查您是否正确地重塑了输入数据。 LSTM 模型将 3D 数据作为输入,因此需要一个 3D 数组,格式为(序列、时间步长、特征):

序列,是数据集中(或观察/样本)中序列的总数

时间步长,对应于序列的大小

特征,是一个时间步长的观察次数(/变量数)

因此,您只为每个时间步定义了一个特征。如果是这种情况,您正在喂它(x.shape[0] 个样本,x.shape[1] 序列中的时间步数,只有 1 个特征/变量) - 这是您的意图吗?获取有关正在使用的数据的更多信息会很有帮助,即特征数量和序列所需的窗口大小。

【讨论】:

  • 坦率地说,我真的不知道重塑中发生了什么,但我知道我需要向 LSTM 输入一个 3d 形状。我想我刚刚在一个随机的在线教程中发现了这个重塑设置。您是否推荐另一种将我的数据重塑为 3d 形状的方法?否则非常有帮助和解释性,+1 票!此外,flatten 只是将列表列表更改为 1 个具有相同值的列表。我想输出许多不同的值。
  • 我怀疑数据是如何被重塑的,即它是否正确地完成了你想要的输出——这可以通过更深入地了解你的 x_data 实际是什么来解决(所以这里有更多信息有帮助:))。当您说您想输出许多不同的值时 - 您是否对模型仅输出 1 个重复的相同值或您想要不同形状的输出感到困扰? (重要的是要记住,您的模型只会输出值/预测的列向量,即 y_train 或 y_test)。
  • 输出数字列表的意思是我希望我的模型输出不同数字的列表。例如,如果我给我的模型提供数字:1、2、3、4、5,我希望模型输出如下内容:2、3、4、5、6。类似于 GAN 模型,但用于文本跨度>
猜你喜欢
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 2016-10-14
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多