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は実際にメンテナンスされていますか?.
さらに掘り下げた後、PyBrainのチュートリアルの例は完全に適切ではないことがわかりました。
ソースコードのメソッドシグネチャを見ると、次のことがわかります。
def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):
つまり、トレーニングセットの25%が検証に使用されます。データでネットワークをトレーニングする場合、これは非常に有効な方法ですが、可能性の完全な範囲、つまり4列XOR 2-in -1-outソリューションセット。XORセットをトレーニングしたいときに、検証のために行の1つを削除すると、すぐに結果として非常にまばらなトレーニングセットが得られ、可能な組み合わせは省略され、トレーニングされていないウェイトが自動的に作成されます。
通常、検証のためにデータの25%を省略した場合、それらの25%が、ネットワークがすでに多かれ少なかれ遭遇したソリューション空間の「大部分」をカバーしていると想定することでこれを行います。この場合、これは当てはまりません。検証のために削除したため、ネットワークにはまったく未知のソリューション空間の25%をカバーしています。
したがって、トレーナーはネットワークを正しくトレーニングしていましたが、XOR問題の25%を省略することにより、ネットワークのトレーニングが不十分になります。
この特定のXORの場合はこの例がまったく間違っているため、クイックスタートとしてのPyBrain Webサイトの別の例は非常に便利です。ランダムに不適切に訓練されたネットワークを出力します。
私は、Andrew Ngが教えてくれた優れた Courseraの機械学習クラス を受講しました。クラスの一部は、xorを認識するための小さなニューラルネットのトレーニングをカバーしました。したがって、収束しなかった quickstart の一部に基づくpybrainの例に少し悩みました。
上記の最小データセットがトレーニングと検証に分割されることを含む、多くの理由があると思います。コースのある時点で、アンドリューは「最も優れたアルゴリズムを持つ人ではなく、データが最も多い人です。そして、2000年代のデータ可用性の急増が理由の一部であることを説明し続けました。 AIの復活、現在は機械学習と呼ばれています。
それをすべて念頭に置いて、私はそれを見つけました
だからここに働くいくつかのコードがあります:
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])
trainer = BackpropTrainer(net, ds, learningrate = 0.9, momentum=0.0, weightdecay=0.0, verbose=True)
trainer.trainEpochs(epochs=1000)
この方法で収束できます。学習率が小さすぎる場合(例:0.01)、極小値で失われます。私がテストしたように、学習率は0.3-30で収束します。
以下は一貫して正しい結果を与えるようです:
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])