【发布时间】:2019-08-07 14:15:22
【问题描述】:
我正在使用简单的 RNN 在时间序列上预测 EWMA (exponential weighted moving average) formula。已经在here发帖了。
虽然模型使用 keras-tf(来自 tensorflow 导入 keras)完美地收敛,但完全相同的代码无法使用原生 keras(导入 keras)。
收敛模型代码(keras-tf):
from tensorflow import keras
import numpy as np
np.random.seed(1337) # for reproducibility
def run_avg(signal, alpha=0.2):
avg_signal = []
avg = np.mean(signal)
for i, sample in enumerate(signal):
if np.isnan(sample) or sample == 0:
sample = avg
avg = (1 - alpha) * avg + alpha * sample
avg_signal.append(avg)
return np.array(avg_signal)
def train():
x = np.random.rand(3000)
y = run_avg(x)
x = np.reshape(x, (-1, 1, 1))
y = np.reshape(y, (-1, 1))
input_layer = keras.layers.Input(batch_shape=(1, 1, 1), dtype='float32')
rnn_layer = keras.layers.SimpleRNN(1, stateful=True, activation=None, name='rnn_layer_1')(input_layer)
model = keras.Model(inputs=input_layer, outputs=rnn_layer)
model.compile(optimizer=keras.optimizers.SGD(lr=0.1), loss='mse')
model.summary()
print(model.get_layer('rnn_layer_1').get_weights())
model.fit(x=x, y=y, batch_size=1, epochs=10, shuffle=False)
print(model.get_layer('rnn_layer_1').get_weights())
train()
非收敛模型代码:
from keras import Model
from keras.layers import SimpleRNN, Input
from keras.optimizers import SGD
import numpy as np
np.random.seed(1337) # for reproducibility
def run_avg(signal, alpha=0.2):
avg_signal = []
avg = np.mean(signal)
for i, sample in enumerate(signal):
if np.isnan(sample) or sample == 0:
sample = avg
avg = (1 - alpha) * avg + alpha * sample
avg_signal.append(avg)
return np.array(avg_signal)
def train():
x = np.random.rand(3000)
y = run_avg(x)
x = np.reshape(x, (-1, 1, 1))
y = np.reshape(y, (-1, 1))
input_layer = Input(batch_shape=(1, 1, 1), dtype='float32')
rnn_layer = SimpleRNN(1, stateful=True, activation=None, name='rnn_layer_1')(input_layer)
model = Model(inputs=input_layer, outputs=rnn_layer)
model.compile(optimizer=SGD(lr=0.1), loss='mse')
model.summary()
print(model.get_layer('rnn_layer_1').get_weights())
model.fit(x=x, y=y, batch_size=1, epochs=10, shuffle=False)
print(model.get_layer('rnn_layer_1').get_weights())
train()
虽然在 tf-keras 收敛模型中,损失最小化并且权重非常接近 EWMA 公式,但在非收敛模型中,损失会爆炸到 nan。据我所知,唯一的区别是我导入类的方式。
我对两种实现都使用了相同的随机种子。我正在使用 keras 2.2.4 和 tensorflow 版本 1.13.1(包括版本 2.2.4-tf 中的 keras)的 Windows pc、Anaconda 环境。
对此有何见解?
【问题讨论】:
-
也许你可以通过打印来检查类是否相同。如果它们不同,请尝试找出两者的不同之处。这将是一种快速而肮脏的调查方式。
-
这些类并不完全相同,因为一个是 tensorflow 中 keras API 的内部实现(据我所知由 google 维护),它是专门为 tensorflow 实现的。第二个“原生”keras 是一个与框架无关的 API,也可以与 theano 一起使用。它们都实现了相同的对象和 API,并假设给出相同的结果,但显然情况并非如此......
-
有趣的是,只有当
SimpleRNN的参数stateful是True时才会发生这种情况。
标签: python tensorflow keras deep-learning