2017-11-29 8 views
0

単純なマルチクラスロジスティック回帰でMNISTデータ(Kaggleからダウンロード)をトレーニングしようとしていますが、scipy.optimize関数がハングします。 fmin{,_cg,_bfgs,_powell}機能は初期値のみの引数x0としてベクトルを取るように見えるので、我々はinitThetaを平らに最後の2行で`scipy.optimize`関数は` maxiter = 0`でもハングします

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) 

は、ここでは、コードです。私はまたreshapeを使用してinitThetaを平らにして、this answerを助けることができます。

は、自分のコンピュータ上で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行になります。

この問題を解決するにはどうすればよいですか?

+0

入力データが問題とは無関係であるとは決して考えないでください。さらに、人々があなたを手助けしやすくする必要があります。問題を再現するコード例を単純にコピー&ペーストして新しいソリューションを試すことができれば、有用な答えを得られる可能性は非常に高いです。 – kazemakase

+0

@kazemakase(私の返信は明白な理由で消えてしまったので、もう一度入力しています...)おかげさまで、ありがとうございました。私はデータ解析コードのビットを追加しました。うまくいけば、今再現可能です:) –

答えて

0

OK fmin_cgがハングしないようにする方法を見つけました。

基本的には、コスト関数の勾配を計算し、fprimeパラメータにfmin_cgという値を渡すだけです。

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) 

1が妥当な時間内モデルを訓練することができます(100を言う)秒以内に終了して、高い数値にmaxiterを設定します。

The documentation of fmin_cgは、fprimeが指定されていない場合、グラデーションが数値計算されると言います。これは、ハングアップの原因と思われるものです。

this notebook by [email protected]のおかげで解決策が見つかりました。

関連する問題