Skip to content

Commit 1359348

Browse files
committed
Added dataset max size. Removed redundant code: KasperskyLab#123
1 parent 65108bc commit 1359348

10 files changed

Lines changed: 35 additions & 69 deletions

File tree

examples/mnist-learn/altai/construct_network.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ auto add_subnetwork_populations(AnnotatedNetwork &result)
108108
};
109109
//
110110
std::vector<PopulationRole> pop_data{
111-
{{10 * neurons_per_column, l_neuron}, true, false, "L"},
112-
{{10, default_neuron}, true, true, "OUT"},
113-
{{10, default_neuron}, false, false, "BIAS"}};
111+
{{classes_amount * neurons_per_column, l_neuron}, true, false, "L"},
112+
{{classes_amount, default_neuron}, true, true, "OUT"},
113+
{{classes_amount, default_neuron}, false, false, "BIAS"}};
114114

115115
std::vector<knp::core::UID> population_uids;
116116
for (auto &pop_init_data : pop_data)
@@ -163,7 +163,7 @@ AnnotatedNetwork create_example_network(int num_compound_networks)
163163
TARGET_to_L_synapse.delay_ = 3;
164164

165165
DeltaProjection TARGET_to_L_projection = knp::framework::projection::creators::aligned<DeltaSynapse>(
166-
knp::core::UID(false), population_uids[L], 10, pop_data[L].pd_.size_,
166+
knp::core::UID(false), population_uids[L], classes_amount, pop_data[L].pd_.size_,
167167
[&TARGET_to_L_synapse](size_t, size_t) { return TARGET_to_L_synapse; });
168168
result.network_.add_projection(TARGET_to_L_projection);
169169
result.data_.projections_from_classes_.push_back(TARGET_to_L_projection.get_uid());
@@ -175,7 +175,7 @@ AnnotatedNetwork create_example_network(int num_compound_networks)
175175
TARGET_to_L_synapse2.delay_ = 4;
176176

177177
DeltaProjection TARGET_to_L_projection2 = knp::framework::projection::creators::all_to_all<DeltaSynapse>(
178-
knp::core::UID(false), population_uids[L], 10, pop_data[L].pd_.size_,
178+
knp::core::UID(false), population_uids[L], classes_amount, pop_data[L].pd_.size_,
179179
[&TARGET_to_L_synapse2](size_t, size_t) { return TARGET_to_L_synapse2; });
180180
result.network_.add_projection(TARGET_to_L_projection2);
181181
result.data_.projections_from_classes_.push_back(TARGET_to_L_projection2.get_uid());
@@ -186,7 +186,7 @@ AnnotatedNetwork create_example_network(int num_compound_networks)
186186
TARGET_to_BIAS_synapse.weight_ = 10 * scale;
187187

188188
DeltaProjection TARGET_to_BIAS_projection = knp::framework::projection::creators::aligned<DeltaSynapse>(
189-
knp::core::UID(false), population_uids[BIAS], 10, pop_data[BIAS].pd_.size_,
189+
knp::core::UID(false), population_uids[BIAS], classes_amount, pop_data[BIAS].pd_.size_,
190190
[&TARGET_to_BIAS_synapse](size_t, size_t) { return TARGET_to_BIAS_synapse; });
191191
result.network_.add_projection(TARGET_to_BIAS_projection);
192192
result.data_.projections_from_classes_.push_back(TARGET_to_BIAS_projection.get_uid());

examples/mnist-learn/altai/inference.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ std::vector<knp::core::messaging::SpikeMessage> run_mnist_inference(
8383
std::vector<knp::core::UID> wta_uids;
8484
{
8585
std::vector<size_t> wta_borders;
86-
for (size_t i = 0; i < num_possible_labels; ++i) wta_borders.push_back(neurons_per_column * (i + 1));
86+
for (size_t i = 0; i < classes_amount; ++i) wta_borders.push_back(neurons_per_column * (i + 1));
8787
wta_uids = knp::framework::projection::add_wta_handlers(
8888
model_executor, wta_winners_amount, wta_borders, described_network.data_.wta_data_);
8989
}

examples/mnist-learn/altai/main.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
#include "time_string.h"
3333
#include "train.h"
3434

35-
constexpr float state_increment_factor = 1.f / 255;
36-
constexpr size_t classes_amount = 10;
37-
3835
namespace data_processing = knp::framework::data_processing::classification::images;
3936
namespace inference_evaluation = knp::framework::inference_evaluation::classification;
4037

@@ -63,8 +60,8 @@ int main(int argc, char** argv)
6360

6461
data_processing::Dataset dataset;
6562
dataset.process_labels_and_images(
66-
images_stream, labels_stream, images_amount_to_train, classes_amount, input_size, steps_per_image,
67-
dataset.make_incrementing_image_to_spikes_converter(active_steps, state_increment_factor));
63+
images_stream, labels_stream, images_amount_to_train + images_amount_for_inference, classes_amount, input_size,
64+
steps_per_image, dataset.make_incrementing_image_to_spikes_converter(active_steps, state_increment_factor));
6865
dataset.split(images_amount_to_train, images_amount_for_inference);
6966

7067
std::cout << "Processed dataset, training will last " << dataset.get_steps_required_for_training()

examples/mnist-learn/altai/shared_network.h

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,14 @@
2626
#include <knp/synapse-traits/all_traits.h>
2727

2828
// Network hyperparameters. You may want to fine-tune these.
29-
/*
30-
constexpr float default_threshold = 8.571F;
31-
constexpr float min_synaptic_weight = -0.7;
32-
constexpr float max_synaptic_weight = 0.864249F;
33-
constexpr float base_weight_value = 0.000F;
34-
constexpr int neuron_dopamine_period = 10;
35-
constexpr int synapse_dopamine_period = 10;
36-
constexpr float l_neuron_potential_leak = 1.0 - 1.0 / 3.0;
37-
constexpr float dopamine_parameter = 0.042F;
38-
constexpr float dopamine_value = dopamine_parameter;
39-
constexpr float threshold_weight_coeff = 0.023817F;
40-
*/
41-
42-
//
43-
// Network geometry.
44-
//
4529

4630
// Number of neurons reserved per a single digit.
47-
// constexpr size_t neurons_per_column = 15;
31+
constexpr size_t neurons_per_column = 20;
4832

49-
// Ten possible digits, one column per each.
50-
constexpr size_t num_possible_labels = 10;
33+
// Ten possible digits, one column for each one.
34+
constexpr size_t classes_amount = 10;
5135

52-
// All columns are a part of the same population.
53-
// constexpr size_t num_input_neurons = neurons_per_column * num_possible_labels;
36+
constexpr float state_increment_factor = 1.f / 255;
5437

5538
// Number of pixels in width for a single MNIST image.
5639
constexpr size_t input_size_width = 28;
@@ -67,10 +50,5 @@ constexpr size_t steps_per_image = 15;
6750
/// How many subnetworks to use.
6851
constexpr size_t num_subnetworks = 1;
6952

70-
constexpr size_t neurons_per_column = 20;
71-
7253
// Number of pixels for a single MNIST image.
7354
constexpr size_t input_size = input_size_width * input_size_height;
74-
75-
// Dense input projection from 28 * 28 image to population of 150 neurons.
76-
// constexpr size_t input_projection_size = input_size * num_input_neurons;

examples/mnist-learn/altai/train.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ AnnotatedNetwork train_mnist_network(
131131
std::vector<knp::core::UID> wta_uids;
132132
{
133133
std::vector<size_t> wta_borders;
134-
for (size_t i = 0; i < num_possible_labels; ++i) wta_borders.push_back(neurons_per_column * (i + 1));
134+
for (size_t i = 0; i < classes_amount; ++i) wta_borders.push_back(neurons_per_column * (i + 1));
135135
wta_uids = knp::framework::projection::add_wta_handlers(
136136
model_executor, wta_winners_amount, wta_borders, example_network.data_.wta_data_);
137137
}

knp/base-framework/impl/data_processing/classification/dataset.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void Dataset::split(size_t frames_for_training, size_t frames_for_inference)
3434
SPDLOG_ERROR(
3535
"Incorrect split size. Dataset is too small. Required {} frames for training, and {} frames for inference, "
3636
"while dataset only have {} frames.",
37-
frames_for_training, frames_for_training, data_for_training_.size());
37+
frames_for_training, frames_for_inference, data_for_training_.size());
3838
throw std::runtime_error("Dataset too small.");
3939
}
4040

knp/base-framework/impl/data_processing/classification/image.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@ namespace knp::framework::data_processing::classification::images
2626
{
2727

2828
void Dataset::process_labels_and_images(
29-
std::istream &images_stream, std::istream &labels_stream, size_t training_amount, size_t classes_amount,
29+
std::istream &images_stream, std::istream &labels_stream, size_t max_images_amount, size_t classes_amount,
3030
size_t image_size, size_t steps_per_image,
3131
std::function<Frame(std::vector<uint8_t> const &)> const &image_to_spikes)
3232
{
3333
image_size_ = image_size;
3434
steps_per_frame_ = steps_per_image;
35-
required_training_amount_ = training_amount;
3635
classes_amount_ = classes_amount;
3736

3837
std::vector<uint8_t> image_reading_buffer(image_size, 0);
3938

39+
data_for_training_.reserve(max_images_amount);
40+
4041
while (images_stream.good() && labels_stream.good())
4142
{
4243
images_stream.read(reinterpret_cast<char *>(image_reading_buffer.data()), image_size);
@@ -48,6 +49,8 @@ void Dataset::process_labels_and_images(
4849

4950
// Push to training data set because we dont know dataset size yet for a split
5051
data_for_training_.push_back({label, std::move(spikes_frame)});
52+
53+
if (data_for_training_.size() == max_images_amount) break;
5154
}
5255
}
5356

knp/base-framework/include/knp/framework/data_processing/classification/dataset.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,6 @@ class KNP_DECLSPEC Dataset
129129
*/
130130
[[nodiscard]] inline size_t get_steps_required_for_inference() const { return steps_required_for_inference_; }
131131

132-
/**
133-
* @brief Get the user-specified amount of training data required.
134-
* @return required training amount, which may affect the allocation of data for inference.
135-
*/
136-
[[nodiscard]] inline size_t get_required_training_amount() const { return required_training_amount_; }
137-
138132
/**
139133
* @brief Get the number of classes in the dataset.
140134
* @return number of classes.
@@ -190,13 +184,6 @@ class KNP_DECLSPEC Dataset
190184
*/
191185
size_t steps_required_for_inference_ = 0;
192186

193-
/**
194-
* @brief User-specified amount of training data required.
195-
* @note If this value is less than the actual size of @ref data_for_training_, the @ref split function adjusts the
196-
* inference data accordingly.
197-
*/
198-
size_t required_training_amount_ = 0;
199-
200187
/**
201188
* @brief Number of classes in the dataset.
202189
*/

knp/base-framework/include/knp/framework/data_processing/classification/image.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,52 +46,54 @@ class KNP_DECLSPEC Dataset final : public classification::Dataset
4646
* @brief Process labels and images, converting the images to spike form and creating data pairs.
4747
* @param images_stream stream containing the raw image data.
4848
* @param labels_stream stream containing the corresponding labels.
49-
* @param training_amount desired number of images to use for training.
49+
* @param max_images_amount maximum amount of images that should be processed.
5050
* @param classes_amount total number of classes in the dataset.
5151
* @param image_size size of each image in bytes.
5252
* @param steps_per_image number of steps required to transmit an image in spike form to a model.
5353
* @param image_to_spikes function that converts raw image data to spike form, returning a `Frame` object.
54-
* @details This method reads images and labels from the provided streams, converts each image to spike form
55-
* using the provided converter function, and creates data pairs consisting of the label and spike frame.
54+
* @details This method reads images and labels from the provided streams, converts each image to spike form
55+
* using the provided converter function, and creates data pairs consisting of the label and spike frame.
5656
* The data pairs are added to the training dataset.
5757
*/
5858
void process_labels_and_images(
59-
std::istream &images_stream, std::istream &labels_stream, size_t training_amount, size_t classes_amount,
59+
std::istream &images_stream, std::istream &labels_stream, size_t max_images_amount, size_t classes_amount,
6060
size_t image_size, size_t steps_per_image,
6161
std::function<Frame(std::vector<uint8_t> const &)> const &image_to_spikes);
6262

6363
/**
6464
* @brief Create a generator that produces spike data from training labels.
6565
* @return functor for generating spikes from training labels.
66-
* @details The generated spike data is created by iterating over the training labels in a loop, with each label repeated at regular intervals.
66+
* @details The generated spike data is created by iterating over the training labels in a loop, with each label
67+
* repeated at regular intervals.
6768
*/
6869
[[nodiscard]] std::function<knp::core::messaging::SpikeData(knp::core::Step)> make_training_labels_generator()
6970
const;
7071

7172
/**
7273
* @brief Create a generator that produces spike data from training images.
7374
* @return functor for generating spikes from training images.
74-
* @details The spike data is generated by iterating over the training images in a looped manner, where each image is divided into
75-
* frames. For each frame, the corresponding spike data is extracted and returned.
75+
* @details The spike data is generated by iterating over the training images in a looped manner, where each image
76+
* is divided into frames. For each frame, the corresponding spike data is extracted and returned.
7677
*/
7778
[[nodiscard]] std::function<knp::core::messaging::SpikeData(knp::core::Step)>
7879
make_training_images_spikes_generator() const;
7980

8081
/**
8182
* @brief Create a generator that produces spike data from inference images.
8283
* @return functor for generating spikes from inference images.
83-
* @details The spike data is generated by iterating over the inference images in a looped manner, where each image is divided into
84-
* frames. For each frame, the corresponding spike data is extracted and returned.
84+
* @details The spike data is generated by iterating over the inference images in a looped manner, where each image
85+
* is divided into frames. For each frame, the corresponding spike data is extracted and returned.
8586
*/
8687
[[nodiscard]] std::function<knp::core::messaging::SpikeData(knp::core::Step)>
8788
make_inference_images_spikes_generator() const;
8889

8990
/**
9091
* @brief Create an incrementing image to spikes converter.
91-
* @details This converter generates spikes based on the input image data, considering the specified number of active steps
92-
* and the state increment factor. Spikes are sent for the active steps, and no spikes are sent for the remaining steps
93-
* until the total steps per image (@ref steps_per_frame_) are reached.
94-
* @param active_steps number of active steps, which must be less than the total steps per image (@ref steps_per_frame_).
92+
* @details This converter generates spikes based on the input image data, considering the specified number of
93+
* active steps and the state increment factor. Spikes are sent for the active steps, and no spikes are sent for the
94+
* remaining steps until the total steps per image (@ref steps_per_frame_) are reached.
95+
* @param active_steps number of active steps, which must be less than the total steps per image (@ref
96+
* steps_per_frame_).
9597
* @param state_increment_factor factor by which the state is incremented for each input value.
9698
* @return functor that converts raw image data to spikes.
9799
*/

knp/tests/framework/data_processing_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ TEST(DataProcessing, ImageClassification)
3838

3939
ASSERT_EQ(dataset.get_image_size(), image_size);
4040
ASSERT_EQ(dataset.get_amount_of_classes(), classes_amount);
41-
ASSERT_EQ(dataset.get_required_training_amount(), training_amount);
4241
ASSERT_EQ(dataset.get_steps_per_frame(), steps_per_image);
4342
ASSERT_EQ(dataset.get_steps_required_for_training(), training_amount);
4443
ASSERT_EQ(dataset.get_steps_required_for_inference(), inference_amount);

0 commit comments

Comments
 (0)