NeuralNetwork::NeuralNetwork(const NeuralNetworkTopology& topology) : m_topology(topology) { unsigned int prev_layer_num_neuron = m_topology.getInput(); m_layerHidden.resize( m_topology.getHiddens().size() ); for (unsigned int i = 0; i < m_layerHidden.size(); ++i) { t_layer& layer = m_layerHidden[i]; layer.resize( m_topology.getHiddens()[i] ); for (t_neuron& neuron : layer) { neuron.m_weights.resize( prev_layer_num_neuron ); for (float& weight : neuron.m_weights) weight = randomClamped(); } prev_layer_num_neuron = m_topology.getHiddens()[i]; } m_layerOutput.resize( m_topology.getOutput() ); for (t_neuron& neuron : m_layerOutput) { neuron.m_weights.resize( prev_layer_num_neuron ); for (float& weight : neuron.m_weights) weight = randomClamped(); } }
Neuron::Neuron(int newNumInputs): numInputs(newNumInputs+1){ //Need an additional weight for the bias for (int i=0; i<newNumInputs+1;i++){ //Set up weights with a random initial value vecWeight.push_back(randomClamped()); } }
void GeneticAlgorithm::mutate(t_genome& genome) const { int total_mutated = 0; for (float& weight : genome.m_weights) if (randomFloat() < 0.1f) { weight += (randomClamped() * 0.2f); ++total_mutated; } // D_MYLOG("total_mutated=" << ((float)total_mutated / genome.m_weights.size()) * 100); }
void GeneticAlgorithm::BreedPopulation() { // D_MYLOG("step"); if (m_genomes.empty()) return; std::vector<t_genome> bestGenomes; getBestGenomes(10, bestGenomes); // D_MYLOG("current_best=" << bestGenomes[0].m_fitness); // D_MYLOG("step"); // for (t_genome& g : bestGenomes) // D_MYLOG("g=" << g.m_id); std::vector<t_genome> children; children.reserve( m_genomes.size() ); // m_best_fitness = std::max(m_best_fitness, bestGenomes[0].m_fitness); if (m_best_fitness < bestGenomes[0].m_fitness) { m_best_fitness = bestGenomes[0].m_fitness; D_MYLOG("m_current_generation=" << m_current_generation << std::fixed << ", m_best_fitness=" << m_best_fitness); m_is_a_great_generation = true; } else { m_is_a_great_generation = false; } unsigned int current_index = 0; if (m_best_fitness > m_alpha_genome.m_fitness) { m_alpha_genome = bestGenomes[0]; // D_MYLOG("new alpha"); } else { t_genome bestDude; bestDude.m_fitness = 0.0f; bestDude.m_id = m_alpha_genome.m_id; bestDude.m_weights = m_alpha_genome.m_weights; bestDude.m_index = current_index++; mutate(bestDude); children.push_back(bestDude); // D_MYLOG("alpha reused"); } { // Carry on the best dude. t_genome bestDude; bestDude.m_fitness = 0.0f; bestDude.m_id = bestGenomes[0].m_id; bestDude.m_weights = bestGenomes[0].m_weights; bestDude.m_index = current_index++; mutate(bestDude); children.push_back(bestDude); } // D_MYLOG("step"); // breed best genomes for (unsigned int i = 0; i < bestGenomes.size(); ++i) for (unsigned int j = i+1; j < bestGenomes.size(); ++j) { // D_MYLOG("i=" << i << ", j=" << j); t_genome baby1, baby2; CrossBreed(bestGenomes[i], bestGenomes[j], baby1, baby2); mutate(baby1); mutate(baby2); baby1.m_index = current_index++; baby2.m_index = current_index++; children.push_back(baby1); children.push_back(baby2); } // D_MYLOG("step"); // For the remainding n population, add some random kiddies. unsigned int remainingChildren = (m_genomes.size() - children.size()); // D_MYLOG("step m_genomes.size()" << m_genomes.size()); // D_MYLOG("step children.size()" << children.size()); // D_MYLOG("step remainingChildren" << remainingChildren); for (unsigned int i = 0; i < remainingChildren; i++) { t_genome genome; genome.m_id = m_current_id++; genome.m_fitness = 0.0f; genome.m_weights.resize( m_pNNTopology->getTotalWeights() ); for (float& weight : genome.m_weights) weight = randomClamped(); genome.m_index = current_index++; children.push_back( genome ); } // D_MYLOG("step"); m_genomes = children; ++m_current_generation; // D_MYLOG("/step"); for (unsigned int i = 0; i < m_genomes.size(); ++i) m_NNetworks[i].setWeights( m_genomes[i].m_weights ); }
void GeneticAlgorithm::generateRandomPopulation() { std::vector<unsigned int> tmp_hidden; // tmp_hidden.push_back(8); tmp_hidden.push_back(4); tmp_hidden.push_back(3); // tmp_hidden.push_back(7); // tmp_hidden.push_back(7); // tmp_hidden.push_back(7); // tmp_hidden.push_back(6); // tmp_hidden.push_back(7); // tmp_hidden.push_back(7); // tmp_hidden.push_back(7); // tmp_hidden.push_back(6); // tmp_hidden.push_back(5); // tmp_hidden.push_back(4); // tmp_hidden.push_back(4); // tmp_hidden.push_back(3); m_pNNTopology = t_pNNTopology(new NeuralNetworkTopology(5, tmp_hidden, 2)); // reset the genomes m_genomes.resize(100); for (unsigned int i = 0; i < m_genomes.size(); ++i) { t_genome& genome = m_genomes[i]; genome.m_index = i; genome.m_id = m_current_id++; genome.m_fitness = 0.0f; genome.m_weights.resize( m_pNNTopology->getTotalWeights() ); for (float& weight : genome.m_weights) weight = randomClamped(); } m_NNetworks.reserve( m_genomes.size() ); for (unsigned int i = 0; i < m_genomes.size(); ++i) { m_NNetworks.push_back( NeuralNetwork(*m_pNNTopology) ); m_NNetworks[i].setWeights( m_genomes[i].m_weights ); } m_current_generation = 1; m_best_fitness = 0.0f; m_alpha_genome.m_index = -1; m_alpha_genome.m_id = -1; m_alpha_genome.m_fitness = 0.0f; }