32

PyBrain チュートリアルの次のコードがあります。

from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure.modules import TanhLayer

ds = SupervisedDataSet(2, 1)
ds.addSample((0,0), (0,))
ds.addSample((0,1), (1,))
ds.addSample((1,0), (1,))
ds.addSample((1,1), (0,))

net     = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
trainer = BackpropTrainer(net, ds)

for inp, tar in ds:
     print [net.activate(inp), tar]

errors  = trainer.trainUntilConvergence()

for inp, tar in ds:
     print [net.activate(inp), tar]

ただし、結果として、十分にトレーニングされていないニューラル ネットワークが作成されます。エラー出力を見ると、ネットワークは適切にトレーニングされていますが、「continueEpochs」引数を使用してさらにトレーニングを行っているため、ネットワークのパフォーマンスが再び低下しています。したがって、ネットワークは収束していますが、最適なトレーニング済みネットワークを取得する方法はありません。PyBrain のドキュメントは、最適にトレーニングされたネットワークが返されることを暗示していますが、エラーのタプルを返します。

continueEpochs を 0 に設定するとエラー (ValueError: max() arg は空のシーケンス) が発生するため、continueEpochs は 0 よりも大きくする必要があります。

ドキュメントとコードに大きな違いがあるように見えるため、PyBrain は実際に維持されていますか。

4

4 に答える 4

35

さらに掘り下げた後、PyBrain のチュートリアルの例が完全に場違いであることがわかりました。

ソース コードのメソッド シグネチャを見ると、次のことがわかります。

def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):

これは、トレーニング セットの 25% が検証に使用されることを意味します。これは、ネットワークをデータでトレーニングする場合に非常に有効な方法ですが、完全な範囲の可能性を自由に使用できる場合、つまり 4 行 XOR 2-in-1-out ソリューション セットがある場合は、これを行いません。XOR セットをトレーニングする必要があり、検証のために行の 1 つを削除すると、可能な組み合わせの 1 つが省略され、トレーニングされていない重みが自動的に発生する非常にまばらなトレーニング セットが得られます。

通常、検証のためにデータの 25% を省略する場合、それらの 25% が、ネットワークが多かれ少なかれ既に遭遇したソリューション スペースの「ほとんど」をカバーすると仮定して、これを行います。この場合、これは正しくなく、検証のために削除したため、ネットワークにはまったく知られていないソリューション スペースの 25% をカバーしています。

そのため、トレーナーはネットワークを正しくトレーニングしていましたが、XOR 問題の 25% を省略したため、トレーニングが不十分なネットワークになってしまいました。

この特定の XOR のケースでは、この例は明らかに間違っているため、クイックスタートとして PyBrain Web サイトの別の例が非常に便利です。よく訓練されていないランダムなネットワークを出力するだけなので、彼らがこの例を自分で試したのではないかと思うかもしれません。

于 2012-08-21T08:23:06.910 に答える
17

私は、Coursera で Andrew Ng が教えてくれた優れた機械学習クラスを受講しました。クラスの一部では、xor を認識するための小さなニューラル ネットワークのトレーニングについて説明しました。そのため、収束しなかったクイックスタートの部分に基づく pybrain の例に少し悩まされました。

最小限のデータセットがトレーニングと検証に分割されているという上記の理由を含め、多くの理由があると思います。コースのある時点で、アンドリューは次のように述べています。機械学習と呼ばれるようになった AI の復活。

だから、すべてを念頭に置いて、私はそれを見つけました

  1. 検証セットは、トレーニング フェーズの後に来るため、4 つのサンプルを持つことができます。
  2. クラスで学んだように、ネットワークには隠れ層に2つのノードしか必要ありません。
  3. この場合、学習率は 0.005 のようにかなり小さくする必要があります。そうしないと、トレーニングが答えをスキップすることがあります (これは、私が数字で遊んで確認したクラスの重要なポイントです)。
  4. 学習率が小さいほど、maxEpochs を小さくできます。学習率が小さいということは、収束が最小化に向かって勾配に沿ってより小さいステップを取ることを意味します。大きい場合は、maxEpochs を大きくして、最小値に達したと判断するまでの待機時間が長くなるようにする必要があります。
  5. ネットワークに bias=True が必要です (これにより、定数 1 ノードが入力層と非表示層に追加されます)。バイアスに関するこの質問への回答を読んでください。
  6. 最後に、そして最も重要なこととして、大きなトレーニング セットが必要です。1000 人は約 75% の確率で正しい答えに収束しました。これは最小化アルゴリズムに関係していると思われます。数値が小さいと、頻繁に失敗します。

したがって、動作するコードは次のとおりです。

from pybrain.datasets import SupervisedDataSet

dataModel = [
    [(0,0), (0,)],
    [(0,1), (1,)],
    [(1,0), (1,)],
    [(1,1), (0,)],
]

ds = SupervisedDataSet(2, 1)
for input, target in dataModel:
    ds.addSample(input, target)

# create a large random data set
import random
random.seed()
trainingSet = SupervisedDataSet(2, 1);
for ri in range(0,1000):
    input,target = dataModel[random.getrandbits(2)];
    trainingSet.addSample(input, target)

from pybrain.tools.shortcuts import buildNetwork
net = buildNetwork(2, 2, 1, bias=True)

from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(net, ds, learningrate = 0.001, momentum = 0.99)
trainer.trainUntilConvergence(verbose=True,
                              trainingData=trainingSet,
                              validationData=ds,
                              maxEpochs=10)

print '0,0->', net.activate([0,0])
print '0,1->', net.activate([0,1])
print '1,0->', net.activate([1,0])
print '1,1->', net.activate([1,1])
于 2013-12-10T04:30:43.723 に答える
2
trainer = BackpropTrainer(net, ds, learningrate = 0.9, momentum=0.0, weightdecay=0.0, verbose=True) 
trainer.trainEpochs(epochs=1000)

This way can converge. if learningrate is too small(e.g. 0.01), it lost in local minimum. As I have tested, learningrate in 0.3-30, it can converge.

于 2014-03-23T14:42:39.223 に答える
0

以下は一貫して正しい結果を与えるようです:

from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure import TanhLayer
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer

#net = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
net = buildNetwork(2, 3, 1, bias=True)

ds = SupervisedDataSet(2, 1)
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))
ds.addSample((0, 0), (0,))
ds.addSample((0, 1), (1,))
ds.addSample((1, 0), (1,))
ds.addSample((1, 1), (0,))

trainer = BackpropTrainer(net, ds, learningrate=0.001, momentum=0.99)

trainer.trainUntilConvergence(verbose=True)

print net.activate([0,0])
print net.activate([0,1])
print net.activate([1,0])
print net.activate([1,1])
于 2016-02-04T19:16:33.750 に答える