2

MNIST セット (手書き数字のセット) を使用して分類器をトレーニングしようとしていますが、確率的勾配降下アルゴリズムを実装したいと考えています。ここに私が書いた関数があります:

def Stochastic_gradient_descent(theta, y, X, alpha, nIter):
    costs = numpy.zeros([nIter, 1])
    N = y.size
    for i in range(nIter):
        random = randint(0,49999)
        theta -= alpha*(tls.h(theta, X)[random] - y[random])*X[[random],:].T
        costs[i] = (1/N)*tls.cost(theta, y, X)
    return theta, costs

alpha はステップの長さです

h は、transpose(theta).X のシグモイド関数です。

X は 50000*785 で、50000 はトレーニング セットのサイズで、785 = (画像のサイズ) + 1 (定数 theta0 の場合)

この関数は、100 回の反復 (nIter) で約 9 秒、つまり 100*1*785 の乗算で実行されます。私が見つけた分類子は満足のいくものです。この実行時間を勾配降下アルゴリズムと比較したいと思いました。

theta -= alpha * (1/N) * (numpy.dot((tls.h(theta, X) - y).T, X)).T

この関数は、100 回の反復 (nIter) で約 12 秒で実行されるため、(h(theta,X)-y) として 100*50000*785 の乗算は 50000*1 ベクトルです。私が見つけた分類子も満足のいくものですが、このコードは最初のコードよりもそれほど遅くないので驚いています。ベクトル化がドット関数で重要な役割を果たしていることは理解していますが、パフォーマンスが低下すると予想していました。確率的勾配降下法のパフォーマンスを改善する方法はありますか?

ご協力ありがとうございました。

4

1 に答える 1

1

私に関する限り、ベクトル化は SGD のパフォーマンスを改善する最も簡単な方法です。他にもいくつか試してみることができます。たとえば、いくつかのサンプルのミニバッチを使用して Cython バージョンをコーディングする (単一サンプルの「ノイズ」を平均化する傾向がある)、または単純に次を使用してさまざまな停止基準を試すことができます: 早期停止、ゼロに十分近い、しきい値-停止、...

ML 学習アルゴリズムまたは最適化関数を実装して、最初の連絡先としてそれについて学習することが目的である場合は、完璧です。仕事を続けて下さい。しかし、専門的な方法で作業したい場合は、既に最適化された (十分にテストされた) ライブラリを使用する必要があります。

Caffe、Torch、Theano、Neon (Nirvana) などの PS ライブラリには、GPU サポートに加えて非常に高いパフォーマンスを実現できる、非常に複雑で魔法のような最適化があります。

最も人気のあるライブラリのいくつかでコーディングされた ImageNet 勝者モデルのベンチマーク: https://github.com/soumith/convnet-benchmarks

于 2016-02-07T02:17:37.873 に答える