`scipy.optimize` 函数甚至在 `maxiter=0` 时也会挂起
`scipy.optimize` functions hang even with `maxiter=0`
我正在尝试使用简单的多 class 逻辑回归训练 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
。我还使用 reshape
将 initTheta
展平,希望 能有所帮助。
成本函数计算没有问题,在我的电脑上不到2秒:
print(costFunctionFlatTheta(flatInitTheta), costFunctionFlatTheta1(flatInitTheta1))
# 0.69314718056 0.69314718056
但是所有 fmin
函数都挂起,即使我设置了 maxiter=0
。
例如
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 行。
如何解决这个问题?
好的,我找到了停止 fmin_cg
挂起的方法。
基本上我只需要写一个函数来计算成本函数的梯度,并将它传递给fmin_cg
的fprime
参数。
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 帮助我找到了解决方案。
我正在尝试使用简单的多 class 逻辑回归训练 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
。我还使用 reshape
将 initTheta
展平,希望
成本函数计算没有问题,在我的电脑上不到2秒:
print(costFunctionFlatTheta(flatInitTheta), costFunctionFlatTheta1(flatInitTheta1))
# 0.69314718056 0.69314718056
但是所有 fmin
函数都挂起,即使我设置了 maxiter=0
。
例如
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 行。
如何解决这个问题?
好的,我找到了停止 fmin_cg
挂起的方法。
基本上我只需要写一个函数来计算成本函数的梯度,并将它传递给fmin_cg
的fprime
参数。
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 帮助我找到了解决方案。