our_knp/examples/examples/mnist-learn/training.h
int 8f43927575 Initial import: KNP experiments (examples, viz, cats-dogs, reports)
examples/ is based on KasperskyLab/knp at 55470ed6 with local changes
to the mnist-learn altai/blifat models, cuda-backend CMake and model_loader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:17:15 +03:00

207 lines
9.3 KiB
C++

/**
* @file training.h
* @brief Functions for training.
* @kaspersky_support A. Vartenkov
* @date 24.03.2025
* @license Apache 2.0
* @copyright © 2025-2026 AO Kaspersky Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <knp/framework/model_executor.h>
#include <knp/framework/monitoring/model.h>
#include <knp/framework/projection/wta.h>
#include <knp/framework/tags/name.h>
#include <map>
#include <memory>
#include <filesystem>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include "annotated_network.h"
#include "dataset.h"
#include "global_config.h"
#include "models/altai/network_functions.h"
#include "models/blifat/network_functions.h"
/**
* @brief Build input channel map for training operations.
*
* @details This function configures the input and output channels required for training by setting up spike generators
* for image data and labels, and establishing the necessary connections between network components.
*
* @tparam Neuron neuron type for neuron model specification.
*
* @param network annotated network structure containing network and annotations.
* @param model model.
* @param dataset dataset containing training data and configuration.
*
* @return channel map containing configured input channels for training.
*/
template <typename Neuron>
knp::framework::ModelLoader::InputChannelMap build_channel_map_train(
const AnnotatedNetwork& network, knp::framework::Model& model, const Dataset& dataset)
{
// Create random unique identifiers for input and output channels.
knp::core::UID input_image_channel_raster;
knp::core::UID input_image_channel_classes;
knp::core::UID output_channel;
// Connect rasterized image projections to input channel for image data.
for (auto image_proj_uid : network.data_.projections_from_raster_)
model.add_input_channel(input_image_channel_raster, image_proj_uid);
// Connect class label projections to input channel for target labels.
for (auto target_proj_uid : network.data_.projections_from_classes_)
model.add_input_channel(input_image_channel_classes, target_proj_uid);
// Connect output populations to output channel for results.
for (auto out_pop : network.data_.output_uids_) model.add_output_channel(output_channel, out_pop);
// Create and populate channel map for model execution.
// Online Help link: https://click.kaspersky.com/?hl=en-US&version=2.0&pid=KNP&link=online_help&helpid=276672
knp::framework::ModelLoader::InputChannelMap channel_map;
channel_map.insert({input_image_channel_raster, dataset.make_training_images_spikes_generator()});
channel_map.insert({input_image_channel_classes, make_training_labels_spikes_generator<Neuron>(dataset)});
return channel_map;
}
/**
* @brief Train neural network on the provided dataset.
*
* @details This function executes the complete training process for a neural network, including model initialization,
* training execution, and comprehensive monitoring. It handles the configuration of input and output channels,
* logging, and progress tracking.
*
* @tparam Neuron neuron type for neuron model specification.
*
* @param backend shared pointer to the computational backend for training execution.
* @param network annotated network structure containing the network and its annotations.
* @param model_desc model description containing configuration parameters and paths.
* @param dataset dataset containing training data and timing specifications.
*/
template <typename Neuron>
void train_network(
const std::shared_ptr<knp::core::Backend>& backend, AnnotatedNetwork& network, const ModelDescription& model_desc,
const Dataset& dataset)
{
// Store population names for logging and debugging purposes.
std::map<knp::core::UID, std::string> pop_names;
for (const auto& pop : network.network_.get_populations())
std::visit(
[&pop_names](const auto& pop) { pop_names[pop.get_uid()] = knp::framework::tags::get_name(pop); }, pop);
// Create model from annotated network structure.
// Online Help link: https://click.kaspersky.com/?hl=en-US&version=2.0&pid=KNP&link=online_help&helpid=235849
knp::framework::Model model(std::move(network.network_));
// Build channel map for training operations with proper input and output connections.
knp::framework::ModelLoader::InputChannelMap channel_map = build_channel_map_train<Neuron>(network, model, dataset);
// Initialize model executor with backend and channel map for execution.
// Online Help link: https://click.kaspersky.com/?hl=en-US&version=2.0&pid=KNP&link=online_help&helpid=251296
knp::framework::ModelExecutor model_executor(model, backend, std::move(channel_map));
// Add status logger to monitor training progress and system state
// Online Help link: https://click.kaspersky.com/?hl=en-US&version=2.0&pid=KNP&link=online_help&helpid=260375
knp::framework::monitoring::model::add_status_logger(model_executor, model, std::cout, 1);
// Initialize logging streams and accumulators for detailed monitoring.
// All these variables should have the same lifetime as model_executor.
std::ofstream log_stream, weight_stream;
// cppcheck-suppress variableScope
std::map<std::string, size_t> spike_accumulator;
// Configure WTA (Winner-Take-All) handlers for competitive learning mechanisms.
// Online Help link: https://click.kaspersky.com/?hl=en-US&version=2.0&pid=KNP&link=online_help&helpid=301132
std::vector<knp::core::UID> wta_uids = knp::framework::projection::add_wta_handlers(
model_executor, wta_winners_amount, network.data_.wta_borders_, network.data_.wta_data_);
// Register WTA populations for logging to track competitive behavior.
for (auto const& uid : wta_uids) pop_names[uid] = "WTA";
// Add real-time spike logger for console output during training.
knp::framework::monitoring::model::add_spikes_logger(model_executor, pop_names, std::cout);
// Setup detailed logging infrastructure if enabled in configuration.
if (!model_desc.log_path_.empty())
{
// Create logging directory structure if it doesn't exist.
std::filesystem::create_directories(model_desc.log_path_);
// Setup aggregated spikes logging for detailed analysis.
log_stream.open(model_desc.log_path_ / "spikes_training.csv", std::ofstream::out);
if (log_stream.is_open())
knp::framework::monitoring::model::add_aggregated_spikes_logger(
model, pop_names, model_executor, spike_accumulator, log_stream, aggregated_spikes_logging_period);
else
std::cout << "Couldn't open spikes_training.csv at " << model_desc.log_path_ << std::endl;
// Setup weight logging for tracking synaptic changes during training.
weight_stream.open(model_desc.log_path_ / "weights.log", std::ofstream::out);
if (weight_stream.is_open())
knp::framework::monitoring::model::add_projection_weights_logger(
weight_stream, model_executor, network.data_.projections_from_raster_[0],
projection_weights_logging_period);
else
std::cout << "Couldn't open weights.csv at " << model_desc.log_path_ << std::endl;
}
// Execute training simulation with progress reporting.
model_executor.start(
[&dataset](size_t step)
{
if (step % 20 == 0) std::cout << "Step: " << step << std::endl;
return step != dataset.get_steps_amount_for_training();
});
}
/**
* @brief Train neural network model and prepare for inference.
*
* @details This function orchestrates the complete training workflow, including backend loading, network training, and
* post-training preparation for inference operations. It provides a high-level interface for executing the full training
* pipeline.
*
* @tparam Neuron neuron type for neuron model specification.
*
* @param model_desc model description containing configuration parameters and paths.
* @param dataset dataset containing training data and timing specifications.
* @param network annotated network structure containing the network and its annotations.
* @param backend_loader backend loader for loading the training backend.
*/
template <typename Neuron>
void train_model(
const ModelDescription& model_desc, const Dataset& dataset, AnnotatedNetwork& network,
knp::framework::BackendLoader& backend_loader)
{
// Load training backend for computational execution.
std::shared_ptr<knp::core::Backend> training_backend = backend_loader.load(model_desc.training_backend_path_);
// Execute the complete training process with the loaded backend.
train_network<Neuron>(training_backend, network, model_desc, dataset);
// Prepare the trained network for inference operations.
prepare_network_for_inference<Neuron>(training_backend, model_desc, network);
}