/
moshroom_edu
/
evolution
Обзор
Документация
Войти
/
moshroom_edu
/
evolution
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
src/neruo_engine/neurone.cpp
301 строка
7 KB
mushroom
resurrection
21 май 2026, 17:18
21 май 2026, 17:18
4d88a97
Код
Авторство
О чём код?
#include "neuro_engine/neurone.h" #include "neuro_engine/ann.h" #include "logger.h" #include "defines.h" #include <assert.h> #include <map> #include <iomanip> namespace n_engine { const std::vector<link> & neurone::links() const { return m_links; } void neurone::copy(const neurone &r) { m_links = r.m_links; m_value = r.m_value; } void neurone::mutate_weights(ulli mutation_percent, double delta) { double temp_x = (static_cast<double>(m_links.size()) / 100 * mutation_percent); ulli x = static_cast<ulli>(std::round(temp_x)); std::map<ulli, bool> mutated; for(ulli i = 0; i < x ; ++i) { ulli index ; do { index = static_cast<ulli>(rand()) % m_links.size(); } while(mutated.find(index) != mutated.end()); double rand_delta = static_cast<double>(((rand() % 2001) - 1000))/1000 ; rand_delta = delta * (rand_delta > 0 ? 1 : -1); m_links[index].mutate(rand_delta); } } void neurone::neuro_love(const neurone &p1, const neurone &p2) { assert(p1.m_links.size() == p2.m_links.size() && m_links.size() == p1.m_links.size()); const size_t l_size = m_links.size(); for(size_t li = 0; li < l_size; ++li) { const auto & p1l = p1.m_links[li]; const auto & p2l = p2.m_links[li]; auto & ml = m_links[li]; assert(p1l.m_out_neurone_layer == p2l.m_out_neurone_layer && p1l.m_out_neurone_index == p2l.m_out_neurone_index && ml.m_out_neurone_layer == p1l.m_out_neurone_layer && ml.m_out_neurone_index == p1l.m_out_neurone_index); ml.m_weight = (rand() % 2001) > 1000 ? p2l.m_weight : p1l.m_weight; } } void neurone::optimize(double optimize_param) { assert(m_reccurent); auto it = m_links.begin(); while(it != m_links.end()) { if(std::fabs(it->m_weight) < optimize_param) { it = m_links.erase(it); continue; } ++it; } } void neurone::mutate_struct(ulli mutation_percent, double optimize_param) { assert(m_reccurent); double d_x = static_cast<double>(m_links.size()) / 100.0 * mutation_percent; ulli x = static_cast<ulli>(std::round(d_x)); optimize(optimize_param); links_recurent(static_cast<ulli>(rand()) % (x ? x : 1)); } void neurone::serialize(std::string &state) const { state += std::to_string(m_links.size()) + ";"; for(const auto & l:m_links) { std::stringstream ss; ss << std::setprecision(16); ss << l.m_out_neurone_layer << ";"; ss << l.m_out_neurone_index << ";"; ss << l.m_weight << ";"; state += ss.str(); } } ulli neurone::deserialize(const std::string & buffer) { std::vector<std::string> data; m_links.clear(); slice(data, buffer, ';'); auto it = data.begin(); ulli res = std::stoull(it->c_str()); if(!res) return 0; it++; auto end = --data.end(); while(it != end) { ulli layer = std::stoull(it->c_str()); ++it; ulli neurone = std::stoull(it->c_str()); ++it; double weight = std::stod(it->c_str()); ++it; m_links.emplace_back(layer, neurone, false); m_links.back().m_weight = weight; } return res; } void neurone::links_forward(ulli number) { const auto & layers = m_ann->layers(); assert(m_layer != layers.size()-1); ulli temp = layers[m_layer + 1].size(); ulli offset = m_links.size(); if( temp < number) number = temp; m_links.reserve(number); for (ulli i = 0; i < number; ++i) { m_links.push_back(link(m_layer+1, i + offset, true)); } } bool is_exists(const std::map<ulli, std::map<ulli, bool>> & indexes, ulli layer, ulli index) { auto _layer = indexes.find(layer); if(_layer == indexes.end()) { return false; } auto _index = _layer->second.find(index); return _index != _layer->second.end(); } void neurone::links_recurent(ulli number) { links_forward(number); if(!m_layer) return; const auto & layers = m_ann->layers(); if(m_layer == layers.size()-1) return; ulli layer; layer = m_layer; const n_engine::layer & my_layer = layers[layer]; number = my_layer.size(); for(ulli i = 0; i < number; ++i) { m_links.push_back(link(layer, i, true)); } } void neurone::propagation() { // Fucking shit! It's been wrong! if(m_links.size() == 0) { return; } auto & layers = m_ann->layers(); lli count_of_forward = static_cast<lli>(layers[m_layer + 1].size()); const auto link_end = m_links.begin() + count_of_forward; for(auto _link = m_links.begin(); _link != link_end; ++_link) { layers[_link->m_out_neurone_layer] [_link->m_out_neurone_index].inc_input( m_value * _link->m_weight); } } void neurone::reccurent_propagation() { if(m_links.size() == 0) { return; } auto & layers = m_ann->layers(); auto begin = m_links.begin() + static_cast<lli>(layers[m_layer+1].size()); auto end = m_links.end(); // lli temp = std::distance(begin, end); //assert(temp == static_cast<lli>(layers[m_layer].size())); for(auto _link = begin; _link != end; ++_link) { layers[_link->m_out_neurone_layer] [_link->m_out_neurone_index].inc_input( m_value * _link->m_weight); } } neurone::neurone( ann *network, bool prop_type, ulli index, ulli layer, activation_type type ) : m_index(index), m_layer(layer), m_type(type), m_ann(network), m_reccurent(prop_type) { } bool neurone::operator ==(const neurone &r) const { return m_links == r.m_links; } void neurone::init_links(ulli number) { if(m_reccurent) { links_recurent(number); } else { links_forward(number); } } void neurone::activate() { switch (m_type) { case activation_type::sigmoid : { m_value = sigmoid(m_input); break; } case activation_type::tanh : { m_value = tanh(m_input); break; } case activation_type::relu : { m_value = relu(m_input); break; } case activation_type::percepto_tanh : m_value = percepto_tanh(m_input); break; case activation_type::bias : m_value = 1.0; } m_input = 0.0; propagation(); } void neurone::inc_input(double xw) { m_input += xw; } void neurone::set_type(const activation_type &type) { m_type = type; } } //namespace n_engine