/// <summary> /// Calculate the output of the SOM, for each output neuron. Typically, /// you will use the classify method instead of calling this method. /// </summary> /// <param name="som">The input pattern.</param> /// <param name="input">The output activation of each output neuron.</param> /// <returns></returns> private double[] Compute(SelfOrganizingMap som, double[] input) { var result = new double[som.OutputCount]; var matrixRows = som.Weights.ToRowArrays(); for (var i = 0; i < som.OutputCount; i++) { var optr = matrixRows[i]; Matrix matrixA = DenseMatrix.Create(input.Length, 1, 0); for (var j = 0; j < input.Length; j++) { matrixA[0, j] = input[j]; } Matrix matrixB = DenseMatrix.Create(1, input.Length, 0); for (var j = 0; j < optr.Length; j++) { matrixB[0, j] = optr[j]; } result[i] = VectorAlgebra.DotProduct(matrixA.ToRowArrays()[0], matrixB.ToRowArrays()[0]); } return(result); }
/** * Update the velocity of a particle * * @param particleIndex index of the particle in the swarm */ protected void UpdateVelocity(int particleIndex) { double[] particlePosition = _particles[particleIndex].LongTermMemory; double[] vtmp = new double[particlePosition.Length]; // Standard PSO formula // inertia weight VectorAlgebra.Mul(_velocities[particleIndex], inertiaWeight); // cognitive term VectorAlgebra.Copy(vtmp, _bestVectors[particleIndex]); VectorAlgebra.Sub(vtmp, particlePosition); VectorAlgebra.MulRand(_rnd, vtmp, this.c1); VectorAlgebra.Add(_velocities[particleIndex], vtmp); // social term if (particleIndex != _bestVectorIndex) { VectorAlgebra.Copy(vtmp, _bestVector); VectorAlgebra.Sub(vtmp, particlePosition); VectorAlgebra.MulRand(_rnd, vtmp, c2); VectorAlgebra.Add(_velocities[particleIndex], vtmp); } }
/// <summary> /// Construct PSO trainer. /// </summary> /// <param name="theParticles">The particles to use.</param> /// <param name="theCalculateScore">The score object.</param> public TrainPSO(IMLMethod[] theParticles, IScoreFunction theCalculateScore) { _particles = theParticles; _score = theCalculateScore; int vectorSize = theParticles[0].LongTermMemory.Length; int particleCount = theParticles.Length; _bestVectors = new double[particleCount][]; _velocities = new double[particleCount][]; _bestScores = new double[particleCount]; for (int i = 0; i < particleCount; i++) { _bestVectors[i] = new double[vectorSize]; _velocities[i] = new double[vectorSize]; } _bestVectorIndex = -1; _bestVector = new double[vectorSize]; foreach (double[] velocity in _velocities) { VectorAlgebra.Randomise(_rnd, velocity, this.maxVelocity); } }
/// <summary> /// Update the personal best position of a particle. /// </summary> /// <param name="particleIndex">Index of the particle in the swarm.</param> /// <param name="particlePosition">the particle current position vector.</param> protected void UpdatePersonalBestPosition(int particleIndex, double[] particlePosition) { // set the network weights and biases from the vector double score = _score.CalculateScore(_particles[particleIndex]); // update the best vectors (g and i) if ((_bestScores[particleIndex] == 0) || IsScoreBetter(score, _bestScores[particleIndex])) { _bestScores[particleIndex] = score; VectorAlgebra.Copy(_bestVectors[particleIndex], particlePosition); } }
/// <summary> /// Update the swarm's best position. /// </summary> protected void UpdateGlobalBestPosition() { bool bestUpdated = false; for (int i = 0; i < this._particles.Length; i++) { if ((_bestVectorIndex == -1) || IsScoreBetter(_bestScores[i], _bestScores[_bestVectorIndex])) { _bestVectorIndex = i; bestUpdated = true; } } if (bestUpdated) { VectorAlgebra.Copy(_bestVector, _bestVectors[_bestVectorIndex]); this.bestScore = _bestScores[_bestVectorIndex]; } }
/// <summary> /// Update the velocity, position and personal /// best position of a particle. /// </summary> /// <param name="particleIndex">index of the particle in the swarm</param> protected void UpdateParticle(int particleIndex) { double[] particlePosition = _particles[particleIndex].LongTermMemory; UpdateVelocity(particleIndex); // velocity clamping VectorAlgebra.ClampComponents(_velocities[particleIndex], maxVelocity); // new position (Xt = Xt-1 + Vt) VectorAlgebra.Add(particlePosition, _velocities[particleIndex]); // pin the particle against the boundary of the search space. // (only for the components exceeding maxPosition) VectorAlgebra.ClampComponents(particlePosition, maxPosition); UpdatePersonalBestPosition(particleIndex, particlePosition); }
/// <summary> /// Constructor. /// </summary> /// <param name="network">an initialised Encog network. /// The networks in the swarm will be created with /// the same topology as this network.</param> /// <param name="randomizer">any type of Encog network weight initialisation /// object.</param> /// <param name="calculateScore">any type of Encog network scoring/fitness object.</param> /// <param name="populationSize">the swarm size.</param> public NeuralPSO(BasicNetwork network, IRandomizer randomizer, ICalculateScore calculateScore, int populationSize) : base(TrainingImplementationType.Iterative) { // initialisation of the member variables m_populationSize = populationSize; m_randomizer = randomizer; m_calculateScore = calculateScore; m_bestNetwork = network; m_networks = new BasicNetwork[m_populationSize]; m_velocities = null; m_bestVectors = new double[m_populationSize][]; m_bestErrors = new double[m_populationSize]; m_bestVectorIndex = -1; // get a vector from the network. m_bestVector = NetworkCODEC.NetworkToArray(m_bestNetwork); m_va = new VectorAlgebra(); }