【问题标题】:Keras BFGS training using Scipy minimizeKeras BFGS 训练使用 Scipy 最小化
【发布时间】:2016-07-19 06:09:25
【问题描述】:

我想训练一个使用 BFGS 在 Keras 中实现的前馈神经网络。为了看看是否可以做到,我使用scipy.optimize.minimize 实现了一个感知器,代码如下。

from __future__ import print_function
import numpy as np
from scipy.optimize import minimize
from keras.models import Sequential
from keras.layers.core import Dense

# Dummy training examples
X = np.array([[-1,2,-3,-1],[3,2,-1,-4]]).astype('float')
Y = np.array([[2],[-1]]).astype('float')

model = Sequential()
model.add(Dense(1, activation='sigmoid', input_dim=4))

def loss(W):
    weightsList = [np.zeros((4,1)), np.zeros(1)]
    for i in range(4):
        weightsList[0][i,0] = W[i]
    weightsList[1][0] = W[4]
    model.set_weights(weightsList)
    preds = model.predict(X)
    mse = np.sum(np.square(np.subtract(preds,Y)))/len(X[:,0])
    return mse

# Dummy first guess
V = [1.0, 2.0, 3.0, 4.0, 1.0]
res = minimize(loss, x0=V, method = 'BFGS', options={'disp':True})
print(res.x)

但是,这个输出表明损失函数没有优化:

Using Theano backend.
Using gpu device 0: GeForce GTX 960M (CNMeM is disabled, cuDNN not available)
Optimization terminated successfully.
         Current function value: 2.499770
         Iterations: 0
         Function evaluations: 7
         Gradient evaluations: 1
[ 1.  2.  3.  4.  1.]

任何想法为什么这不起作用?是不是因为我没有将梯度输入到minimize,导致无法计算这种情况下的数值逼近?

【问题讨论】:

    标签: python scipy neural-network keras


    【解决方案1】:

    是不是因为我没有输入梯度进行最小化,导致这种情况下无法计算数值逼近?

    这是因为你不输出梯度,所以 scipy 通过数值微分来近似它们。也就是说,它在 X 处评估函数,然后在 X + epsilon 处评估函数,以逼近局部梯度。

    但是 epsilon 足够小,以至于在转换为 theano 的 32 位时,更改完全丢失了。最初的猜测实际上并不是最小值,scipy 只是这么认为,因为它认为目标函数的值没有变化。您只需要像这样增加 epsilon:

    V = [1.0, 2.0, 3.0, 4.0, 1.0]
    print('Starting loss = {}'.format(loss(V)))
    # set the eps option to increase the epsilon used in numerical diff
    res = minimize(loss, x0=V, method = 'BFGS', options={'eps':1e-6,'disp':True})
    print('Ending loss = {}'.format(loss(res.x)))
    

    这给出了:

    Using Theano backend.
    Starting loss = 2.49976992001
    Optimization terminated successfully.
             Current function value: 1.002703
             Iterations: 19
             Function evaluations: 511
             Gradient evaluations: 73
    Ending loss = 1.00270344184
    

    【讨论】:

      【解决方案2】:

      输出表明您的起始值是最小值。我不确定 keras 是什么/做什么,但如果我是你,我会首先绘制你试图在每个维度上最小化的函数。我的猜测是,这样做问题会变得很明显。

      【讨论】:

        【解决方案3】:

        要将 Scipy 优化器与 keras 一起使用,您需要实现一个循环,以便在每次迭代中,使用 Keras 根据损失函数计算梯度,然后使用优化器更新神经网络权重。我写了一个小型库来执行此操作https://github.com/pedro-r-marques/keras-opt

        它的工作方式是在给定梯度的情况下覆盖 Keras 用于计算权重更新的图表。不是通过后端图执行权重更新,而是在每个小批量结束时累积梯度。在训练周期结束时,权重被呈现给优化器,优化器提出新的全局权重更新。

        【讨论】:

          猜你喜欢
          • 2017-07-14
          • 1970-01-01
          • 2020-08-25
          • 2012-09-04
          • 2017-07-07
          • 2020-05-21
          • 2018-01-30
          • 2015-02-18
          相关资源
          最近更新 更多