25 Layer(
size_t input_size,
size_t output_size)
26 : input_size_(input_size), output_size_(output_size) {
27 weights_.resize(input_size * output_size);
28 biases_.resize(output_size);
32 std::vector<T>
forward(
const std::vector<T>& input) {
33 if (input.size() != input_size_) {
34 throw std::invalid_argument(
"Invalid input size");
36 std::vector<T> output(output_size_);
38 for (
size_t i = 0; i < output_size_; ++i) {
39 output[i] = biases_[i];
40 for (
size_t j = 0; j < input_size_; ++j) {
41 output[i] += input[j] * weights_[i * input_size_ + j];
55 T scale = std::sqrt(2.0 / (input_size_ + output_size_));
56 for (
auto& w : weights_) {
57 w = (
static_cast<T
>(rand()) / RAND_MAX * 2 - 1) * scale;
59 for (
auto& b : biases_) {
92 if (activation_ ==
"relu") {
94 }
else if (activation_ ==
"sigmoid") {
95 return 1.0 / (1.0 + std::exp(-x));
102 if (activation_ ==
"relu") {
103 return x > 0 ? 1 : 0;
104 }
else if (activation_ ==
"sigmoid") {
105 double sig = apply_activation(x);
106 return sig * (1 - sig);
108 double tanh_x = std::tanh(x);
109 return 1 - tanh_x * tanh_x;
114 std::vector<double>
prepare_batch(
const std::vector<T>& data,
size_t start_idx)
const {
115 std::vector<double> batch;
116 batch.reserve(std::min(batch_size_, data.size() - start_idx));
118 for (
size_t i = 0; i < batch_size_ && (start_idx + i) < data.size(); ++i) {
120 batch.push_back(compute_feature(data[start_idx + i]));
122 batch.push_back(
static_cast<double>(data[start_idx + i]));
128 template <
typename U>
134 for (
const auto& inner : arr) {
135 sum += compute_feature(inner);
137 return sum / arr.size();
140 return std::accumulate(arr.begin(), arr.end(), 0.0) / arr.size();
144 return static_cast<double>(arr);
150 : window_size_(window_size), threshold_(threshold), learning_rate_(0.01), batch_size_(32),
151 activation_(
"relu"), epochs_(100) {}
157 threshold_ = threshold;
167 std::vector<std::vector<T>>
chunk(
const std::vector<T>& data)
const {
173 if (data.size() <= window_size_) {
177 std::vector<std::vector<T>> result;
178 std::vector<T> current_chunk;
180 for (
const auto& value : data) {
182 double feature = compute_feature(value);
183 if (!current_chunk.empty() &&
184 std::abs(feature - compute_feature(current_chunk.back())) > threshold_) {
185 result.push_back(current_chunk);
186 current_chunk.clear();
190 if (!current_chunk.empty() &&
191 std::abs(
static_cast<double>(value - current_chunk.back())) > threshold_) {
192 result.push_back(current_chunk);
193 current_chunk.clear();
196 current_chunk.push_back(value);
199 if (!current_chunk.empty()) {
200 result.push_back(current_chunk);
212 throw std::invalid_argument(
"Learning rate must be positive");
214 learning_rate_ = rate;
222 return learning_rate_;
231 throw std::invalid_argument(
"Batch size must be positive");
249 if (activation !=
"relu" && activation !=
"sigmoid" && activation !=
"tanh") {
250 throw std::invalid_argument(
251 "Invalid activation function. Supported: relu, sigmoid, tanh");
253 activation_ = activation;
269 if (num_epochs == 0) {
270 throw std::invalid_argument(
"Number of epochs must be positive");
272 epochs_ = num_epochs;
288 std::vector<double>
train(
const std::vector<T>& data) {
289 if (data.size() < window_size_) {
290 throw std::invalid_argument(
"Training data size must be larger than window size");
297 std::vector<double> epoch_losses;
298 epoch_losses.reserve(epochs_);
301 for (
size_t epoch = 0; epoch < epochs_; ++epoch) {
302 double epoch_loss = 0.0;
303 size_t num_batches = (data.size() + batch_size_ - 1) / batch_size_;
305 for (
size_t batch = 0; batch < num_batches; ++batch) {
306 size_t start_idx = batch * batch_size_;
307 auto batch_data = prepare_batch(data, start_idx);
308 if (batch_data.size() < window_size_)
312 auto hidden = input_layer.
forward(batch_data);
313 for (
auto& h : hidden)
314 h = apply_activation(h);
315 auto output = hidden_layer.
forward(hidden);
318 double target = batch_data.back();
319 double prediction = output[0];
320 double loss = 0.5 * (prediction - target) * (prediction - target);
324 double error = prediction - target;
325 double delta = error * activation_derivative(prediction);
328 for (
size_t i = 0; i < window_size_; ++i) {
329 hidden[i] -= learning_rate_ * delta * batch_data[i];
333 epoch_losses.push_back(epoch_loss / num_batches);
Neural network layer implementation.
Layer(size_t input_size, size_t output_size)
void initialize_weights()
std::vector< T > weights_
std::vector< T > forward(const std::vector< T > &input)
Class implementing neural network-based chunking.
std::vector< double > train(const std::vector< T > &data)
Train the neural network on the provided data.
void set_learning_rate(double rate)
Set the learning rate for neural network training.
double activation_derivative(double x) const
size_t get_batch_size() const
Get the current batch size.
std::vector< double > prepare_batch(const std::vector< T > &data, size_t start_idx) const
size_t get_epochs() const
Get the current number of training epochs.
size_t get_window_size() const
std::vector< std::vector< T > > chunk(const std::vector< T > &data) const
void set_activation(const std::string &activation)
Set the activation function type.
double compute_feature(const U &arr) const
void set_threshold(double threshold)
void set_epochs(size_t num_epochs)
Set the number of training epochs.
void set_batch_size(size_t size)
Set the batch size for training.
double get_threshold() const
void set_window_size(size_t size)
NeuralChunking(size_t window_size=8, double threshold=0.5)
std::string get_activation() const
Get the current activation function type.
double get_learning_rate() const
Get the current learning rate.
double apply_activation(double x) const
size_t input_size
Size of input layer.
double threshold
Decision threshold for chunk boundaries.
size_t batch_size
Batch size for processing.
double learning_rate
Learning rate for training.
size_t hidden_size
Size of hidden layer.
Configuration for neural network chunking.