Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Language: Cpp
BasedOnStyle: Google
IndentWidth: 4
AccessModifierOffset: -4
ColumnLimit: 100
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
DerivePointerAlignment: true
KeepEmptyLinesAtTheStartOfBlocks: false
SortIncludes: Never
MaxEmptyLinesToKeep: 1
InsertTrailingCommas: None
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortLambdasOnASingleLine: Inline
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BreakBeforeBraces: Attach
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterStruct: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
CompactNamespaces: false
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
EmptyLineBeforeAccessModifier: LogicalBlock
SpaceInEmptyBlock: false
FixNamespaceComments: true
IncludeBlocks: Regroup
IndentCaseLabels: true
IndentPPDirectives: None
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Left
ReflowComments: false
SeparateDefinitionBlocks: Always
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++20
TabWidth: 4
UseTab: Never
39 changes: 39 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
Checks: '-*,cppcoreguidelines-avoid-goto,cppcoreguidelines-pro-type-const-cast, google-readability-casting, modernize-replace-random-shuffle, readability-braces-around-statements, readability-container-size-empty, readability-redundant-control-flow, readability-redundant-string-init, modernize-use-nullptr, readability-identifier-naming, google-build-using-namespace'
HeaderFilterRegex: '\.h$'
WarningsAsErrors: '*'
CheckOptions:
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.TypedefCase
value: CamelCase
- key: readability-identifier-naming.TypeAliasCase
value: CamelCase
- key: readability-identifier-naming.PrivateMemberSuffix
value: '_'
- key: readability-identifier-naming.StructCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.PrivateMemberCase
value: lower_case
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.GlobalConstantPrefix
value: k
- key: readability-identifier-naming.GlobalConstantCase
value: CamelCase
- key: readability-identifier-naming.StaticConstantPrefix
value: k
- key: readability-identifier-naming.StaticConstantCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariableCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariablePrefix
value: k
- key: google-runtime-int.TypeSuffix
value: _t
Comment thread
IdLeR0 marked this conversation as resolved.
15 changes: 8 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

compile_commands.json
.cache*
.vscode*
build*



13 changes: 13 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

[submodule "libs/EigenRand"]
path = libs/EigenRand
url = https://github.com/bab2min/EigenRand
[submodule "libs/googletest"]
path = libs/googletest
url = https://github.com/google/googletest.git
[submodule "libs/mnist"]
path = libs/mnist
url = https://github.com/wichtounet/mnist.git
[submodule "libs/Eigen"]
path = libs/Eigen
url = https://gitlab.com/libeigen/eigen.git
26 changes: 26 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.10)
project(NeuralNetwork LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include_directories(
${CMAKE_SOURCE_DIR}/libs/Eigen
${CMAKE_SOURCE_DIR}/libs/EigenRand
${CMAKE_SOURCE_DIR}/libs/googletest/googletest/include
${CMAKE_SOURCE_DIR}/libs/mnist/include
${CMAKE_SOURCE_DIR}/src
)

add_subdirectory(${CMAKE_SOURCE_DIR}/libs/googletest)

add_executable(test_net tests/test_net.cpp src/adam_optimizer.cpp src/net.cpp src/loss_function.cpp src/activation_function.cpp src/dataloader.cpp src/layer.cpp src/random_params.cpp tests/mnist_utils.cpp)
target_link_libraries(test_net PRIVATE gtest gtest_main)

enable_testing()
add_test(NAME test_mnist COMMAND test_mnist)



98 changes: 97 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,97 @@
Это README для *нейросети с 0*
# Нейросеть с нуля
В этом проекте реализованы все основные компоненты нейросети на языке c++.
## Функции активации
Проект поддерживает 5 функций активации:
1. ```ActivationFunc::Name::Id``` - Id
2. ```ActivationFunc::Name::ReLU``` - ReLU
3. ```ActivationFunc::Name::Softmax``` - Softmax
4. ```ActivationFunc::Name::Sigmoid``` - Sigmoid
5. ```ActivationFunc::Name::Tanh``` - Tanh
## Функции потерь
Проект поддерживает 3 функции потерь:
1. ```LossFunc::Name::Mae``` - Mean Absolute Error.
2. ```LossFunc::Name::Mse``` - Mean Squared Error.
3. ```LossFunc::Name::CrossEntropy``` - Cross‑Entropy.
## Можно генерировать случайные параметры слоев самому
Для этого необходимо создать объект класса ```RandomParams```
1. ```GenerateNormalMatrix``` - генерирует матрицу с нормальным распределением (по умолчанию ~ N(0, 1));
2. ```GenerateUniformMatrix``` - генерирует матрицу с равномерным распределением(по умолчанию с Uni(0, 1));
3. ```GenerateConstantMatrix``` - генерирует матрицу, все элементы которой заполнены одним и тем же числом (по умолчанию все элементы равны 0);
Есть также соответствующие аналоги для векторов (например,```GenerateNormalVector```).
## FileReader/FileWriter - отвечают за запись и чтение нейросети с бинарного файла (см. пример ниже)

## Процесс использование библиотеки
Взаимодействия пользователя с нейросетью можно разделить на 4 части:
построение нейросети, подготовка данных, обучение и тестирование.
```cpp
#include <iostream>
#include "src/net.h"
using namespace network;

int main() {
// создание нейросети из 2х слоев
std::vector<Index> layer_sizes{784, 256, 10};

// создаем свои параметры для слоев (необязательно)
RandomParams rnd(42);
LayerParams first_layer;
LayerParams second_layer;
first_layer.weights = rnd.GenerateNormalMatrix(256, 784, 2, 10); // ~N(2, 10);
first_layer.bias = rnd.GenerateConstantVector(256, 0.01);
second_layer.weights = rnd.GenerateUniformMatrix(10, 256, -1, 1); // ~Uni(-1, 1);
second_layer.bias = rnd.GenerateNormalVector(10); // ~ N(0, 1);
std::vector<LayerParams> layer_params = {first_layer, second_layer};

std::vector<ActivationFunc::Name> activation_functions{
ActivationFunc::Name::ReLU, ActivationFunc::Name::Softmax}; // Функции активации на слоях
Net my_model(layer_sizes, activation_functions, layer_params);

// подготовка данных
Data train_data;
Data test_data;
// чтение базы данных
// ...

DataLoader data_loader(std::move(train_data));
LossFunc::Name loss_func = LossFunc::Name::CrossEntropy;
Index batch_size = 70;
Index num_epochs = 17;

// Параметры для алгоритма оптимизации Адам
DataType learning_rate = 3e-4;
DataType beta1 = 0.9;
DataType beta2 = 0.99;
Info print_info = Info::On; // хотим, чтобы при обучении выводилась информация в терминал

// обучение
my_model.Train(data_loader, loss_func, batch_size, num_epochs, print_info, learning_rate, beta1,
beta2);

// Вычисляем результат на тестовой выборки
Matrix prediction = my_model.Evaluate(test_data.input);

// сравниваем prediction по какому-то правилу с test.output
// ...

//////////////////////////////////////////////////////////////////

//хотим сохранить нейросеть
FileWriter w("net.bin");
w << my_model;

// хотим выгрузить нейросеть
Net read_model;
FileReader r("net.bin");
r >> read_model;
// read_model == my_model
}

```








1 change: 1 addition & 0 deletions libs/Eigen
Submodule Eigen added at 314739
1 change: 1 addition & 0 deletions libs/EigenRand
Submodule EigenRand added at f3190c
1 change: 1 addition & 0 deletions libs/googletest
Submodule googletest added at 4902ea
1 change: 1 addition & 0 deletions libs/mnist
Submodule mnist added at 3b65c3
Loading