ニューラルネットワークが数字を認識するための基本的なフレームワークがありますが、トレーニングに問題があります。私のバックプロポーションは小さなデータセットでも機能しますが、データポイントが50を超えると、戻り値は0に収束し始めます。何千ものデータセットがある場合、NaNを取得して返します。ニューラルネットワークと大きなデータセット
基本構成:3層:784:15:1
784は、データ・セット当たりの画素、私の隠れ層15個のニューロン、および0から1までの値を返すつの出力ニューロンの数(ありますあなたは10を掛けて数字を得る)。
public class NetworkManager {
int inputSize;
int hiddenSize;
int outputSize;
public Matrix W1;
public Matrix W2;
public NetworkManager(int input, int hidden, int output) {
inputSize = input;
hiddenSize = hidden;
outputSize = output;
W1 = new Matrix(inputSize, hiddenSize);
W2 = new Matrix(hiddenSize, output);
}
Matrix z2, z3;
Matrix a2;
public Matrix forward(Matrix X) {
z2 = X.dot(W1);
a2 = sigmoid(z2);
z3 = a2.dot(W2);
Matrix yHat = sigmoid(z3);
return yHat;
}
public double costFunction(Matrix X, Matrix y) {
Matrix yHat = forward(X);
Matrix cost = yHat.sub(y);
cost = cost.mult(cost);
double returnValue = 0;
int i = 0;
while (i < cost.m.length) {
returnValue += cost.m[i][0];
i++;
}
return returnValue;
}
Matrix yHat;
public Matrix[] costFunctionPrime(Matrix X, Matrix y) {
yHat = forward(X);
Matrix delta3 = (yHat.sub(y)).mult(sigmoidPrime(z3));
Matrix dJdW2 = a2.t().dot(delta3);
Matrix delta2 = (delta3.dot(W2.t())).mult(sigmoidPrime(z2));
Matrix dJdW1 = X.t().dot(delta2);
return new Matrix[]{dJdW1, dJdW2};
}
}
ネットワークフレームワークのコードがあります。私は長さ784の倍精度配列を順方向メソッドに渡します。
int t = 0;
while (t < 10000) {
dJdW = Nn.costFunctionPrime(X, y);
Nn.W1 = Nn.W1.sub(dJdW[0].scalar(3));
Nn.W2 = Nn.W2.sub(dJdW[1].scalar(3));
t++;
}
私はこれを使用して重みを調整します。小さなセットでは、コストは0に収束しますが、大きなセットはありません(100文字に関連するコストは常に13に収束します)。セットが大きすぎると、最初の調整が行われ(そしてコストは下がります)、2番目の調整が終わるとNaNになります。
なぜこの実装は大規模なデータセット(特にトレーニング)で失敗しますか?これをどのように修正できますか?私は同様の構造を1の代わりに10個の出力で試しました。ここではそれぞれ0または1に近い値をブール値のように返しますが、同じことが起こっていました。
私はJavaでこれをやっていますが、それが問題と関係しているのかどうか疑問です。私はそれが宇宙の不足で問題だったかどうか疑問に思っていましたが、私はヒープスペースメッセージを取得していません。どのように私は戻ってpropogatingや何か他のことが起きていることに問題がありますか?
編集:私は何が起こっているか知っていると思います。私は、私のバックプロパゲーション機能が地方の最低限に捕らえられていると思います。トレーニングが成功することがあり、大規模なデータセットでは失敗することがあります。ランダムウェイトから始めているので、ランダムな初期コストが発生します。私が気付いたことは、コストが最初に一定量(それが関係するデータセットの数に依存する)を超えると、コストはきれいな数に(時には27、その他は17.4に)収束し、アウトプットは0に収束する)。
私が始めたときのコスト関数の相対的な最小値が警告され、なぜそれが実現し始めているのですか?だから今質問は、どのように私は実際に世界最小を見つけるだろう私の勾配降下について行くのだろうか?私は途中でJavaで作業しています。
数字の認識は分類問題であり、回帰問題ではありません。 1桁にそれぞれ対応する10個の出力を使用し、最も高い出力値を持つ出力ニューロンに基づいて認識された桁を選択することを検討する必要があります。 – Palle
ええ、私は実際に10の出力フレームワークに戻ってきました –