0

ニューラル ネットワークを作成してトレーニングする小さなプロジェクトを C# で作成しました。詳細については、こちらの以前の質問を参照してください: ( https://scicomp.stackexchange.com/questions/19481 )。

十分なトレーニングを行った後、ニューラル ネットワークは適切に機能しますが、自分で作成したヒル クライミング アルゴリズムが完全ではない可能性があることに気づき、改善のための提案を探しています。特に、適応度評価関数の呼び出しを少なくして局所最適に到達できるでしょうか?

C# での単純なヒル クライミング アルゴリズムの例は Web にあまりないようです。.NET Math Library がありますが、何かにお金を払う必要はありません。

ヒル クライミング アルゴリズムは、ネットワーク内のすべての重みとすべてのバイアスに対して実行され、ネットワークをトレーニングします。複数のパスを実行します。バックプロパゲーションを調べましたが、これは 1 つのトレーニング例にのみ適用されるようです。トレーニング データには約 7000 の例があり、フィットネス関数はそれらすべてのネットワークの平均パフォーマンスを評価し、連続 (ダブル)スコア。

これが私の現在のコードです:

    public static double ImproveProperty(ref double property, double startingFitness, int maxIters, Random r, ref Defs.Network network, Func<Defs.Network, double> fitnessFunction)
    {
        //Record starting values
        var lastFitness = startingFitness;
        var lastValue = property;
        //Randomise magnitude of change to reduce chance 
        //of getting stuck in local optimums
        var magnitude = r.NextDouble();
        var positive = true;
        var iterCount = 0f;
        var magnitudeChange = 5;
        while (iterCount < maxIters)
        {
            iterCount++;
            if (positive)
            {   //Try adding a positive value to the property
                property += magnitude;
                //Evaluate the fitness
                var fitness = fitnessFunction(network);
                if (fitness == lastFitness)
                {   //No change in fitness, increase the magnitude and re-try
                    magnitude *= magnitudeChange;
                    property = lastValue;
                }
                else if (fitness < lastFitness)
                {   //This change decreased the fitness (bad)
                    //Put the property back and try going in the negative direction
                    property = lastValue;
                    positive = false;
                }
                else
                {   //This change increased the fitness (good)
                    //on the next iteration we will try 
                    //to apply the same change again
                    lastFitness = fitness;
                    lastValue = property;
                    //don't increase the iteration count as much
                    //if a good change was made
                    iterCount -= 0.9f;
                }
            }
            else
            {   //Try adding a negative value to the property
                property -= magnitude;
                var fitness = fitnessFunction(network);
                if (fitness == lastFitness)
                {
                    //No change in fitness, increase the magnitude and re-try
                    magnitude *= magnitudeChange;
                    property = lastValue;
                }
                else if (fitness < lastFitness)
                {
                    //This change decreased the fitness (bad)
                    //Now we know that going in the positive direction 
                    //and the negative direction decreases the fitness
                    //so make the magnitude smaller as we are probably close to an optimum
                    property = lastValue;
                    magnitude /= magnitudeChange;
                    positive = true;
                }
                else
                {
                    //This change increased the fitness (good)
                    //Continue in same direction
                    lastFitness = fitness;
                    lastValue = property;
                    iterCount -= 0.9f;
                }
            }
            //Check bounds to prevent math functions overflowing
            if (property > 100)
            {
                property = 100;
                lastFitness = fitnessFunction(network);
                return lastFitness;
            }
            else if (property < -100)
            {
                property = -100;
                lastFitness = fitnessFunction(network);
                return lastFitness;
            }
        }
        return lastFitness;
    }

フィットネス関数は非常にコストがかかるため、できるだけ呼び出さないようにする必要があります。フィットネス関数の呼び出しを減らして局所最適に到達するための改善を探しています。局所最適に行き詰まることはあまり問題ではありません。ネットワーク内のさまざまな重みとバイアスの値に対してフィットネス関数をグラフ化しました。通常、グラフには 1 ~ 3 個の局所最適があるように見えます。ネットワークが数回のパスで同じ適合性を維持している場合は、この関数にパラメーターを追加して、ランダムな値からヒル クライミングを再開することを試みることができます。

4

1 に答える 1

0

このアプローチは実際には拡張できません。単一のパラメーターでわずかな改善を得るために、非常に高価な総フィットネス関数を数回評価しようとしています。これが、勾配ベースの方法が最適化問題をサンプルごと、または通常はミニバッチごとに調べる理由のすべてです。フィットネス関数は、各サンプル (またはバッチ) のフィットネス関数の合計に分解されます。これにより、小さな更新を計算し、正しい方向に一歩進むことができます。

理論を少し読む必要があります。このオンライン ブックなど、優れたオンライン リソースが多数あります。

または、ニューラル ネットワークの背後にある理論にあまり興味がなく、単に適用したい場合は、車輪を再発明するのではなく、代わりに、Torch7 など、ニューラル ネットワーク用の多くのオープン ソース ツールキットの 1 つを使用することをお勧めします。カフェ、pylearn2、ラザニア、ケラス、テアネット...

于 2015-04-29T13:19:25.770 に答える