diff --git a/.gitignore b/.gitignore index e257658..f0bbcbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,3 @@ -# ---> C++ -# 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 - +.DS_Store +build/ +.vscode/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2999c7f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.15.2) +# 设置项目名称与语言 +project(GCTL_AI VERSION 1.0) +# 添加配置配件编写的函数 +include(CMakePackageConfigHelpers) + +# 添加编译选项 +option(GCTL_AI_OPENMP "Use the OpenMP library" OFF) + +message(STATUS "Platform: " ${CMAKE_HOST_SYSTEM_NAME}) +message(STATUS "Install prefix: " ${CMAKE_INSTALL_PREFIX}) +message(STATUS "Processor: " ${CMAKE_HOST_SYSTEM_PROCESSOR}) +message(STATUS "[GCTL_AI] Use the OpenMP library: " ${GCTL_AI_OPENMP}) + +find_package(GCTL REQUIRED) +include_directories(${GCTL_INC_DIR}) + +find_package(GCTL_OPTIMIZATION REQUIRED) +include_directories(${GCTL_OPTIMIZATION_INC_DIR}) + +if(GCTL_AI_OPENMP) + if(NOT OpenMP_CXX_FOUND) + find_package(OpenMP REQUIRED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + include_directories(${OpenMP_CXX_INCLUDE_DIRS}) + endif() +endif() + +# 加入一个头文件配置,让cmake对源码进行操作 +configure_file( + "${PROJECT_SOURCE_DIR}/config.h.in" + "${PROJECT_SOURCE_DIR}/lib/dnn/config.h" + ) + +# 添加库源文件地址 +add_subdirectory(lib) + +# 去掉注释编译示例 +add_subdirectory(examples) \ No newline at end of file diff --git a/GCTL_AIConfig.cmake.in b/GCTL_AIConfig.cmake.in new file mode 100644 index 0000000..db9a325 --- /dev/null +++ b/GCTL_AIConfig.cmake.in @@ -0,0 +1,38 @@ +@PACKAGE_INIT@ + +set(@PROJECT_NAME@_VERSION "@PROJECT_VERSION@") +set_and_check(@PROJECT_NAME@_INSTALL_PREFIX "${PACKAGE_PREFIX_DIR}") +set_and_check(@PROJECT_NAME@_INC_DIR "${PACKAGE_PREFIX_DIR}/include") +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include") +set_and_check(@PROJECT_NAME@_LIB_DIR "${PACKAGE_PREFIX_DIR}/lib") +set_and_check(@PROJECT_NAME@_LIBRARY_DIR "${PACKAGE_PREFIX_DIR}/lib") + +set(@PROJECT_NAME@_LIB gctl_ai) +set(@PROJECT_NAME@_LIBRARY gctl_ai) + +set(@PROJECT_NAME@_OPENMP @GCTL_AI_OPENMP@) +message(STATUS "[GCTL_AI] Use the OpenMP library:" @GCTL_AI_OPENMP@) + +if(NOT GCTL_FOUND) + find_package(GCTL REQUIRED) + include_directories(${GCTL_INC_DIR}) +endif() + +if(NOT GCTL_OPTIMIZATION_FOUND) + find_package(GCTL_OPTIMIZATION REQUIRED) + include_directories(${GCTL_OPTIMIZATION_INC_DIR}) +endif() + +if(@PROJECT_NAME@_OPENMP) + if(NOT OpenMP_CXX_FOUND) + find_package(OpenMP REQUIRED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + include_directories(${OpenMP_CXX_INCLUDE_DIRS}) + endif() +endif() + +# include target information +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + +check_required_components(@PROJECT_NAME@) \ No newline at end of file diff --git a/README.md b/README.md index 3399982..a442297 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ -# gctl_ai - +# gctl_ai + +#### 介绍 +此库包含人工智能算法代码。 \ No newline at end of file diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..58a7bce --- /dev/null +++ b/config.h.in @@ -0,0 +1 @@ +#cmakedefine GCTL_AI_OPENMP \ No newline at end of file diff --git a/data/MNIST/mnist_database.h b/data/MNIST/mnist_database.h new file mode 100644 index 0000000..ed1c1e6 --- /dev/null +++ b/data/MNIST/mnist_database.h @@ -0,0 +1,153 @@ +#ifndef _MNIST_DATABASE_H +#define _MNIST_DATABASE_H + +#include "string" +#include "iostream" +#include "fstream" +#include "vector" + +int ReverseInt(int i) +{ + unsigned char ch1, ch2, ch3, ch4; + ch1 = i & 255; + ch2 = (i >> 8) & 255; + ch3 = (i >> 16) & 255; + ch4 = (i >> 24) & 255; + return((int)ch1 << 24) + ((int)ch2 << 16) + ((int)ch3 << 8) + ch4; +} + +class mnist_database +{ +public: + mnist_database(std::string dir); + virtual ~mnist_database(){} + + const std::vector > &train_images(); + const std::vector > &test_images(); + const std::vector &train_labels(); + const std::vector &test_labels(); + void image_dimension(int &rows, int &cols); + +private: + void read_mnist_images(std::ifstream &fs, std::vector > &images); + void read_mnist_labels(std::ifstream &fs, std::vector &labels); + +private: + std::vector > train_images_, test_images_; + std::vector train_labels_, test_labels_; +}; + +mnist_database::mnist_database(std::string dir) +{ + std::string file = dir + "/t10k-images.idx3-ubyte"; + std::ifstream infile(file, std::ios::binary); + if (!infile) throw std::runtime_error("[mnist_database] Database is not found."); + read_mnist_images(infile, test_images_); + infile.close(); + + file = dir + "/t10k-labels.idx1-ubyte"; + infile.open(file, std::ios::binary); + if (!infile) throw std::runtime_error("[mnist_database] Database is not found."); + read_mnist_labels(infile, test_labels_); + infile.close(); + + file = dir + "/train-images.idx3-ubyte"; + infile.open(file, std::ios::binary); + if (!infile) throw std::runtime_error("[mnist_database] Database is not found."); + read_mnist_images(infile, train_images_); + infile.close(); + + file = dir + "/train-labels.idx1-ubyte"; + infile.open(file, std::ios::binary); + if (!infile) throw std::runtime_error("[mnist_database] Database is not found."); + read_mnist_labels(infile, train_labels_); + infile.close(); +} + +const std::vector > &mnist_database::train_images() +{ + return train_images_; +} + +const std::vector > &mnist_database::test_images() +{ + return test_images_; +} + +const std::vector &mnist_database::train_labels() +{ + return train_labels_; +} + +const std::vector &mnist_database::test_labels() +{ + return test_labels_; +} + +void mnist_database::image_dimension(int &rows, int &cols) +{ + rows = cols = 28; + return; +} + +void mnist_database::read_mnist_images(std::ifstream &fs, std::vector > &images) +{ + int magic_number = 0; + int number_of_images = 0; + int n_rows = 0; + int n_cols = 0; + unsigned char label; + fs.read((char*)&magic_number, sizeof(magic_number)); + fs.read((char*)&number_of_images, sizeof(number_of_images)); + fs.read((char*)&n_rows, sizeof(n_rows)); + fs.read((char*)&n_cols, sizeof(n_cols)); + magic_number = ReverseInt(magic_number); + number_of_images = ReverseInt(number_of_images); + n_rows = ReverseInt(n_rows); + n_cols = ReverseInt(n_cols); + + //std::cout << "magic number = " << magic_number << std::endl; + //std::cout << "number of images = " << number_of_images << std::endl; + //std::cout << "rows = " << n_rows << std::endl; + //std::cout << "cols = " << n_cols << std::endl; + + std::vector tp; + for (int i = 0; i < number_of_images; i++) + { + tp.clear(); + for (int r = 0; r < n_rows; r++) + { + for (int c = 0; c < n_cols; c++) + { + unsigned char image = 0; + fs.read((char*)&image, sizeof(image)); + tp.push_back(image); + } + } + images.push_back(tp); + } + return; +} + +void mnist_database::read_mnist_labels(std::ifstream &fs, std::vector &labels) +{ + int magic_number = 0; + int number_of_images = 0; + fs.read((char*)&magic_number, sizeof(magic_number)); + fs.read((char*)&number_of_images, sizeof(number_of_images)); + magic_number = ReverseInt(magic_number); + number_of_images = ReverseInt(number_of_images); + + //std::cout << "magic number = " << magic_number << std::endl; + //std::cout << "number of images = " << number_of_images << std::endl; + + for (int i = 0; i < number_of_images; i++) + { + unsigned char label = 0; + fs.read((char*)&label, sizeof(label)); + labels.push_back((double)label); + } + return; +} + +#endif // _MNIST_DATABASE_H \ No newline at end of file diff --git a/data/MNIST/t10k-images.idx3-ubyte b/data/MNIST/t10k-images.idx3-ubyte new file mode 100644 index 0000000..1170b2c Binary files /dev/null and b/data/MNIST/t10k-images.idx3-ubyte differ diff --git a/data/MNIST/t10k-labels.idx1-ubyte b/data/MNIST/t10k-labels.idx1-ubyte new file mode 100644 index 0000000..d1c3a97 Binary files /dev/null and b/data/MNIST/t10k-labels.idx1-ubyte differ diff --git a/data/MNIST/train-images.idx3-ubyte b/data/MNIST/train-images.idx3-ubyte new file mode 100644 index 0000000..bbce276 Binary files /dev/null and b/data/MNIST/train-images.idx3-ubyte differ diff --git a/data/MNIST/train-labels.idx1-ubyte b/data/MNIST/train-labels.idx1-ubyte new file mode 100644 index 0000000..d6b4c5d Binary files /dev/null and b/data/MNIST/train-labels.idx1-ubyte differ diff --git a/data/saved_networks/mnist_m1.gctl.dnn b/data/saved_networks/mnist_m1.gctl.dnn new file mode 100644 index 0000000..5b17d16 Binary files /dev/null and b/data/saved_networks/mnist_m1.gctl.dnn differ diff --git a/data/saved_networks/mnist_m2.gctl.dnn b/data/saved_networks/mnist_m2.gctl.dnn new file mode 100644 index 0000000..a44ef58 Binary files /dev/null and b/data/saved_networks/mnist_m2.gctl.dnn differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..3ff7f9d --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -O3") +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin/examples) + +macro(add_example name) + add_executable(${name} ${name}.cpp) + target_link_libraries(${name} PUBLIC gctl_ai) +endmacro() + +add_example(ex1) +add_example(ex2) +add_example(ex_mnist) +add_example(ex_mnist2) +add_example(ex_mnist3) \ No newline at end of file diff --git a/examples/ex1.cpp b/examples/ex1.cpp new file mode 100644 index 0000000..1bed7e0 --- /dev/null +++ b/examples/ex1.cpp @@ -0,0 +1,120 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../lib/dnn.h" +using namespace gctl; + +void data_generator(const matrix &train_obs, matrix &train_tar) +{ + for (int j = 0; j < train_obs.col_size(); j++) + { + train_tar[0][j] = sqrt(train_obs[0][j]*train_obs[0][j] + train_obs[1][j]*train_obs[1][j]); + } + return; +} + +int main(int argc, char const *argv[]) try +{ + // Prepare the data. In this example, we try to learn the sin() function. + matrix train_obs(2, 1000), train_tar(1, 1000), pre_obs(2, 10), pre_tar(1, 10), predicts(1, 10); + + unsigned int seed = 101; + srand(seed); + for (int j = 0; j < 1000; j++) + { + for (int i = 0; i < 2; i++) + { + train_obs[i][j] = random(0.0, 1.0); + } + } + + for (int j = 0; j < 10; j++) + { + for (int i = 0; i < 2; i++) + { + pre_obs[i][j] = random(0.0, 1.0); + } + } + + data_generator(train_obs, train_tar); + data_generator(pre_obs, pre_tar); + + dnn my_nn("Ex-1"); + my_nn.add_hind_layer(2, 100, FullyConnected, Identity); + my_nn.add_hind_layer(100, 100, FullyConnected, PReLU); + my_nn.add_hind_layer(100, 100, FullyConnected, PReLU); + my_nn.add_hind_layer(100, 1, FullyConnected, Identity); + my_nn.add_output_layer(RegressionMSE); + my_nn.add_train_set(train_obs, train_tar, 200); + + my_nn.show_network(); + my_nn.init_network(0.0, 0.1, seed); + + sgd_para my_para = my_nn.default_sgd_para(); + my_nn.train_network(my_para, gctl::ADAM); + //lgd_para my_para = my_nn.default_lgd_para(); + //my_para.flight_times = 5000; + //my_para.lambda = 5e-5; + //my_para.epsilon = 1e-5; + //my_para.batch = 10; + //my_nn.train_network(my_para, gctl::LGD); + + my_nn.predict(pre_obs, predicts); + + double diff = 0; + for (int i = 0; i < 1; i++) + { + for (int j = 0; j < 10; j++) + { + diff = std::max(fabs(predicts[i][j] - pre_tar[i][j]), diff); + } + } + std::clog << "Max difference = " << diff << "\n"; +/* + my_nn.save_network("ex1"); + + dnn file_nn("File NN"); + file_nn.load_network("ex1"); + file_nn.show_network(); + file_nn.predict(pre_obs, predicts); + + diff = 0; + for (int i = 0; i < 1; i++) + { + for (int j = 0; j < 10; j++) + { + diff = std::max(fabs(predicts[i][j] - pre_tar[i][j]), diff); + } + } + std::clog << "Max difference = " << diff << "\n"; +*/ + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/examples/ex2.cpp b/examples/ex2.cpp new file mode 100644 index 0000000..91e27bd --- /dev/null +++ b/examples/ex2.cpp @@ -0,0 +1,66 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../lib/dnn.h" +using namespace gctl; + +int main(int argc, char const *argv[]) try +{ + convolution cnl_layer(0, 3, 10, 10, 3, 3, 2, 2, Valid, ReLU); + std::clog << cnl_layer.layer_info() << std::endl; + + matrix t(100, 3); + std::clog << "T = \n"; + for (size_t c = 0; c < 3; c++) + { + for (size_t i = 0; i < 10; i++) + { + for (size_t j = 0; j < 10; j++) + { + t[i*10+j][c] = i*10 + j + 1; + std::clog << t[i*10+j][c] << " "; + } + std::clog << "\n"; + } + } + + array weights(28); + for (size_t i = 0; i < 28; i++) + { + weights[i] = 1.0; + } + + cnl_layer.forward_propagation(weights, t); + + const matrix &d = cnl_layer.forward_propagation_data(); + d.show(std::clog); + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/examples/ex_mnist.cpp b/examples/ex_mnist.cpp new file mode 100644 index 0000000..b587502 --- /dev/null +++ b/examples/ex_mnist.cpp @@ -0,0 +1,116 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../data/MNIST/mnist_database.h" +#include "../lib/dnn.h" + +using namespace gctl; + +int main(int argc, char const *argv[]) try +{ + mnist_database data("data/MNIST"); + + matrix train_obs(784, 60000), train_lab(10, 60000, 0.0); + matrix test_obs(784, 10000), test_lab(10, 10000, 0.0), predicts(10, 10000); + + const std::vector > &dt_obs = data.train_images(); + for (size_t i = 0; i < 60000; i++) + { + for (size_t j = 0; j < 784; j++) + { + train_obs[j][i] = dt_obs[i][j]/255.0; + } + } + + const std::vector > &dt_obs2 = data.test_images(); + for (size_t i = 0; i < 10000; i++) + { + for (size_t j = 0; j < 784; j++) + { + test_obs[j][i] = dt_obs2[i][j]/255.0; + } + } + + const std::vector &dt_lab = data.train_labels(); + for (size_t i = 0; i < 60000; i++) + { + train_lab[dt_lab[i]][i] = 1.0; + } + + const std::vector &dt_lab2 = data.test_labels(); + for (size_t i = 0; i < 10000; i++) + { + test_lab[dt_lab2[i]][i] = 1.0; + } + + dnn my_nn("Ex-MNIST"); + my_nn.add_hind_layer(784, 800, FullyConnected, PReLU); + my_nn.add_hind_layer(800, 10, FullyConnected, SoftMax); + my_nn.add_output_layer(MultiClassEntropy); + my_nn.add_train_set(train_obs, train_lab, 1000); + my_nn.init_network(0.0, 0.1); + + //sgd_para my_para = my_nn.default_sgd_para(); + //my_para.alpha = 0.01; + //my_para.epsilon = 1e-5; + //my_nn.train_network(my_para, gctl::ADAM); + lgd_para my_para = my_nn.default_lgd_para(); + my_para.flight_times = 1000; + my_para.alpha = 0.08; + my_para.beta = 1.8; + my_nn.train_network(my_para); + + my_nn.predict(test_obs, predicts); + my_nn.save_network("data/saved_networks/mnist_m1"); + + int wrong_predicts = 0; + int test_id, pre_id; + double test_scr, pre_scr; + for (size_t j = 0; j < 10000; j++) + { + test_id = pre_id = 0; + test_scr = pre_scr = 0; + for (size_t i = 0; i < 10; i++) + { + if (test_lab[i][j] > test_scr) {test_scr = test_lab[i][j]; test_id = i;} + if (predicts[i][j] > pre_scr) {pre_scr = predicts[i][j]; pre_id = i;} + } + + if (test_id != pre_id) + { + wrong_predicts++; + } + } + + std::cout << "Correct Rate = " << (10000 - wrong_predicts)/100.0 << "%\n"; + + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/examples/ex_mnist2.cpp b/examples/ex_mnist2.cpp new file mode 100644 index 0000000..f5b24f9 --- /dev/null +++ b/examples/ex_mnist2.cpp @@ -0,0 +1,116 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../data/MNIST/mnist_database.h" +#include "../lib/dnn.h" + +using namespace gctl; + +int main(int argc, char const *argv[]) try +{ + mnist_database data("data/MNIST"); + + matrix train_obs(784, 60000), train_lab(10, 60000, 0.0); + matrix test_obs(784, 10000), test_lab(10, 10000, 0.0), predicts(10, 10000); + + const std::vector > &dt_obs = data.train_images(); + for (size_t i = 0; i < 60000; i++) + { + for (size_t j = 0; j < 784; j++) + { + train_obs[j][i] = dt_obs[i][j]/255.0; + } + } + + const std::vector > &dt_obs2 = data.test_images(); + for (size_t i = 0; i < 10000; i++) + { + for (size_t j = 0; j < 784; j++) + { + test_obs[j][i] = dt_obs2[i][j]/255.0; + } + } + + const std::vector &dt_lab = data.train_labels(); + for (size_t i = 0; i < 60000; i++) + { + train_lab[dt_lab[i]][i] = 1.0; + } + + const std::vector &dt_lab2 = data.test_labels(); + for (size_t i = 0; i < 10000; i++) + { + test_lab[dt_lab2[i]][i] = 1.0; + } + + dnn my_nn("Ex-MNIST"); + my_nn.add_hind_layer(1, 28, 28, 4, 4, 2, 2, Convolution, Same, PReLU); + my_nn.add_hind_layer(169, 256, FullyConnected, PReLU); + my_nn.add_hind_layer(256, 10, FullyConnected, SoftMax); + my_nn.add_output_layer(MultiClassEntropy); + my_nn.add_train_set(train_obs, train_lab, 5000); + my_nn.init_network(0.0, 0.1); + + sgd_para my_para = my_nn.default_sgd_para(); + my_para.alpha = 0.01; + my_para.epsilon = 1e-5; + my_nn.train_network(my_para, gctl::ADAM); + //lgd_para my_para = my_nn.default_lgd_para(); + //my_para.flight_times = 2000; + //my_para.alpha = 0.1; + //my_nn.train_network(my_para); + + my_nn.predict(test_obs, predicts); + my_nn.save_network("data/saved_networks/mnist_m2"); + + int wrong_predicts = 0; + int test_id, pre_id; + double test_scr, pre_scr; + for (size_t j = 0; j < 10000; j++) + { + test_id = pre_id = 0; + test_scr = pre_scr = 0; + for (size_t i = 0; i < 10; i++) + { + if (test_lab[i][j] > test_scr) {test_scr = test_lab[i][j]; test_id = i;} + if (predicts[i][j] > pre_scr) {pre_scr = predicts[i][j]; pre_id = i;} + } + + if (test_id != pre_id) + { + wrong_predicts++; + } + } + + std::cout << "Correct Rate = " << (10000 - wrong_predicts)/100.0 << "%\n"; + + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/examples/ex_mnist3.cpp b/examples/ex_mnist3.cpp new file mode 100644 index 0000000..d7fae16 --- /dev/null +++ b/examples/ex_mnist3.cpp @@ -0,0 +1,87 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../data/MNIST/mnist_database.h" +#include "../lib/dnn.h" + +using namespace gctl; + +int main(int argc, char const *argv[]) try +{ + mnist_database data("data/MNIST"); + dnn my_nn("Ex-MNIST"); + my_nn.load_network("data/saved_networks/mnist_m1.gctl.dnn"); + my_nn.show_network(); + my_nn.save_layer2text(0, "data/saved_networks/mnist_m1_layer1"); + my_nn.save_layer2text(1, "data/saved_networks/mnist_m1_layer2"); +/* + matrix test_obs(784, 10000), test_lab(10, 10000, 0.0), predicts(10, 10000); + + const std::vector > &dt_obs2 = data.test_images(); + for (size_t i = 0; i < 10000; i++) + { + for (size_t j = 0; j < 784; j++) + { + test_obs[j][i] = dt_obs2[i][j]/255.0; + } + } + + const std::vector &dt_lab2 = data.test_labels(); + for (size_t i = 0; i < 10000; i++) + { + test_lab[dt_lab2[i]][i] = 1.0; + } + + my_nn.predict(test_obs, predicts); + + int wrong_predicts = 0; + int test_id, pre_id; + double test_scr, pre_scr; + for (size_t j = 0; j < 10000; j++) + { + test_id = pre_id = 0; + test_scr = pre_scr = 0; + for (size_t i = 0; i < 10; i++) + { + if (test_lab[i][j] > test_scr) {test_scr = test_lab[i][j]; test_id = i;} + if (predicts[i][j] > pre_scr) {pre_scr = predicts[i][j]; pre_id = i;} + } + + if (test_id != pre_id) + { + wrong_predicts++; + } + } + + std::cout << "Correct Rate = " << (10000 - wrong_predicts)/100.0 << "%\n"; +*/ + return 0; +} +catch (std::exception &e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/installer b/installer new file mode 100755 index 0000000..c49ddcc --- /dev/null +++ b/installer @@ -0,0 +1,54 @@ +#!/bin/bash + +if [[ $# == 0 || ${1} == "help" ]]; then + echo "Compiles executables/libraries and maintains installed files. Two tools 'Cmake' and 'stow' are empolyed here. For more information, see https://cmake.org and https://www.gnu.org/software/stow/." + echo "" + echo "School of Earth Sciences, Zhejiang University" + echo "Yi Zhang (yizhang-geo@zju.edu.cn)" + echo "" + echo "Usage: ./config.sh [option] [Cmake options]" + echo "" + echo "Options:" + echo "(1) configure: Configure Cmake project(s). This option could take extra Cmake options as in