/// <summary> /// Constructor. /// </summary> /// <param name="numInputs">Number of inputs.</param> /// <param name="numRBFs">Number of radial basis functions.</param> /// <param name="numOutputs">Number of outputs.</param> public Network(int numInputs, int numRBFs, int numOutputs) { this._numInputs = numInputs; // number of inputs this._numOutputs = numOutputs; // number of outputs int inputWeight = _numInputs * numRBFs; // total number of inputs in network // total number of outputs in network // + 1 because of bias RBF int outputWeight = _numOutputs * (numRBFs + 1); int rbfParams = (_numInputs + 1) * numRBFs; // total number of RBF width scalars and center vectors // allocate space for _longTermMemory _longTermMemory = new double[inputWeight + outputWeight + rbfParams]; _indexInputs = 0; // inputs start at 0 _indexOutputs = inputWeight + rbfParams; // outputs start after inputs and rbf params _rbfs = new GaussianFunction[numRBFs]; // create array of RBFs for (int i = 0; i < numRBFs; i++) { int rbfIndex = inputWeight + ((numInputs + 1) * i); // index of rbf parameters in _longTermMemory // create new Gaussian Function _rbfs[i] = new GaussianFunction(_numInputs, _longTermMemory, rbfIndex); } }
/// <summary> /// Construct the RBF network. /// </summary> /// <param name="theInputCount">The input count.</param> /// <param name="rbfCount">The number of RBF functions.</param> /// <param name="theOutputCount">The output count.</param> public RBFNetwork(int theInputCount, int rbfCount, int theOutputCount) { _inputCount = theInputCount; _outputCount = theOutputCount; // calculate input and output weight counts // add 1 to output to account for an extra bias node int inputWeightCount = _inputCount * rbfCount; int outputWeightCount = (rbfCount + 1) * _outputCount; int rbfParams = (_inputCount + 1) * rbfCount; _longTermMemory = new double[ inputWeightCount + outputWeightCount + rbfParams]; _indexInputWeights = 0; _indexOutputWeights = inputWeightCount + rbfParams; _rbf = new IFnRBF[rbfCount]; for (int i = 0; i < rbfCount; i++) { int rbfIndex = inputWeightCount + ((_inputCount + 1) * i); _rbf[i] = new GaussianFunction(_inputCount, _longTermMemory, rbfIndex); } }
public void ConstructorTest() { // Create a Gaussian function with slope alpha = 4.2 GaussianFunction function = new GaussianFunction(4.2); // Computes the function output (linear, y = alpha * x) double y = function.Function(x: 0.2); // 4.2 * 2 = 0.48 // Draws a sample from a Gaussian distribution with // mean given by the function output y (previously 0.48) double z = function.Generate(x: 0.4); // (random, between 0 and 1) // Please note that the above is completely equivalent // to computing the line below (remember, 0.48 == y) double w = function.Generate2(y: 0.48); // (random, between 0 and 1) // We can also compute the derivative of the sigmoid function double d = function.Derivative(x: 0.2); // 4.2 (the slope) // Or compute the derivative given the functions' output y double e = function.Derivative2(y: 0.2); // 4.2 (the slope) Assert.AreEqual(0.84, y, 1e-7); Assert.AreEqual(4.2, d, 1e-7); Assert.AreEqual(4.2, e, 1e-7); }
public override void Create(int input, int layers, int neurons, int output) { IStochasticFunction function = new GaussianFunction(); //Setup network switch (layers) { case 1: DeepAccordNetwork = new DeepBeliefNetwork(function, input, neurons, output); //Activation function, input, hidden, hidden, output. break; case 2: DeepAccordNetwork = new DeepBeliefNetwork(function, input, neurons, neurons, output); //Activation function, input, hidden, hidden, output. break; case 3: DeepAccordNetwork = new DeepBeliefNetwork(function, input, neurons, neurons, neurons, output); //Activation function, input, hidden, hidden, output. break; case 4: DeepAccordNetwork = new DeepBeliefNetwork(function, input, neurons, neurons, neurons, neurons, output); //Activation function, input, hidden, hidden, output. break; case 5: DeepAccordNetwork = new DeepBeliefNetwork(function, input, neurons, neurons, neurons, neurons, neurons, output); //Activation function, input, hidden, hidden, output. break; } new GaussianWeights(DeepAccordNetwork, 0.1).Randomize(); DeepAccordNetwork.UpdateVisibleWeights(); }
public AnimatedCogsMenu() { const string BUTTON_BACKGROUND_PATH = "Sprites/UI/Menu/buttonBackground"; buttonTexture = GameResources.Content.Load<Texture2D>(BUTTON_BACKGROUND_PATH); isInMenuRoot = true; easingFunction = new GaussianFunction(6f, 3f); const string LARGE_COG_PATH = "Sprites/UI/Menu/largeCog"; const string SMALL_COG_PATH = "Sprites/UI/Menu/smallCog"; const string FONT_PATH = "Fonts/forque"; normalTextColor = Color.Gold; selectedTextColor = Color.White; this.origin = largeCogOrigin; lineSpacing = 100; marginLeft = 200; marginBottom = 300; initialized = true; Font = GameResources.Content.Load<SpriteFont>(FONT_PATH); largeCogTexture = GameResources.Content.Load<Texture2D>(LARGE_COG_PATH); smallCogTexture = GameResources.Content.Load<Texture2D>(SMALL_COG_PATH); SelectNewEntries = SelectMainMenu; easingFunctionArg = 0f; rotatesForward = true; }
public void TestGaussian() { IRadialBasisFunction radial = new GaussianFunction(0.0, 1.0, 1.0); var bubble = new NeighborhoodRBF1D(radial); Assert.AreEqual(0.0, bubble.Function(5, 0), 0.1); Assert.AreEqual(1.0, bubble.Function(5, 5), 0.1); Assert.AreEqual(0.6, bubble.Function(5, 4), 0.1); }
public void TestToString() { double[] ps = { 5, 0, 0, 0 }; var funct = new GaussianFunction(3, ps, 0); double[] x = { -1, 0, 1 }; funct.Evaluate(x); Assert.AreEqual("[GaussianFunction:width=5.00,center=0.00,0.00,0.00]", funct.ToString()); }
public void TestEvaluate() { double[] ps = { 5, 0, 0, 0 }; var funct = new GaussianFunction(3, ps, 0); double[] x = { -1, 0, 1 }; double y = funct.Evaluate(x); Assert.AreEqual(0.9607894391523232, y, AIFH.DefaultPrecision); }
public void TestOther() { double[] ps = { 5, 0, 0, 0 }; var funct = new GaussianFunction(3, ps, 0); Assert.AreEqual(3, funct.Dimensions); funct.SetCenter(0, 100); Assert.AreEqual(100, funct.GetCenter(0), AIFH.DefaultPrecision); funct.Width = 5; Assert.AreEqual(5, funct.Width, AIFH.DefaultPrecision); }
// TODO : Add constant function and trapeziodal private static IFuzzyFunction defineFunction(Match match) { string value = match.Groups[3].Value; string[] functionParameters = match.Groups[4].Value.Split(' '); NumberStyles numberStyles = NumberStyles.AllowParentheses | NumberStyles.AllowTrailingSign | NumberStyles.Float | NumberStyles.AllowThousands | NumberStyles.AllowExponent; if (value == "gaussmf") { GaussianFunction function = new GaussianFunction(); function.Center = Double.Parse(functionParameters[1].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.Steepness = Double.Parse(functionParameters[0].ToUpper(), numberStyles, CultureInfo.InvariantCulture); return(function); } else if (value == "trimf") { TriangleFunction function = new TriangleFunction(); function.LeftPoint = Double.Parse(functionParameters[0].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.MiddlePoint = Double.Parse(functionParameters[1].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.RightPoint = Double.Parse(functionParameters[2].ToUpper(), numberStyles, CultureInfo.InvariantCulture); return(function); } else if (value == "constant") { ConstantFunction function = new ConstantFunction(); function.ConstValue = Double.Parse(functionParameters[0].ToUpper(), numberStyles); return(function); } else if (value == "trapmf") { TrapezoidalFunction function = new TrapezoidalFunction(); function.LeftBottomPoint = Double.Parse(functionParameters[0].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.LeftTopPoint = Double.Parse(functionParameters[1].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.RightTopPoint = Double.Parse(functionParameters[2].ToUpper(), numberStyles, CultureInfo.InvariantCulture); function.RightBottomPoint = Double.Parse(functionParameters[3].ToUpper(), numberStyles, CultureInfo.InvariantCulture); return(function); } else { throw new FuzzyLogicException("Unknown function"); } }
public void Test_RegressionWith_BackwardsEliminationKnnModel() { // Given var randomizer = new Random(55); var baseDataFrame = TestDataBuilder.BuildRandomAbstractNumericDataFrameWithRedundantAttrs(randomizer: randomizer, rowCount: 1000); var queryDataFrame = new DataFrame(new DataTable("some data") { Columns = { new DataColumn("F1", typeof(double)), new DataColumn("F2", typeof(double)), new DataColumn("F3", typeof(double)), new DataColumn("F4", typeof(double)), new DataColumn("F5", typeof(double)) }, Rows = { new object[] { 10, 1, 1, 4, 5 }, new object[] { 4, 2, 1, 9, 10 }, new object[] { 2, 1, 1, 3, 7 }, } }); var expectedValues = Enumerable.Range(0, queryDataFrame.RowCount) .Select( rowIdx => TestDataBuilder.CalcualteLinearlyDependentFeatureValue(queryDataFrame.GetNumericRowVector(rowIdx))).ToList(); var weightingFunction = new GaussianFunction(0.07); var predictor = new SimpleKnnRegressor( new EuclideanDistanceMeasure(), new MinMaxNormalizer(), weightingFunction.GetValue); var modelBuilder = new BackwardsEliminationKnnModelBuilder <double>( new MinMaxNormalizer(), predictor, new MeanSquareError() ); var modelParams = new KnnAdditionalParams(3, true); var errorMeasure = new MeanSquareError(); var subject = new BackwardsEliminationKnnRegressor( new EuclideanDistanceMeasure(), new MinMaxNormalizer(), weightingFunction.GetValue); // When var model = modelBuilder.BuildModel(baseDataFrame, "F6", modelParams); var actualOutcomes = subject.Predict(queryDataFrame, model, "F6"); var mse = errorMeasure.CalculateError(Vector <double> .Build.DenseOfEnumerable(expectedValues), Vector <double> .Build.DenseOfEnumerable(actualOutcomes)); Assert.IsTrue(mse < 0.35); }
/// <summary> /// Creates a Gaussian-Bernoulli network. /// </summary> /// /// <param name="inputsCount">The number of inputs for the network.</param> /// <param name="hiddenNeurons">The number of hidden neurons in each layer.</param> /// public static DeepBeliefNetwork CreateGaussianBernoulli(int inputsCount, params int[] hiddenNeurons) { DeepBeliefNetwork network = new DeepBeliefNetwork(inputsCount, hiddenNeurons); GaussianFunction gaussian = new GaussianFunction(); foreach (StochasticNeuron neuron in network.machines[0].Visible.Neurons) { neuron.ActivationFunction = gaussian; } return(network); }
public NeuralNetwork(int firstLayer, int[] layers, FunctionType func, double sigmoidValue) { IActivationFunction f = null; switch (func) { case FunctionType.BERNOULLI: f = new BernoulliFunction(sigmoidValue); break; case FunctionType.GAUSSIAN: f = new GaussianFunction(sigmoidValue); break; } network = new ActivationNetwork(f, 4, layers); }
public void Test_ClassificationWith_BackwardsEliminationKnnModel() { // Given var randomizer = new Random(55); var data = TestDataBuilder.ReadIrisData(); var trainingDataPercentage = 0.8; int trainingDataCount = (int)(data.RowCount * trainingDataPercentage); var shuffledIndices = data.RowIndices.Shuffle(); var trainingIndices = shuffledIndices.Take(trainingDataCount).ToList(); var testIndices = shuffledIndices.Skip(trainingDataCount).Take(shuffledIndices.Count - trainingDataCount).ToList(); var trainingData = data.GetSubsetByRows(trainingIndices); var testData = data.GetSubsetByRows(testIndices); var weightingFunction = new GaussianFunction(0.07); var predictor = new SimpleKnnClassifier <string>( new EuclideanDistanceMeasure(), new MinMaxNormalizer(), weightingFunction.GetValue); var modelBuilder = new BackwardsEliminationKnnModelBuilder <string>( new MinMaxNormalizer(), predictor, new ClassificationAccuracyError <string>() ); var modelParams = new KnnAdditionalParams(3, true); var errorMeasure = new MeanSquareError(); var subject = new BackwardsEliminationKnnClassifier <string>( new EuclideanDistanceMeasure(), new MinMaxNormalizer(), weightingFunction.GetValue); // When var model = modelBuilder.BuildModel(trainingData, "iris_class", modelParams); var actualResults = subject.Predict(testData, model, "iris_class"); var confusionMatrix = new ConfusionMatrix <string>(testData.GetColumnVector <string>("iris_class"), actualResults); // Then Assert.IsTrue(confusionMatrix.Accuracy >= 0.95); }
public void TestBuildKnnModel() { // Given var randomizer = new Random(55); var baseDataFrame = TestDataBuilder.BuildRandomAbstractNumericDataFrameWithRedundantAttrs(randomizer: randomizer, rowCount: 100); var weightingFunction = new GaussianFunction(0.3); var modelParams = new KnnAdditionalParams(4, true); var predictor = new SimpleKnnRegressor(new EuclideanDistanceMeasure(), new MinMaxNormalizer(), weightingFunction.GetValue); var subject = new BackwardsEliminationKnnModelBuilder <double>( new MinMaxNormalizer(), predictor, new MeanSquareError()); var expectedRemovedFeaturesNames = new[] { "F4" }; // When var model = subject.BuildModel(baseDataFrame, "F6", modelParams) as IBackwardsEliminationKnnModel <double>; // Then Assert.AreEqual(1, model.RemovedFeaturesData.Count); CollectionAssert.AreEquivalent(expectedRemovedFeaturesNames, model.RemovedFeaturesData.Select(f => f.FeatureName)); }
void Solve() { CrowNetP NetP = new CrowNetP(); if (netUP.netType == "som") { #region self organizing maps #region prepare and assign trainingSet.Clear(); int trainVectorDimension = 3; if (trainDataArePoints) { for (int i = 0; i < pointsList.Count; i++) { trainingSet.Add(new TrainingSample(new double[] { pointsList[i].Value.X, pointsList[i].Value.Y, pointsList[i].Value.Z })); } } else { trainVectorDimension = trainingVectorTree.Branches[0].Count; trainingSet = new TrainingSet(trainVectorDimension); for (int i = 0; i < trainingVectorTree.Branches.Count; i++) { double[] values = new double[trainVectorDimension]; for (int j = 0; j < trainVectorDimension; j++) { values[j] = trainingVectorTree.Branches[i][j].Value; } trainingSet.Add(new TrainingSample(values)); } } /// process /// start learning int learningRadius = Math.Max(layerWidth, layerHeight) / 2; INeighborhoodFunction neighborhoodFunction = new GaussianFunction(learningRadius, netUP.neighborDistance) as INeighborhoodFunction; if (neighborhood) { neighborhoodFunction = new MexicanHatFunction(learningRadius) as INeighborhoodFunction; } LatticeTopology topology = LatticeTopology.Rectangular; if (latticeTopology) { topology = LatticeTopology.Hexagonal; } KohonenLayer inputLayer = new KohonenLayer(trainVectorDimension); KohonenLayer outputLayer = new KohonenLayer(new Size(layerWidth, layerHeight), neighborhoodFunction, topology); KohonenConnector connector = new KohonenConnector(inputLayer, outputLayer); connector.Initializer = randomizer; outputLayer.SetLearningRate(learningRate, 0.05d); outputLayer.IsRowCircular = isCircularRows; outputLayer.IsColumnCircular = isCircularColumns; network = new KohonenNetwork(inputLayer, outputLayer); network.useRandomTrainingOrder = opt.UseRandomTraining; #endregion #region delegates network.BeginEpochEvent += new TrainingEpochEventHandler( delegate(object senderNetwork, TrainingEpochEventArgs args) { #region TrainingCycle if (network == null || !GO) { return; } int iPrev = layerWidth - 1; allValuesTree = new GH_Structure <GH_Number>(); for (int i = 0; i < layerWidth; i++) { for (int j = 0; j < layerHeight; j++) { IList <ISynapse> synapses = (network.OutputLayer as KohonenLayer)[i, j].SourceSynapses; double x = synapses[0].Weight; double y = synapses[1].Weight; double z = synapses[2].Weight; for (int k = 0; k < trainVectorDimension; k++) { allValuesTree.Append(new GH_Number(synapses[k].Weight), new GH_Path(i, j)); } rowX[j][i] = x; rowY[j][i] = y; rowZ[j][i] = z; columnX[i][j] = x; columnY[i][j] = y; columnZ[i][j] = z; if (j % 2 == 1) { hexagonalX[i][j] = x; hexagonalY[i][j] = y; hexagonalZ[i][j] = z; } else { hexagonalX[iPrev][j] = x; hexagonalY[iPrev][j] = y; hexagonalZ[iPrev][j] = z; } } iPrev = i; } if (isCircularRows) { for (int i = 0; i < layerHeight; i++) { rowX[i][layerWidth] = rowX[i][0]; rowY[i][layerWidth] = rowY[i][0]; rowZ[i][layerWidth] = rowZ[i][0]; } } if (isCircularColumns) { for (int i = 0; i < layerWidth; i++) { columnX[i][layerHeight] = columnX[i][0]; columnY[i][layerHeight] = columnY[i][0]; columnZ[i][layerHeight] = columnZ[i][0]; hexagonalX[i][layerHeight] = hexagonalX[i][0]; hexagonalY[i][layerHeight] = hexagonalY[i][0]; hexagonalZ[i][layerHeight] = hexagonalZ[i][0]; } } Array.Clear(isWinner, 0, layerHeight * layerWidth); #endregion NetP = new CrowNetP("som", layerWidth, layerHeight, isCircularRows, isCircularColumns, latticeTopology, neighborhood, isWinner, rowX, rowY, rowZ, columnX, columnY, columnZ, hexagonalX, hexagonalY, hexagonalZ, allValuesTree); counter++; }); network.EndSampleEvent += new TrainingSampleEventHandler( delegate(object senderNetwork, TrainingSampleEventArgs args) { isWinner[network.Winner.Coordinate.X, network.Winner.Coordinate.Y] = true; }); #endregion #endregion } network.Learn(trainingSet, cycles); }
void Solve() { #region prepare and assign trainingSet.Clear(); for (int i = 0; i < trainVectorCount; i++) { List <double> dl = new List <double>(); for (int j = 0; j < trainVectorDimension; j++) { dl.Add(trainVectors[i][j]); } trainingSet.Add(new TrainingSample(dl.ToArray())); } /// process /// start learning /// get learning radius for neighborhood function int learningRadius = 0; for (int i = 0; i < dimension; i++) { if (size[i] > learningRadius) { learningRadius = size[i]; } } learningRadius /= 2; INeighborhoodFunction neighborhoodFunction = new GaussianFunction(learningRadius, netUP.neighborDistance) as INeighborhoodFunction; if (neighborhood) { neighborhoodFunction = new MexicanHatFunction(learningRadius) as INeighborhoodFunction; } LatticeTopology topology = LatticeTopology.Rectangular; if (latticeTopology) { topology = LatticeTopology.Hexagonal; } /// instantiate relevant network layers KohonenLayer inputLayer = new KohonenLayer(trainVectorDimension); KohonenLayerND outputLayer = new KohonenLayerND(size, neighborhoodFunction, topology); KohonenConnectorND connector = new KohonenConnectorND(inputLayer, outputLayer, netUP.initialNodes); if (netUP.initialNodes.Length != 0) { connector.Initializer = new GivenInput(netUP.initialNodes); } else { connector.Initializer = new RandomFunction(0.0, 1.0); } outputLayer.SetLearningRate(learningRate, 0.05d); outputLayer.IsDimensionCircular = isDimensionCircular; network = new KohonenNetworkND(inputLayer, outputLayer); network.useRandomTrainingOrder = randomTrainingOrder; inputLayer.ParallelComputation = false; outputLayer.ParallelComputation = parallelComputing; #endregion #region delegates network.BeginEpochEvent += new TrainingEpochEventHandler( delegate(object senderNetwork, TrainingEpochEventArgs args) { #region trainingCylce if (network == null || !GO) { return; } trainedVectors = new double[outputLayer.neuronCount, trainVectorDimension]; for (int i = 0; i < outputLayer.neuronCount; i++) { IList <ISynapse> synapses = (network.OutputLayer as KohonenLayerND)[outputLayer.adressBook[i]].SourceSynapses; for (int j = 0; j < trainVectorDimension; j++) { trainedVectors[i, j] = synapses[j].Weight; } } //make new net here netP = new CrowNetSOMNDP(size, isDimensionCircular, latticeTopology, neighborhood, trainedVectors, outputLayer.adressBook); counter++; #endregion }); network.EndSampleEvent += new TrainingSampleEventHandler( delegate(object senderNetwork, TrainingSampleEventArgs args) { netP.winner = outputLayer.WinnerND.CoordinateND; }); #endregion network.Learn(trainingSet, cycles); }
/// <summary> /// Internal function to increase the neuron count. This will add a /// zero-weight neuron to this layer. /// </summary> /// <param name="layer">The layer to increase.</param> /// <param name="neuronCount">The new neuron count.</param> private void IncreaseNeuronCount(ILayer layer, int neuronCount) { // adjust the bias double[] newBias = new double[neuronCount]; if (layer.HasBias) { for (int i = 0; i < layer.NeuronCount; i++) { newBias[i] = layer.BiasWeights[i]; } layer.BiasWeights = newBias; } // adjust the outbound weight matrixes foreach (ISynapse synapse in layer.Next) { if (synapse.WeightMatrix != null) { Matrix newMatrix = new Matrix(neuronCount, synapse .ToNeuronCount); // copy existing matrix to new matrix for (int row = 0; row < layer.NeuronCount; row++) { for (int col = 0; col < synapse.ToNeuronCount; col++) { newMatrix[row, col] = synapse.WeightMatrix[row, col]; } } synapse.WeightMatrix = newMatrix; } } // adjust the inbound weight matrixes ICollection <ISynapse> inboundSynapses = this.network.Structure .GetPreviousSynapses(layer); foreach (ISynapse synapse in inboundSynapses) { if (synapse.WeightMatrix != null) { Matrix newMatrix = new Matrix(synapse.FromNeuronCount, neuronCount); // copy existing matrix to new matrix for (int row = 0; row < synapse.FromNeuronCount; row++) { for (int col = 0; col < synapse.ToNeuronCount; col++) { newMatrix[row, col] = synapse.WeightMatrix[row, col]; } } synapse.WeightMatrix = newMatrix; } } // adjust the bias if (layer.HasBias) { double[] newBias2 = new double[neuronCount]; for (int i = 0; i < layer.NeuronCount; i++) { newBias2[i] = layer.BiasWeights[i]; } layer.BiasWeights = newBias2; } // adjust RBF if (layer is RadialBasisFunctionLayer) { RadialBasisFunctionLayer rbf = (RadialBasisFunctionLayer)layer; IRadialBasisFunction[] newRBF = new IRadialBasisFunction[neuronCount]; for (int i = 0; i < rbf.RadialBasisFunction.Length; i++) { newRBF[i] = rbf.RadialBasisFunction[i]; } for (int i = rbf.RadialBasisFunction.Length; i < neuronCount; i++) { newRBF[i] = new GaussianFunction(ThreadSafeRandom.NextDouble() - 0.5, ThreadSafeRandom.NextDouble(), ThreadSafeRandom.NextDouble() - 0.5); } rbf.RadialBasisFunction = newRBF; } // finally, up the neuron count layer.NeuronCount = neuronCount; }
/// <summary> /// Prune one of the neurons from this layer. Remove all entries in this /// weight matrix and other layers. /// </summary> /// <param name="targetLayer">The neuron to prune. Zero specifies the first neuron.</param> /// <param name="neuron">The neuron to prune.</param> public void Prune(ILayer targetLayer, int neuron) { // delete a row on this matrix foreach (ISynapse synapse in targetLayer.Next) { if (synapse.WeightMatrix != null) { synapse.WeightMatrix = MatrixMath.DeleteRow(synapse.WeightMatrix, neuron); } } // delete a column on the previous ICollection <ILayer> previous = this.network.Structure .GetPreviousLayers(targetLayer); foreach (ILayer prevLayer in previous) { if (previous != null) { foreach (ISynapse synapse in prevLayer.Next) { if (synapse.WeightMatrix != null) { synapse.WeightMatrix = MatrixMath.DeleteCol(synapse.WeightMatrix, neuron); } } } } // remove the bias if (targetLayer.HasBias) { double[] newBias = new double[targetLayer .NeuronCount - 1]; int targetIndex = 0; for (int i = 0; i < targetLayer.NeuronCount; i++) { if (i != neuron) { newBias[targetIndex++] = targetLayer.BiasWeights[i]; } } targetLayer.BiasWeights = newBias; } // adjust RBF if (targetLayer is RadialBasisFunctionLayer) { RadialBasisFunctionLayer rbf = (RadialBasisFunctionLayer)targetLayer; IRadialBasisFunction[] newRBF = new GaussianFunction[targetLayer .NeuronCount - 1]; int targetIndex = 0; for (int i = 0; i < targetLayer.NeuronCount; i++) { if (i != neuron) { newRBF[targetIndex++] = rbf.RadialBasisFunction[i]; } } rbf.RadialBasisFunction = newRBF; } // update the neuron count targetLayer.NeuronCount -= 1; }