神经网络的 Matlab 实现大大优于 Keras 变体

Matlab implementation of neural network is vastly superior to Keras variant

为了比较这两种变体,我尝试实现一个简单的示例:学习 sinc 函数。

Matlab 在这里非常简单,用

创建数据
x = 0 : 0.1 : 10;
y = sin(x) ./ x;

并使用 Neural Network Fitting 拟合工具进行训练。 Matlab 在仅仅 62 个时期后产生了 5.31e-10 的损失。

如您所见,肉眼完美契合。 现在我用keras实现了同样的网络:

model = Sequential()
model.add(Dense(10, input_shape=(1,)))
model.add(Activation('tanh'))
model.add(Dense(1))
model.add(Activation('linear'))

opti = Adam()

model.compile(optimizer=opti,
              loss='mean_squared_error')

并以类似的方式准备数据:

x = np.arange(0, 10.1, 0.1)

def sinc(x):
    if x == 0:
        return 1
    else:
        return (np.sin(x) / x)

y = [sinc(val) for val in x]

并与

一起训练
history = model.fit(x, y, epochs=100, validation_split=0.15)

100 个 epoch 后,损失大约为 0.02。

Keras的性能明显比Matlabs差很多

我唯一能想到的是,Levenberg-Marquardt 比 Adam 好得离谱,因为即使在 1000 个 epoch 之后,训练损失也没有太大改善。

我也试过提高 Adam 的学习率,但即便如此,损失也只是在 0.0003 左右停止下降

这是一个 link 到 Jupyter notebook,如果你想看一下我用于我的 Keras 实现的确切代码:

Jupyter Notebook

现在我的问题是,我是否以及如何改进我的 Keras 实现,而不会留下明显的限制(比如增加隐藏层的大小),这些限制是我挑战 Matlab 所施加的太多?

Now my question is if and how I can improve on my Keras implementation without leaving the obvious constraints (like increasing the hidden layer size) imposed by my challenge to beat Matlab too much?

为了改进您的 Keras 实现,我建议您先 试用一下默认情况下可用的其他优化器 ,因为其中一个可能非常适合您的情况,并且可能超过 Matlab 的实现.

如果这不起作用,您仍然可以创建满足您需要的自定义优化器class。在您的情况下,您可以尝试自己实施 Levenberg-Marquardt 优化器。为此,您应该扩展 Optimizers class 并覆盖 get_updatesget_config 方法,例如:

class myLM(Optimizer):
    def __init__(self, your=0., parameters=0., here=0., **kwargs):
       #Initialize your custom Optimizer
    def get_updates(self, loss, params):
       #Calculate and return the update according to LM implementation
       return self.updates
    def get_config(self):
       #override configuration method
       config = {'your': float(K.get_value(self.lr)),
              'parameters': float(K.get_value(self.beta_1)),
              'here': float(K.get_value(self.beta_2)),
               }
       base_config = super(myML, self).get_config() #other configs
       return dict(list(base_config.items()) + list(config.items()))

然后您可以实例化自定义优化器并在编译模型时将其传递给 optimizer

我建议您检查 Keras Optimizers 代码(在本例中为 Adam),这样您就可以知道每种方法的预期功能 return 并能够根据您的需要构建它们定制需求。