python - 神经网络 : estimating sine wave frequency

标签 python tensorflow neural-network keras lstm

为了学习 Keras LSTM 和 RNN,我想创建一个简单的问题来解决:给定一个正弦波,我们可以预测它的频率吗?

我不希望一个简单的神经网络能够预测频率,因为时间的概念在这里很重要。然而,即使使用 LSTM,我也无法学习频率;我能够学习一个平凡的零作为估计频率(即使对于火车样本)。

这是创建训练集的代码。

import numpy as np
import matplotlib.pyplot as plt

def create_sine(frequency):
    return np.sin(frequency*np.linspace(0, 2*np.pi, 2000))

train_x = np.array([create_sine(x) for x in range(1, 300)])
train_y = list(range(1, 300))

现在,这是一个用于此示例的简单神经网络。

from keras.models import Model
from keras.layers import Dense, Input, LSTM

input_series = Input(shape=(2000,),name='Input')
dense_1 = Dense(100)(input_series)
pred = Dense(1, activation='relu')(dense_1)
model = Model(input_series, pred)
model.compile('adam','mean_absolute_error')
model.fit(train_x[:100], train_y[:100], epochs=100)

正如预期的那样,这个神经网络没有学到任何有用的东西。接下来,我尝试了一个简单的 LSTM 示例。

input_series = Input(shape=(2000,1),name='Input')
lstm = LSTM(100)(input_series)
pred = Dense(1, activation='relu')(lstm)
model = Model(input_series, pred)
model.compile('adam','mean_absolute_error')
model.fit(train_x[:100].reshape(100, 2000, 1), train_y[:100], epochs=100)

但是,这个基于 LSTM 的模型也没有学到任何有用的东西。

最佳答案

为什么不学习?

您认为训练 RNN 是一个简单的问题,但实际上您的网络设置并不容易:

  • 如前所述,缺少重要样本。你把那么多数据丢进去(300 * 2000 点),但实际目标(频率)只被网络看到一次。即使网络确实学到了一些东西,它也很有可能会过度拟合。

  • 数据不一致。请记住,RNN 擅长捕捉系列数据中的相似模式。例如,在 NLP 中,语料库中的所有句子都受相同的语言规则约束,更多的句子有助于 RNN 更好地理解这些规则,即,更多的数据有助于。

    在您的情况下,具有不同频率的系列不太相似:将正弦与 frequency=1frequency=100 进行比较。数据的这种多样性使学习变得更难,而不是更容易。这并不意味着 RNN 无法学习频率,它只是意味着您不应该对像您这样的微不足道的 RNN 很难学习感到惊讶。

  • 数据规模。将频率从 1 更改为 300,将 xy 的比例更改两个数量级,这对任何神经网络都可能存在问题。

解决方案

由于您的目标很有教育意义,我通过将目标频率限制为 10 简单地解决了第二项和第三项,因此缩放和分布多样性不是什么大问题(欢迎您在这里尝试不同的值:您应该看到将这个参数增加到 50 会使任务复杂得多)。

第一项的解决方法是为 RNN 提供每个频率的 10 个示例,而不是一个。我还添加了一个隐藏层以增加网络灵 active ,以及​​一个简单的正则化器(Dropout 层)。

完整代码:

import numpy as np
from keras.models import Model
from keras.layers import Input, Dense, Dropout, LSTM

max_freq = 10
time_steps = 100

def create_sine(frequency, offset):
  return np.sin(frequency * np.linspace(offset, 2 * np.pi + offset, time_steps))

train_y = list(range(1, max_freq)) * 10
train_x = np.array([create_sine(freq, np.random.uniform(0,1)) for freq in train_y])
train_y = np.array(train_y)

input_series = Input(shape=(time_steps, 1), name='Input')
lstm = LSTM(units=100)(input_series)
hidden = Dense(units=100, activation='relu')(lstm)
dropout = Dropout(rate=0.1)(hidden)
output = Dense(units=1, activation='relu')(dropout)

model = Model(input_series, output)
model.compile('adam', 'mean_squared_error')
model.fit(train_x.reshape(-1, time_steps, 1), train_y, epochs=200)

# Trying the network on the same data
test_x = train_x.reshape(-1, time_steps, 1)
test_y = train_y
predicted = model.predict(test_x).reshape([-1])
print()
print((predicted - train_y)[:12])
print(np.mean(np.abs(predicted - train_y)))

输出:

ma​​x_freq=10

[-0.05612183 -0.01982236 -0.03744316 -0.02568841 -0.11959982 -0.0770483
  0.04643679  0.12057972 -0.00625324 -0.00724655 -0.16919005 -0.04512954]
0.0503574344847

ma​​x_freq=20(其他都一样)

[ 0.51365542  0.09269333 -0.009691    0.0619092   0.09852839  0.04378462
  0.01430321 -0.01953268  0.00722599  0.02558327 -0.04520988 -0.0614748 ]
0.146024380232

ma​​x_freq=30(其他都一样)

[-0.28205156 -0.28922796 -0.00569081 -0.21314907  0.1068716   0.23497915
  0.23975039  0.25955486  0.26333141  0.24235058  0.08320332 -0.03686047]
0.406703719805

请注意,结果是随机的,实际上增加 max_freq 会增加 divergence 的变化。但即使它收敛了,尽管有更多的数据,性能也没有提高,反而变得更糟,而且速度非常快。

关于python - 神经网络 : estimating sine wave frequency,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47932589/

相关文章:

python - ClientForm.AmbiguityError : more than one control matching name

Python For 循环(迭代变量名 = 列表名)

python - 在行 [NumPy 或 Tensorflow] 的索引值之前将行中的值设置为零

python - 可重用的 Tensorflow 卷积网络

python - python中如何实现Leaky Relu的导数?

python - 有没有办法在 Azure Functions 中延迟 QueueMessage?

python - 使用 ctypes 和 SSE/AVX 有时会出现段错误

python - 根据bool值不断更新tf.cond

python - 无法使用pip或anaconda安装tensorflow

python - 在keras中创建一个神经网络来乘以两个输入整数