【问题标题】:`scipy.optimize` functions hang even with `maxiter=0`即使使用 `maxiter=0`,`scipy.optimize` 函数也会挂起
【发布时间】:2018-05-12 23:17:52
【问题描述】:

我正在尝试使用简单的多类逻辑回归来训练 MNIST 数据(我从 Kaggle 下载),但 scipy.optimize 函数挂起。

代码如下:

import csv
from math import exp
from numpy import *
from scipy.optimize import fmin, fmin_cg, fmin_powell, fmin_bfgs

# Prepare the data

def getIiter(ifname):
    """
    Get the iterator from a csv file with filename ifname
    """
    ifile = open(ifname, 'r')
    iiter = csv.reader(ifile)
    iiter.__next__()
    return iiter

def parseRow(s):
    y = [int(x) for x in s]
    lab = y[0]
    z = y[1:]
    return (lab, z)

def getAllRows(ifname):
    iiter = getIiter(ifname)
    x = []
    l = []
    for row in iiter:
        lab, z = parseRow(row)
        x.append(z)
        l.append(lab)
    return x, l

def cutData(x, y):
    """
    70% training
    30% testing
    """
    m = len(x)
    t = int(m * .7)
    return [(x[:t], y[:t]), (x[t:], y[t:])]

def num2IndMat(l):
    t = array(l)
    tt = [vectorize(int)((t == i)) for i in range(10)]
    return array(tt).T

def readData(ifname):
    x, l = getAllRows(ifname)
    t = [[1] + y for y in x]
    return array(t), num2IndMat(l)

#Calculate the cost function

def sigmoid(x):
    return 1 / (1 + exp(-x))

vSigmoid = vectorize(sigmoid)
vLog = vectorize(log)

def costFunction(theta, x, y):
    sigxt = vSigmoid(dot(x, theta))
    cm = (- y * vLog(sigxt) - (1 - y) * vLog(1 - sigxt)) / m / N
    return sum(cm)

def unflatten(flatTheta):
    return [flatTheta[i * N : (i + 1) * N] for i in range(n + 1)]

def costFunctionFlatTheta(flatTheta):
    return costFunction(unflatten(flatTheta), trainX, trainY)

def costFunctionFlatTheta1(flatTheta):
    return costFunction(flatTheta.reshape(785, 10), trainX, trainY)

x, y = readData('train.csv')
[(trainX, trainY), (testX, testY)] = cutData(x, y)

m = len(trainX)
n = len(trainX[0]) - 1
N = len(trainY[0])

initTheta = zeros(((n + 1), N))
flatInitTheta = ndarray.flatten(initTheta)
flatInitTheta1 = initTheta.reshape(1, -1)

在最后两行中,我们将initTheta 展平,因为fmin{,_cg,_bfgs,_powell} 函数似乎只将向量作为初始值参数x0。我还使用reshapeinitTheta 展平,希望this answer 能有所帮助。

在我的计算机上计算花费不到 2 秒的成本函数没有问题:

print(costFunctionFlatTheta(flatInitTheta), costFunctionFlatTheta1(flatInitTheta1))
# 0.69314718056 0.69314718056

但是即使我设置了maxiter=0,所有fmin 函数也会挂起。 例如

newFlatTheta = fmin(costFunctionFlatTheta, flatInitTheta, maxiter=0)

newFlatTheta1 = fmin(costFunctionFlatTheta1, flatInitTheta1, maxiter=0)

当我中断程序时,在我看来,这一切都挂在optimize.py 调用成本函数的行处,如下所示:

return function(*(wrapper_args + args))

例如,如果我使用 fmin_cg,这将是 optimize.py(版本 0.5)中的第 292 行。

我该如何解决这个问题?

【问题讨论】:

  • 永远不要假设输入数据与问题无关 :) 此外,您希望人们可以轻松地帮助您。如果您可以简单地复制和粘贴代码示例来重现问题并尝试新的解决方案,那么您更有可能得到有用的答案。
  • @kazemakase(我的回复无缘无故消失了,所以我再次输入...)感谢您的建议。我已经添加了一些数据解析代码,希望它现在可以重现 :)

标签: optimization scipy logistic-regression


【解决方案1】:

好的,我找到了阻止 fmin_cg 挂起的方法。

基本上我只需要写一个计算代价函数梯度的函数,并将它传递给fmin_cgfprime参数即可。

def gradient(theta, x, y):
    return dot(x.T, vSigmoid(dot(x, theta)) - y) / m / N

def gradientFlatTheta(flatTheta):
    return ndarray.flatten(gradient(flatTheta.reshape(785, 10), trainX, trainY))

然后

newFlatTheta = fmin_cg(costFunctionFlatTheta, flatInitTheta, fprime=gradientFlatTheta, maxiter=0)

在几秒钟内终止,将 maxiter 设置为更高的数字(比如 100)可以在合理的时间内训练模型。

The documentation of fmin_cg 表示如果没有给出fprime,则梯度将被数值计算,我怀疑这是导致挂起的原因。

感谢this notebook by zgo2016@Kaggle 帮助我找到了解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 2013-08-13
    • 2018-03-18
    • 1970-01-01
    • 2011-03-29
    • 2021-05-02
    相关资源
    最近更新 更多