0

私は基本的なニューラル ネットワークの結果を証明するために取り組んでいますが、これまでのところできていません。encog でフィードフォワード xor 問題を実行し、最終的な重みと計算された出力をエクスポートします。

証明するために、重みを入力するExcelシートがあるだけです.I1 * W1 + I2 * W2 | I1*W3+I2*W4 を非表示層に適用し、次にそれぞれのシグモイド アクティベーション、次に H1*W5+H2*W6 を出力のために再度シグモイド化します。

したがって、偏りはなく、基本的な 2x2x1 ですが、ウェイトを接続すると得られる出力値は、encog で受け取る期待される出力値に近くありません。

encog からテストする 8 つの出力セットがありますが、これまでのところ、同じ結論には達していません。どんな助けでも大歓迎です。

以下は、それが役立つ場合の出力例です。ありがとう、イスラエル

出力重み

61.11812639080170、-70.09419692460420、2.58264325902522、2.59015713019213、1.16050691499417、1.16295830927117

出力値

0.01111771776254、0.96929877340644、0.96926035361899、0.04443376315742

Excelでは、シグモイド関数に使用しているものは次のとおりです:= 1 /(1 + EXP(-1 *(C3)))、シグモイドの外での加算と乗算であるため、これ以上役立つかどうかはわかりません。

Form1.cs は次のとおりです。

using Encog.Engine.Network.Activation;
using Encog.ML.Data.Basic;
using Encog.Neural.Networks;
using Encog.Neural.Networks.Layers;
using Encog.Neural.Networks.Training.Propagation.Resilient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Encog_Visual
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            double[][] XOR_Input = 
            {
                new[] {0.0,0.0},
                new[] {1.0,0.0},
                new[] {0.0,1.0},
                new[] {1.0,1.0}
            };

            double[][] XOR_Ideal =
            {
                new[] {0.0},
                new[] {1.0},
                new[] {1.0},
                new[] {0.0}
            };

            var trainingSet = new BasicMLDataSet(XOR_Input, XOR_Ideal);

            BasicNetwork network = CreateNetwork();

            var train = new ResilientPropagation(network, trainingSet);

            int epoch = 0;
            do
            {          
                train.Iteration();
                epoch++;
                string result0 = String.Format("Iteration No :{0}, Error: {1}", epoch, train.Error);
                textBox1.AppendText(result0 + Environment.NewLine);
            } while (train.Error > 0.001);


            foreach (var item in trainingSet)
            {
                var output = network.Compute(item.Input);
                string result1 = String.Format("Input : {0}, {1} Ideal : {2} Actual : {3}", item.Input[0], item.Input[1], item.Ideal[0], output[0]);
                textBox1.AppendText(result1 + Environment.NewLine + network.DumpWeights() + Environment.NewLine);
            }        


        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private static BasicNetwork CreateNetwork()
        {
            var network = new BasicNetwork();
            network.AddLayer(new BasicLayer(null, false, 2));
            network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 2));
            network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 1));
            network.Structure.FinalizeStructure();
            network.Reset();
            return network;
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }


    }


}
4

2 に答える 2

2

私はこれに出くわし、ここにたどり着きました。詳細が必要な答えが残っていると思います:

はい、確かに、レイヤーはEncog フレームワーク全体で異なる基準で番号付けされているように見えるため、各重みがどのレイヤーに属しているかを判断するには時間がかかります。

たとえば、次のようなコードを記述した場合、 wherenetworkNameは自分のものと呼びたいものです (例: "XOR_one")。main public Form1()次に、ネットワーク トレーニング ループの後に、次の 1 行を追加して、この関数を から呼び出すことができますsaveNetwork("XOR_one");

public DirectoryInfo dataDirRoot;
public FileInfo dataFileRoot;
public StreamWriter fileWriteSW;

public bool saveNetwork(string networkName)
{
    try
    {
        // File data initialized
        if (dataDirRoot == null) dataDirRoot = new DirectoryInfo(Application.StartupPath + "\\Data");
        if (!dataDirRoot.Exists) dataDirRoot.Create();

        dataFileRoot = new FileInfo(dataDirRoot + "\\" + networkName + ".weights.txt");
        fileWriteSW = new StreamWriter(dataFileRoot.FullName, false, Encoding.Default);

        // (A) Write down weights from left to right layers, meaning input first and output last.
        // ...within each layer, weights are ordered up-down, always, in all three methods.
        for (int j = 0; j < network.LayerCount-1; j++)
        {
            for (int l = 0; l < network.GetLayerNeuronCount(j + 1); l++)
            {
                for (int k = 0; k < network.GetLayerTotalNeuronCount(j); k++)
                {
                    fileWriteSW.Write(network.GetWeight(j, k, l).ToString("r") + ", ");
                }
                fileWriteSW.Write("\r\n"); 
            }
        }
        fileWriteSW.Write("\r\n\r\n");

        // (B) Write down weights from left to right layers, output first, input last
        double[] auxDouble = new double[network.EncodedArrayLength()];  
        network.EncodeToArray(auxDouble);

        for (int j = 0; j < network.EncodedArrayLength(); j++)
        {
            fileWriteSW.Write(auxDouble[j] + "\r\n");
        }
        fileWriteSW.Flush();
        fileWriteSW.Close();

        // (C) Write down network structure
        // ...you will find that "weights" in the same order as with "DumpWeights()"
        dataFileRoot = new FileInfo(dataDirRoot + networkName + ".encog.txt");
        Encog.Persist.EncogDirectoryPersistence.SaveObject(dataFileRoot, network);
    }
    catch (Exception e)
    {
        MessageBox.Show("Error: " + e.Message);
        return false;
    }
    return true;
}

重要: 隠れ層にバイアスをかけずに XOR ネットワークをトレーニングすることは非常に難しいため、表示している結果には、例よりも 2 つ多くの重みがあります。これは、コード内の 1 行を変更することで実現できます。

...network.AddLayer(new BasicLayer(null, false, 2));

network.AddLayer(new BasicLayer(null, true, 2));

...隠しレイヤーに重み入力を与えるため。隠れ層のニューロンには、それぞれ 3 つの重みがあります。1 つはニューロン入力 1 から、もう 1 つはニューロン入力 2 から、そして 3 つ目はバイアス ニューロン (入力層の「3 番目のニューロン」としてリストされ、値が 1.0 に固定されています) からのものです。

したがって、ここで注意が必要なのは、どのレイヤーに「レイヤー 0」という名前を付けるかです。

(A) の場合、レイヤー 0 は左から 1 番目の入力レイヤーであり、重みは最初の非表示レイヤー (入力には重みがないため)、ニューロン 0 から 1、そして出力レイヤーであるニューロン 0 からダンプされます。

ただし、(B) および (C) で "DumpWeights()" の場合、レイヤー 0 は右から 1 番目、つまり出力レイヤーであり、重みは右から左のレイヤーにダンプされ、各レイヤー内で上下にダンプされます。

常に、各レイヤー内で、重みは順番にダンプされます。Neuron 0 から n まで、および各ニューロン内では、レイヤーの上位ニューロンから左から最後のニューロンまで、またはバイアスが左層に存在する場合はバイアスになります。

出力重みの結果は次のようになります。

Case (A)
-3.61545321823196, -2.7522256580709645, 3.509680820551957, 
-7.2744584719809806, -6.05682131778526, 7.6850785784618676, 
-35.025902985103983, 31.763309640942925, 

Case (B) 
-35.025902985104
31.7633096409429
-3.61545321823196
-2.75222565807096
3.50968082055196
-7.27445847198098
-6.05682131778526
7.68507857846187

それでは見てみましょう:

**Output Layer** (being it called 0 or N... you decide, I prefer N)
**Neuron 0** (the only one there)
weight 2,0,0 = -35.025902985104 (where 2 is layer, 0 is first neuron in hidden layer and 0 is output neuron)
weight 2,1,0 = 31.7633096409429

**Hidden Layer** (I choose 1)
**Neuron 0** (first one)
weight 1,0,0 = -3.61545321823196 (where 1 is layer, 0 is first neuron in input layer and 0 is this neuron)
weight 1,1,0 = -2.75222565807096
weight 1,2,0 = 3.50968082055196
**Neuron 1** (last one)
weight 1,0,1 = -7.27445847198098 
weight 1,1,1 = -6.05682131778526
weight 1,2,1 = 7.68507857846187 (where 1 is layer, 2 is bias in input layer and 1 is this neuron)

注:質問の例は、DumpWeights()61.11812639080170、-70.09419692460420、2.58264325902522、2.59015713019213、1.16050691499417、1.16295830927117の結果でした

ケース (B) に対応し、コンマ区切りのみです。最初の 2 つの数値は出力ニューロンに属し、後者は出力ニューロンに属し、3 番目と 4 番目は 1 番目のニューロン (隠れ層) に、5 番目と 6 番目は 2 番目のニューロン (隠れ層) に属します。

ここに、データを使用した Excel の例の CSV を含めます。

,,=+A2,2.58264325902522,,,,,,,
0,,=+A4,2.59015713019213,=C1*D1+C2*D2,=1/(1+EXP(-1*(E2))),,,,,
,,=+A2,1.16050691499417,,,,=+F2,61.1181263908017,,
0,,=+A4,1.16295830927117,=C3*D3+C4*D4,=1/(1+EXP(-1*(E4))),,=+F4,-70.0941969246042,=H3*I3+H4*I4,=1/(1+EXP(-1*(J4)))
,,,,,,,,,,
,,=+A7,2.58264325902522,,,,,,,
1,,=+A9,2.59015713019213,=C6*D6+C7*D7,=1/(1+EXP(-1*(E7))),,,,,
,,=+A7,1.16050691499417,,,,=+F7,61.1181263908017,,
0,,=+A9,1.16295830927117,=C8*D8+C9*D9,=1/(1+EXP(-1*(E9))),,=+F9,-70.0941969246042,=H8*I8+H9*I9,=1/(1+EXP(-1*(J9)))
,,,,,,,,,,
,,=+A12,2.58264325902522,,,,,,,
0,,=+A14,2.59015713019213,=C11*D11+C12*D12,=1/(1+EXP(-1*(E12))),,,,,
,,=+A12,1.16050691499417,,,,=+F12,61.1181263908017,,
1,,=+A14,1.16295830927117,=C13*D13+C14*D14,=1/(1+EXP(-1*(E14))),,=+F14,-70.0941969246042,=H13*I13+H14*I14,=1/(1+EXP(-1*(J14)))
,,,,,,,,,,
,,=+A17,2.58264325902522,,,,,,,
1,,=+A19,2.59015713019213,=C16*D16+C17*D17,=1/(1+EXP(-1*(E17))),,,,,
,,=+A17,1.16050691499417,,,,=+F17,61.1181263908017,,
1,,=+A19,1.16295830927117,=C18*D18+C19*D19,=1/(1+EXP(-1*(E19))),,=+F19,-70.0941969246042,=H18*I18+H19*I19,=1/(1+EXP(-1*(J19)))
,,,,,,,,,,
DumpWeights() = ,,,,,,,,,,
"61.11812639080170, -70.09419692460420, 2.58264325902522, 2.59015713019213, 1.16050691499417, 1.16295830927117",,,,,,,,,,

それはそれを行う必要があります:)

(記録のために、私は Encog v3.2.0 を使用しました)

于 2014-05-25T15:27:30.923 に答える