コード例 #1
0
 private void ValidateHopfield(HopfieldNetwork network)
 {
     Assert.AreEqual(4, network.NeuronCount);
     Assert.AreEqual(4, network.CurrentState.Count);
     Assert.AreEqual(16, network.Weights.Length);
     Assert.AreEqual(1.0, network.GetWeight(1, 1));
 }
コード例 #2
0
        public void ShouldRecogniseInversedSymbolWithNoises()
        {
            // given
            var hopfieldNetwork = new HopfieldNetwork();
            var symbolsToLearn  = new List <BipolarSymbol>
            {
                SymbolFactory.CreateBipolarFromDigit(0),
                SymbolFactory.CreateBipolarFromDigit(1),
                SymbolFactory.CreateBipolarFromDigit(2)
            };

            hopfieldNetwork.Learn(symbolsToLearn);

            // when
            bool symbolIsRecognised = hopfieldNetwork.TryRecognise(IversedNumberOneWithNoises());

            // then
            Assert.Equal(1, hopfieldNetwork.IterationsCountOfRecognising);
            Assert.True(symbolIsRecognised);

            BipolarSymbol expectedRecognisedSymbol = SymbolFactory.CreateBipolarFromDigit(1);

            expectedRecognisedSymbol.Inverse();
            Assert.Equal(expectedRecognisedSymbol.ConvertToOneDimensionalArray(), hopfieldNetwork.SymbolsOut);
        }
コード例 #3
0
        public void Execute(IExampleInterface app)
        {
            this.app = app;

            // Create the neural network.
            BasicLayer hopfield;
            var        network = new HopfieldNetwork(4);

            // This pattern will be trained
            bool[] pattern1 = { true, true, false, false };
            // This pattern will be presented
            bool[]  pattern2 = { true, false, false, false };
            IMLData result;

            var data1 = new BiPolarMLData(pattern1);
            var data2 = new BiPolarMLData(pattern2);
            var set   = new BasicMLDataSet();

            set.Add(data1);

            // train the neural network with pattern1
            app.WriteLine("Training Hopfield network with: "
                          + FormatBoolean(data1));

            network.AddPattern(data1);
            // present pattern1 and see it recognized
            result = network.Compute(data1);
            app.WriteLine("Presenting pattern:" + FormatBoolean(data1)
                          + ", and got " + FormatBoolean(result));
            // Present pattern2, which is similar to pattern 1. Pattern 1
            // should be recalled.
            result = network.Compute(data2);
            app.WriteLine("Presenting pattern:" + FormatBoolean(data2)
                          + ", and got " + FormatBoolean(result));
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: iroegbu/HopfieldNeuralNet
        /**
         * A simple main method to test the Hopfield neural network.
         *
         * @param args
         *            Not used.
         */
        static void Main(string[] args)
        {
            // Create the neural network.
            HopfieldNetwork network = new HopfieldNetwork(4);

            // This pattern will be trained
            bool[] TrainingPattern = { true, true, false, false };
            // This pattern will be presented
            bool[] PresentedPattern = { true, false, false, false };
            bool[] result;

            // train the neural network with pattern1
            Console.WriteLine("Training Hopfield network with: "
                              + FormatBoolean(TrainingPattern));
            network.Train(TrainingPattern);
            // present pattern1 and see it recognized
            result = network.Present(TrainingPattern);
            Console.WriteLine("Presenting pattern:" + FormatBoolean(TrainingPattern)
                              + ", and got " + FormatBoolean(result));
            // Present pattern2, which is similar to pattern 1. Pattern 1
            // should be recalled.
            result = network.Present(PresentedPattern);
            Console.WriteLine("Presenting pattern:" + FormatBoolean(PresentedPattern)
                              + ", and got " + FormatBoolean(result));
            Console.ReadLine();
        }
コード例 #5
0
        public void ShouldCreateHopfieldNetwork()
        {
            // when
            var hopfieldNetwork = new HopfieldNetwork();

            // then
            Assert.NotNull(hopfieldNetwork);
        }
コード例 #6
0
        public void Setup()
        {
            Pattern1 = new HopfieldPattern(0.0, 1.0, 0.0, 1.0);
            Pattern2 = new HopfieldPattern(1.0, 0.0, 0.0, 1.0);

            Network = new HopfieldNetwork(4);

            Network.Train(Pattern1);
            Network.Train(Pattern2);
        }
コード例 #7
0
        public void ShouldRaiseErrorWhenLearningWithoutSymbols(List <BipolarSymbol> emptySymbols)
        {
            // given
            var hopfieldNetwork = new HopfieldNetwork();

            // when
            Action networkLearning = () => hopfieldNetwork.Learn(emptySymbols);

            // then
            Assert.Throws <NoSymbollsPassedException>(networkLearning);
        }
コード例 #8
0
        public void TestPersistSerial()
        {
            HopfieldNetwork network = new HopfieldNetwork(4);

            network.SetWeight(1, 1, 1);

            SerializeObject.Save(SERIAL_FILENAME.ToString(), network);
            HopfieldNetwork network2 = (HopfieldNetwork)SerializeObject.Load(SERIAL_FILENAME.ToString());

            ValidateHopfield(network2);
        }
コード例 #9
0
        public void TestPersistEG()
        {
            HopfieldNetwork network = new HopfieldNetwork(4);

            network.SetWeight(1, 1, 1);
            network.SetProperty("x", 10);

            EncogDirectoryPersistence.SaveObject(EG_FILENAME, network);
            HopfieldNetwork network2 = (HopfieldNetwork)EncogDirectoryPersistence.LoadObject((EG_FILENAME));

            ValidateHopfield(network2);
        }
コード例 #10
0
 public void Evaluate(HopfieldNetwork hopfield, String[][] pattern)
 {
     for (int i = 0; i < pattern.Length; i++)
     {
         BiPolarMLData pattern1 = ConvertPattern(pattern, i);
         hopfield.CurrentState = pattern1;
         int           cycles   = hopfield.RunUntilStable(100);
         BiPolarMLData pattern2 = hopfield.CurrentState;
         Console.WriteLine("Cycles until stable(max 100): " + cycles + ", result=");
         Display(pattern1, pattern2);
         Console.WriteLine(@"----------------------");
     }
 }
コード例 #11
0
        public void Run()
        {
            var hopfieldLogic = new HopfieldNetwork(WIDTH * HEIGHT);
            var train         = new TrainHopfieldStorkey(hopfieldLogic);

            for (var i = 0; i < PATTERN.Length; i++)
            {
                train.AddPattern(ConvertPattern(PATTERN, i));
            }

            Evaluate(hopfieldLogic, PATTERN);
            Evaluate(hopfieldLogic, PATTERN2);
        }
コード例 #12
0
        public void ShouldCorrectlyLearnDigits(List <int> digits)
        {
            // given
            int[,] expectedWeights = HopfieldNetworkWeightsFactory.WeightsForHebbianLearningOfDigits(digits);
            var hopfieldNetwork = new HopfieldNetwork();
            IList <BipolarSymbol> symbolsToLearn = digits.Select(SymbolFactory.CreateBipolarFromDigit).ToList();

            // when
            hopfieldNetwork.Learn(symbolsToLearn);

            // then
            Assert.Equal(expectedWeights, hopfieldNetwork.Weights);
        }
コード例 #13
0
 public static void Evaluate(HopfieldNetwork hopfieldLogic, String[][] pattern)
 {
     for (int i = 0; i < pattern.Length; i++)
     {
         double[] pattern1 = ConvertPattern(pattern, i);
         hopfieldLogic.CopyToCurrentState(pattern1);
         int      cycles   = hopfieldLogic.RunUntilStable(100);
         double[] pattern2 = hopfieldLogic.CurrentState;
         Console.WriteLine("Cycles until stable(max 100): " + cycles + ", result=");
         Display(pattern1, pattern2);
         Console.WriteLine("----------------------");
     }
 }
コード例 #14
0
        public void GetResult()
        {
            var network = new HopfieldNetwork();

            network.Train(new Dictionary <string, string>
            {
                { "1", Pattern1 },
                { "2", Pattern2 }
            });

            var result = network.GetResult(Pattern1);

            Assert.AreEqual(Pattern1, result);
        }
コード例 #15
0
        public void TrainEventTest()
        {
            var network = new HopfieldNetwork();

            network.OnItemProcessed += (sender, args) =>
            {
                Assert.AreEqual(Math.Sqrt(network.NumberOfNeurons), args.ItemsCount);
            };
            network.Train(new Dictionary <string, string>
            {
                { "1", Pattern1 },
                { "2", Pattern2 }
            });
        }
コード例 #16
0
        public void Run()
        {
            HopfieldNetwork      hopfieldLogic = new HopfieldNetwork(WIDTH * HEIGHT);
            TrainHopfieldHebbian train         = new TrainHopfieldHebbian(hopfieldLogic);

            for (int i = 0; i < PATTERN.Length; i++)
            {
                train.AddPattern(ConvertPattern(PATTERN, i));
            }
            train.Learn();

            Evaluate(hopfieldLogic, PATTERN);
            Evaluate(hopfieldLogic, PATTERN2);
        }
コード例 #17
0
        public void EvaluateEnergyFunctionTest()
        {
            var network = new HopfieldNetwork();

            network.Train(new Dictionary <string, string>
            {
                { "1", Pattern1 },
                { "2", Pattern2 }
            });

            var energyState = network.CurrentEnergyState;

            network.GetResult(Pattern3);

            Assert.IsTrue(network.CurrentEnergyState <= energyState);
        }
コード例 #18
0
        public void ShouldRecogniseLearnedSymbol()
        {
            // given
            var hopfieldNetwork = new HopfieldNetwork();
            var symbolsToLearn  = new List <BipolarSymbol> {
                SymbolFactory.CreateBipolarFromDigit(1), SymbolFactory.CreateBipolarFromDigit(3)
            };

            hopfieldNetwork.Learn(symbolsToLearn);

            // when
            bool symbolIsRecognised = hopfieldNetwork.TryRecognise(SymbolFactory.CreateBipolarFromDigit(1));

            // then
            Assert.True(symbolIsRecognised);
            Assert.Equal(0, hopfieldNetwork.IterationsCountOfRecognising);
        }
コード例 #19
0
        public void ShouldRecogniseTheClosestLearnedSymbol()
        {
            // given
            var hopfieldNetwork = new HopfieldNetwork();
            var symbolsToLearn  = new List <BipolarSymbol> {
                SymbolFactory.CreateBipolarFromDigit(1), SymbolFactory.CreateBipolarFromDigit(3)
            };

            hopfieldNetwork.Learn(symbolsToLearn);

            // when
            bool symbolIsRecognised = hopfieldNetwork.TryRecognise(SymbolFactory.CreateBipolarFromDigit(2));

            // then
            Assert.True(symbolIsRecognised);
            Assert.Equal(1, hopfieldNetwork.IterationsCountOfRecognising);
            Assert.Equal(SymbolFactory.CreateBipolarFromDigit(3).ConvertToOneDimensionalArray(), hopfieldNetwork.SymbolsOut);
        }
コード例 #20
0
        public static void Main()
        {
            Agent reasoner = World.NewAgent();

            InitializeWorld(reasoner);

            //Adds all of the declarative chunks to the GKS
            foreach (DeclarativeChunk dc in chunks)
            {
                reasoner.AddKnowledge(dc);
            }

            //Initializes the Hopfield network in the bottom level of the NACS
            HopfieldNetwork net = AgentInitializer.InitializeAssociativeMemoryNetwork
                                      (reasoner, HopfieldNetwork.Factory);

            //Species all of the dimension-value pairs as nodes for the Hopfield network
            net.Nodes.AddRange(dvs);

            //Commits the Hopfield network
            reasoner.Commit(net);

            //Encodes the patterns into the Hopfield network
            EncodeHopfieldNetwork(net);

            //Sets up the rules in the top level of the NAS
            SetupRules(reasoner);

            //Specifies that the NACS should perform 2 reasoning iterations
            reasoner.NACS.Parameters.REASONING_ITERATION_COUNT = 2;
            //Sets the conclusion threshold to 1
            //(indicating that only fully matched conclusions should be returned)
            reasoner.NACS.Parameters.CONCLUSION_THRESHOLD = 1;

            //Initiates reasoning and outputs the results
            DoReasoning(reasoner);

            //Kills the reasoning agent
            reasoner.Die();

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
コード例 #21
0
        public void ShouldNotRecogniseIncorrectSymbol()
        {
            // given
            var hopfieldNetwork = new HopfieldNetwork();
            var symbolsToLearn  = new List <BipolarSymbol>
            {
                SymbolFactory.CreateBipolarFromDigit(1),
                SymbolFactory.CreateBipolarFromDigit(2),
                SymbolFactory.CreateBipolarFromDigit(4)
            };

            hopfieldNetwork.Learn(symbolsToLearn);

            // when
            bool symbolIsRecognised = hopfieldNetwork.TryRecognise(SymbolFactory.CreateBipolarFromDigit(9));

            // then
            Assert.Equal(1, hopfieldNetwork.IterationsCountOfRecognising);
            Assert.Equal(OutputForUnrecognisedDigitNine(), hopfieldNetwork.SymbolsOut);
            Assert.False(symbolIsRecognised);
        }
        private void TrainButton_Click(object sender, RoutedEventArgs e)
        {
            var colCount = 5;
            var rowCount = 5;

            var pattern = new double[colCount * rowCount];

            for (var row = 0; row < rowCount; row++)
            {
                for (var col = 0; col < colCount; col++)
                {
                    pattern[row * colCount + col] = ((ToggleButton)_GetControlIn(DrawingGrid, new GridCoordinates(row, col))).IsChecked.Value
                        ? 1.0
                        : 0.0;
                }
            }

            var hopfieldPattern = new HopfieldPattern(pattern);

            hopfieldNetwork = hopfieldNetwork ?? new HopfieldNetwork(25);
            hopfieldNetwork.Train(hopfieldPattern);
        }
コード例 #23
0
        /// <summary>
        /// Encodes the patterns into the specified Hopfield network and then tests to make sure they have been successfully encoded
        /// </summary>
        /// <remarks>
        /// <note type="implementnotes">Most of the work that is done by this method is actually also performed by the implicit component initializer's
        /// <see cref="ImplicitComponentInitializer.Encode{T}(T, ImplicitComponentInitializer.EncodeTerminationConditions, int, ActivationCollection[])">
        /// Encode</see> method. However, we must separate the "encode" and "recall" phases in this example since we are using a different
        /// <see cref="HopfieldNetwork.TransmissionOptions">transmission option</see> between these encoding process.</note>
        /// </remarks>
        /// <param name="net">the network where the patterns are to be encoded</param>
        static void EncodeHopfieldNetwork(HopfieldNetwork net)
        {
            //Tracks the accuracy of correctly encoded patterns
            double accuracy = 0;

            //Continue encoding until all of the patterns are successfully recalled
            do
            {
                //Specifies to use the "N spins" transmission option during the encoding phase
                net.Parameters.TRANSMISSION_OPTION =
                    HopfieldNetwork.TransmissionOptions.N_SPINS;

                List <ActivationCollection> sis = new List <ActivationCollection>();
                foreach (DeclarativeChunk dc in chunks)
                {
                    //Gets a new "data set" object (to be used by the Encode method to encode the pattern)
                    ActivationCollection si = ImplicitComponentInitializer.NewDataSet();

                    //Sets up the pattern
                    si.AddRange(dc, 1);

                    sis.Add(si);
                }

                //Encodes the pattern into the Hopfield network
                ImplicitComponentInitializer.Encode(net, sis);


                //Specifies to use the "let settle" transmission option during the testing phase
                net.Parameters.TRANSMISSION_OPTION =
                    HopfieldNetwork.TransmissionOptions.LET_SETTLE;

                //Tests the net to see if it has learned the patterns
                accuracy = ImplicitComponentInitializer.Encode(net, sis, testOnly: true);

                Console.WriteLine(((int)accuracy * 100) + "% of the patterns were successfully recalled.");
            } while (accuracy < 1);
        }
コード例 #24
0
ファイル: MainForm.cs プロジェクト: villacortafritz/Hopfield
 public MainForm()
 {
     InitializeComponent();
     InitializeControls();
     _hopfieldNetwork = new HopfieldNetwork();
 }
コード例 #25
0
 public HopfieldRecForm()
 {
     InitializeComponent();
     grid          = new bool[HopfieldRecForm.GRID_X * HopfieldRecForm.GRID_Y];
     this.hopfield = new HopfieldNetwork(HopfieldRecForm.GRID_X * HopfieldRecForm.GRID_Y);
 }
コード例 #26
0
        /// <summary>
        /// Generate the Hopfield neural network.
        /// </summary>
        ///
        /// <returns>The generated network.</returns>
        public IMLMethod Generate()
        {
            var logic = new HopfieldNetwork(_neuronCount);

            return(logic);
        }
コード例 #27
0
        public static void Main()
        {
            Agent reasoner = World.NewAgent();

            InitializeWorld(reasoner);

            //Adds all of the declarative chunks to the GKS
            foreach (DeclarativeChunk dc in chunks)
            {
                reasoner.AddKnowledge(dc);
            }

            //Initializes the Hopfield network in the bottom level of the NACS
            HopfieldNetwork net = AgentInitializer.InitializeAssociativeMemoryNetwork
                                      (reasoner, HopfieldNetwork.Factory);

            //Species all of the dimension-value pairs as nodes for the Hopfield network
            net.Nodes.AddRange(dvs);

            //Commits the Hopfield network
            reasoner.Commit(net);

            //Encodes the patterns into the Hopfield network
            EncodeHopfieldNetwork(net);

            //Specifies that the NACS should perform 2 reasoning iterations
            reasoner.NACS.Parameters.REASONING_ITERATION_COUNT = 1;
            //Sets the conclusion threshold to 1
            //(indicating that only fully matched conclusions should be returned)
            reasoner.NACS.Parameters.CONCLUSION_THRESHOLD = 1;

            // Add Some Action Chunks for the ACS
            World.NewExternalActionChunk("Yes");
            World.NewExternalActionChunk("No");
            ReasoningRequestActionChunk think = World.NewReasoningRequestActionChunk("DoReasoning");

            think.Add(NonActionCenteredSubsystem.RecognizedReasoningActions.NEW, 1, false);

            World.NewDimensionValuePair("state", 1);
            World.NewDimensionValuePair("state", 2);
            World.NewDimensionValuePair("state", 3);

            // Add ACS Rule to use chunks
            RefineableActionRule yes = AgentInitializer.InitializeActionRule(reasoner, RefineableActionRule.Factory, World.GetActionChunk("Yes"));

            yes.GeneralizedCondition.Add(World.GetDeclarativeChunk(1), true);
            reasoner.Commit(yes);

            RefineableActionRule no = AgentInitializer.InitializeActionRule(reasoner, RefineableActionRule.Factory, World.GetActionChunk("No"));

            no.GeneralizedCondition.Add(World.GetDeclarativeChunk(0), true, "altdim");
            no.GeneralizedCondition.Add(World.GetDeclarativeChunk(2), true, "altdim");
            no.GeneralizedCondition.Add(World.GetDeclarativeChunk(3), true, "altdim");
            no.GeneralizedCondition.Add(World.GetDeclarativeChunk(4), true, "altdim");
            reasoner.Commit(no);

            RefineableActionRule doReasoning = AgentInitializer.InitializeActionRule(reasoner, RefineableActionRule.Factory, World.GetActionChunk("DoReasoning"));

            doReasoning.GeneralizedCondition.Add(World.GetDimensionValuePair("state", 1));
            reasoner.Commit(doReasoning);

            RefineableActionRule doNothing = AgentInitializer.InitializeActionRule(reasoner, RefineableActionRule.Factory, ExternalActionChunk.DO_NOTHING);

            doNothing.GeneralizedCondition.Add(World.GetDimensionValuePair("state", 2));
            reasoner.Commit(doNothing);

            reasoner.ACS.Parameters.PERFORM_RER_REFINEMENT            = false;
            reasoner.ACS.Parameters.FIXED_BL_LEVEL_SELECTION_MEASURE  = 0;
            reasoner.ACS.Parameters.FIXED_RER_LEVEL_SELECTION_MEASURE = 1;
            reasoner.ACS.Parameters.FIXED_IRL_LEVEL_SELECTION_MEASURE = 0;
            reasoner.ACS.Parameters.FIXED_FR_LEVEL_SELECTION_MEASURE  = 0;
            reasoner.ACS.Parameters.LEVEL_SELECTION_METHOD            = ActionCenteredSubsystem.LevelSelectionMethods.STOCHASTIC;
            reasoner.ACS.Parameters.LEVEL_SELECTION_OPTION            = ActionCenteredSubsystem.LevelSelectionOptions.FIXED;
            reasoner.ACS.Parameters.NACS_REASONING_ACTION_PROBABILITY = 1;
            reasoner.ACS.Parameters.EXTERNAL_ACTION_PROBABILITY       = 1;
            reasoner.NACS.Parameters.REASONING_ITERATION_TIME         = 3000;

            //Initiates the simulation and outputs the results
            Run(reasoner);

            //Kills the reasoning agent
            reasoner.Die();

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
コード例 #28
0
 private void btnClear_Click(object sender, EventArgs e)
 {
     network = new HopfieldNetwork(4);
     RefreshMatrixPreview();
 }
コード例 #29
0
 public HopfieldSimple()
 {
     InitializeComponent();
     this.network = new HopfieldNetwork(4);
     RefreshMatrixPreview();
 }
コード例 #30
0
ファイル: Program.cs プロジェクト: 2021SIA/TP4
        /// <summary>
        /// Unsupervised Learning Engine
        /// </summary>
        /// <param name="config">Path to the configuration file</param>
        static async void Main(string config)
        {
            Configuration configuration = Configuration.FromYamlFile(config);

            switch (configuration.Network)
            {
            case "hopfield":
                //Parse network patterns
                var patterns = HopfieldUtils.ParsePatterns(configuration.Patterns, configuration.PatternRows, configuration.PatternColumns);
                //Initialize Hopfield network
                var network = new HopfieldNetwork(patterns);
                //Test network and get closest pattern
                Console.WriteLine($"Testing Pattern: {configuration.TestPattern}; Noise: {configuration.Noise}\n");
                var result = HopfieldUtils.Test(network, patterns, configuration.TestPattern, configuration.Noise);
                //Print network intermediate states
                PrintPatterns(result, configuration.PatternColumns);
                //Check if network got to test pattern successfully
                if (patterns.IndexOf(result[result.Count - 1]) == configuration.TestPattern)
                {
                    Console.WriteLine("Found pattern!\n");
                }
                else
                {
                    Console.WriteLine("Could not find pattern.\n");
                }

                if (configuration.Metrics == "all" || configuration.Metrics == "noise")
                {
                    //Get network noise accuracy metrics
                    await HopfieldUtils.SaveNoiseAccuracyMetrics(network, patterns, configuration.Repetitions, configuration.TestPattern);

                    Console.WriteLine($"Noise metrics stored in accuracy.csv [Repetitions: {configuration.Repetitions}]");
                }
                if (configuration.Metrics == "all" || configuration.Metrics == "energy")
                {
                    //Get network energy metrics
                    await HopfieldUtils.SaveEnergyMetrics(network, patterns, configuration.Repetitions, configuration.TestPattern, configuration.Noise);

                    Console.WriteLine("Energy metrics stored in energy_{i}.csv" + $" [Repetitions: {configuration.Repetitions}]");
                }
                break;

            case "oja":
                var networkOja = new OjaNetwork(configuration.LearningRate, configuration.Epochs, ParseCsv(configuration.Csv));
                var W          = networkOja.TrainOja();
                Console.WriteLine(W);
                break;

            case "kohonen":
                var values  = ParseCsv(configuration.Csv);
                var kohonen = new KohonenNetwork(values, configuration.KohonenK, configuration.WeightEntries);
                kohonen.Train(configuration.Epochs);
                var i         = 0;
                var countries = new string[] { "Austria", "Belgium", "Bulgaria", "Croatia", "Czech", "Denmark", "Estonia", "Finland", "Germany", "Greece", "Hungary", "Iceland", "Ireland", "Italy", "Latvia", "Lithuania", "Luxembourg", "Netherlands", "Norway", "Poland", "Portugal", "Slovakia", "Slovenia", "Spain", "Sweden", "Switzerland", "Ukraine", "United Kingdom" };
                var groups    = new List <(int x, int y)>();
                foreach (var city in kohonen.values)
                {
                    (int x, int y)group = kohonen.Classify(city);
                    Console.WriteLine($"{countries[i++]}: {group.x},{group.y}");
                    groups.Add(group);
                }
                await File.WriteAllLinesAsync("classification.csv", groups.Select((v, index) => $"{v.x},{v.y}"));

                var weights = from Vector <double> weight in kohonen.W select weight;
                await File.WriteAllLinesAsync("weights.csv", weights.Select((v, index) => v.Aggregate("", (str, n) => str + n + ",")));

                var distances = new List <double>();
                for (i = 0; i < kohonen.N; i++)
                {
                    for (var j = 0; j < kohonen.N; j++)
                    {
                        int imin = Math.Max(0, i - 1);
                        int imax = Math.Min(kohonen.N - 1, i + 1);
                        int jmin = Math.Max(0, j - 1);
                        int jmax = Math.Min(kohonen.N - 1, j + 1);

                        var neuronDist = new List <double>();
                        for (int x = imin; x <= imax; x++)
                        {
                            for (int y = jmin; y <= jmax; y++)
                            {
                                if ((i != x || j != y) && kohonen.Distance((i, j), (x, y)) <= 1)
                                {
                                    neuronDist.Add(kohonen.Distance(kohonen.W[i, j], kohonen.W[x, y]));
                                }
                            }
                        }
                        distances.Add(neuronDist.Average());
                    }
                }
                await File.WriteAllLinesAsync("distances.csv", distances.Select(v => v.ToString()));

                break;
            }
        }