ЛСТМ (Long Short-Term Memory) - это тип рекуррентных нейронных сетей, который широко используется для работы с последовательностями данных, такими как тексты, временные ряды и др.
Для создания простого примера слоя LSTM на C++ нам понадобятся следующие библиотеки:
- Eigen - для работы с многомерными массивами;
- NumCpp - для работы с числовыми данными.
Прежде всего, нам нужно определить структуру LSTM-слоя, которая включает в себя веса, смещения и активационную функцию. Вот пример кода:
#include <iostream> #include <Eigen/Dense> #include <NumCpp.hpp> class LSTM { private: int input_size; int hidden_size; int output_size; Eigen::MatrixXf W_i, W_f, W_o, W_c; Eigen::MatrixXf U_i, U_f, U_o, U_c; Eigen::VectorXf b_i, b_f, b_o, b_c; Eigen::VectorXf c_prev, h_prev; public: LSTM(int input_size, int hidden_size, int output_size) : input_size(input_size), hidden_size(hidden_size), output_size(output_size) { // Инициализация весов и смещений случайными значениями W_i = Eigen::MatrixXf::Random(hidden_size, input_size); W_f = Eigen::MatrixXf::Random(hidden_size, input_size); W_o = Eigen::MatrixXf::Random(hidden_size, input_size); W_c = Eigen::MatrixXf::Random(hidden_size, input_size); U_i = Eigen::MatrixXf::Random(hidden_size, hidden_size); U_f = Eigen::MatrixXf::Random(hidden_size, hidden_size); U_o = Eigen::MatrixXf::Random(hidden_size, hidden_size); U_c = Eigen::MatrixXf::Random(hidden_size, hidden_size); b_i = Eigen::VectorXf::Random(hidden_size); b_f = Eigen::VectorXf::Random(hidden_size); b_o = Eigen::VectorXf::Random(hidden_size); b_c = Eigen::VectorXf::Random(hidden_size); c_prev = Eigen::VectorXf::Zero(hidden_size); h_prev = Eigen::VectorXf::Zero(hidden_size); } Eigen::VectorXf forward(Eigen::VectorXf x) { Eigen::VectorXf i = (W_i * x + U_i * h_prev + b_i).unaryExpr([](float val) { return 1.0f / (1.0f + std::exp(-val)); }); Eigen::VectorXf f = (W_f * x + U_f * h_prev + b_f).unaryExpr([](float val) { return 1.0f / (1.0f + std::exp(-val)); }); Eigen::VectorXf o = (W_o * x + U_o * h_prev + b_o).unaryExpr([](float val) { return 1.0f / (1.0f + std::exp(-val)); }); Eigen::VectorXf g = (W_c * x + U_c * h_prev + b_c).unaryExpr([](float val) { return std::tanh(val); }); Eigen::VectorXf c = f.array() * c_prev.array() + i.array() * g.array(); Eigen::VectorXf h = o.array() * std::tanh(c.array()); c_prev = c; h_prev = h; return h; } }; int main() { // Создание объекта LSTM с входным размером 10, скрытым размером 16 и выходным размером 8 LSTM lstm(10, 16, 8); // Пример использования LSTM-слоя Eigen::VectorXf x(10); x << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; Eigen::VectorXf h = lstm.forward(x); std::cout << "Output: " << h.transpose() << std::endl; return 0; }
В данном примере мы определяем класс LSTM, который имеет конструктор для инициализации весов и смещений случайными значениями, а также функцию forward, которая принимает входной вектор и возвращает выходной вектор LSTM-слоя.
В функции forward мы сначала вычисляем значения вентилей (и, f, o) и гейта (g), затем обновляем состояние g-ячейки (c) и скрытое состояние (h). Наконец, мы возвращаем скрытое состояние.
В main-функции мы создаем объект LSTM и передаем входной вектор x размером 10. Затем выводим выходной вектор на экран.
Надеюсь, пример ясен и поможет вам в создании слоя LSTM на C++!