欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)神經(jīng)網(wǎng)絡(luò)框架SimpleNN的詳細過程

 更新時間:2021年08月25日 10:40:40   作者:Peiy_Liu  
本來自己想到用C++實現(xiàn)神經(jīng)網(wǎng)絡(luò)主要是想強化一下編碼能力并入門深度學(xué)習(xí),對C++實現(xiàn)神經(jīng)網(wǎng)絡(luò)框架SimpleNN的詳細過程感興趣的朋友一起看看吧

SimpleNN is a simple neural network framework written in C++.It can help to learn how neural networks work.
源碼地址:https://github.com/Kindn/SimpleNN

Features

  • Construct neural networks.
  • Configure optimizer and loss layer for the network to train models and use models to do prediction.Save models.
  • Network architecture will be saved as a .netjson file,while weights will be saved as a .weightsbinary file.
  • Load models.Load network from an existing .netfile and load weights from an existing .weights.Load dataset (including data and labels) from a .csvfile.It is neccesary to preprocess the dataset(mnist etc.) into SimpleNN stype 2D matrix and save it into a .csvfile.All data in SimpleNN will be organized into columns and conbined into a 2D matrix.
  • For example,mostly a batch of C C C channels H H Hx W W W images with batch size N N N will be flatten into columns by channel and organized into an ( H ∗ W ) (H*W) (H∗W)x ( C ∗ N ) (C*N) (C∗N) matrix.構(gòu)建自定義網(wǎng)絡(luò)。
  • 為網(wǎng)絡(luò)對象配置優(yōu)化器和損失函數(shù)層來訓(xùn)練模型,并用模型作預(yù)測。
  • 保存模型。網(wǎng)絡(luò)結(jié)構(gòu)用json格式描述,擴展名為 .net;權(quán)重存為二進制文件,擴展名為.weights
  • 加載模型。從已有的.net文件中加載網(wǎng)絡(luò),從已有的.weights文件中加載權(quán)重。
  • .csv文件中加載數(shù)據(jù)集。在此之前需要對原始數(shù)據(jù)集(如mnist等)進行預(yù)處理組織為一個二維矩陣。
  • 在SimpleNN中流動的所有數(shù)據(jù)都是組織成一列列的并組合成一個二維矩陣。

例如,大多數(shù)情況下一批batch size為 N N N 的 C C C 通道 H H Hx W W W 圖像會按通道展開成列并組織為一個 ( H ∗ W ) (H*W) (H∗W)x ( C ∗ N ) (C*N) (C∗N)的矩陣。

 Dependencies

The core of SimpleNN is completely written with C++11 STL.So to build SimpleNN it just need a C++ compiler surppoting C++11 stantard.

P.S.:Some examples in examplesfolder needs 3rd-party libraries like OpenCV3.So if you want to build them as well you may install the needed libraries first.

Platform

Any os with C++11 compiler.

To Do

  • 豐富layers和nets。
  • 實現(xiàn)AutoGradient,使之可基于計算圖構(gòu)造網(wǎng)絡(luò)。
  • 利用并行計算實現(xiàn)矩陣運算等過程的加速優(yōu)化(多線程、GPU),目前所有矩陣運算都是用for循環(huán)硬堆的,毫無性能可言。。。
  • 利用自己造的這個輪子復(fù)現(xiàn)更多的神經(jīng)網(wǎng)絡(luò)模型。
  • 為什么用二維矩陣來存儲數(shù)據(jù)呢主要是因為一開始只是寫了一個二維矩陣運算模板類,然后就想直接用這個類實現(xiàn)神經(jīng)網(wǎng)絡(luò)。一般情況下這種數(shù)據(jù)處理方法應(yīng)該是夠用的,后面看如果有必要的話再實現(xiàn)一個四維的Tensor類。

本來自己想到用C++實現(xiàn)神經(jīng)網(wǎng)絡(luò)主要是想強化一下編碼能力并入門深度學(xué)習(xí),所以我會盡力親自從頭實現(xiàn)以上功能,歡迎各位大佬們批評指點!

Usage

1.Build

git clone 
cd SimpleNN
mkdir build
cd build
cmake ..
make

2.Run examples(Linux)

examples都在examples目錄下,以例子recognition為例。本例是利用圖像分割和LeNet進行數(shù)字識別。

若目標數(shù)字是黑底白字,則在終端輸入(假設(shè)終端在SimpleNN根目錄下打開)

examples/mnist/recognition <image_path>

效果:

在這里插入圖片描述在這里插入圖片描述

若目標數(shù)字是黑底白字,則輸入

examples/mnist/recognition <image_path> --reverse

在mnist目錄下已有訓(xùn)練好的LeNet權(quán)重參數(shù)。若要運行examples/mnist/train,需要先在examples/mnist/dataset目錄下運行generate_csv.py來生成數(shù)據(jù)集的csv文件(這個文件有400多M屬于大文件試了好多種都push不上來QAQ)。

注:本例依賴OpenCV3,如果要運行須事先安裝,不然不會編譯本例。

3.Coding

Construct network

int input_img_rows1 = 28;
                int input_img_cols1 = 28;
                int input_img_channels1 = 1;

                int conv_output_img_channels1 = 6;
                int conv_filter_rows1 = 5;
                int conv_filter_cols1 = 5;
                int conv_row_pads1 = 0;
                int conv_col_pads1 = 0;
                int conv_row_strides1 = 1;
                int conv_col_strides1 = 1;

                std::shared_ptr<snn::Convolution> conv_layer1(new snn::Convolution(input_img_rows1, input_img_cols1, 
                                                            input_img_channels1, 
                                                            conv_output_img_channels1, 
                                                            conv_filter_rows1, conv_filter_cols1, 
                                                            conv_row_pads1, conv_col_pads1, 
                                                            conv_row_strides1, conv_col_strides1, 
                                                            0, 0.283, 
                                                            0, 0.01));

                int pool_input_img_rows1 = conv_layer1->output_img_rows;
                int pool_input_img_cols1 = conv_layer1->output_img_cols;
                int pool_filter_rows1 = 2;
                int pool_filter_cols1 = 2;
                int pool_pads1 = 0;
                int pool_strides1 = 2;

                std::shared_ptr<snn::MaxPooling> pool_layer1(new snn::MaxPooling(pool_input_img_rows1, pool_input_img_cols1, 
                                                        pool_filter_rows1, pool_filter_cols1, 
                                                        pool_pads1, pool_pads1, 
                                                        pool_strides1, pool_strides1, 
                                                        conv_output_img_channels1, false));

                int input_img_rows2 = pool_layer1->output_img_rows;
                int input_img_cols2 = pool_layer1->output_img_rows;
                int input_img_channels2 = pool_layer1->image_channels;

                int conv_output_img_channels2 = 16;
                int conv_filter_rows2 = 5;
                int conv_filter_cols2 = 5;
                int conv_row_pads2 = 0;
                int conv_col_pads2 = 0;
                int conv_row_strides2 = 1;
                int conv_col_strides2 = 1;

                std::shared_ptr<snn::Convolution> conv_layer2(new snn::Convolution(input_img_rows2, input_img_cols2, 
                                                            input_img_channels2, 
                                                            conv_output_img_channels2, 
                                                            conv_filter_rows2, conv_filter_cols2, 
                                                            conv_row_pads2, conv_col_pads2, 
                                                            conv_row_strides2, conv_col_strides2, 
                                                            0, 0.115, 
                                                            0, 0.01));

                int pool_input_img_rows2 = conv_layer2->output_img_rows;
                int pool_input_img_cols2 = conv_layer2->output_img_cols;
                int pool_filter_rows2 = 2;
                int pool_filter_cols2 = 2;
                int pool_pads2 = 0;
                int pool_strides2 = 2;

                std::shared_ptr<snn::MaxPooling> pool_layer2(new snn::MaxPooling(pool_input_img_rows2, pool_input_img_cols2, 
                                                        pool_filter_rows2, pool_filter_cols2, 
                                                        pool_pads2, pool_pads2, 
                                                        pool_strides2, pool_strides2, 
                                                        conv_output_img_channels2, true));

                int aff1_input_rows = pool_layer2->output_rows * conv_output_img_channels2; // because flatten-flag is true
                int aff1_input_cols = 1;
                int aff1_output_rows = 120;
                int aff1_output_cols = 1;

                std::shared_ptr<snn::Affine> aff1_layer(new snn::Affine(aff1_input_rows, aff1_input_cols, 
                                                aff1_output_rows, aff1_output_cols, 0, 2.0 / double(aff1_input_rows), 
                                                                                    0, 0.01));

                int aff2_input_rows = 120;
                int aff2_input_cols = 1;
                int aff2_output_rows = 84;
                int aff2_output_cols = 1;

                std::shared_ptr<snn::Affine> aff2_layer(new snn::Affine(aff2_input_rows, aff2_input_cols, 
                                                aff2_output_rows, aff2_output_cols, 0, 2.0 / 120.0, 0, 0.01));

                int aff3_input_rows = 84;
                int aff3_input_cols = 1;
                int aff3_output_rows = 10;
                int aff3_output_cols = 1;

                std::shared_ptr<snn::Affine> aff3_layer(new snn::Affine(aff3_input_rows, aff3_input_cols, 
                                                aff3_output_rows, aff3_output_cols, 0, 2.0 / 84.0, 0, 0.01));

                std::shared_ptr<snn::Relu> relu_layer1(new snn::Relu);
                std::shared_ptr<snn::Relu> relu_layer2(new snn::Relu);
                std::shared_ptr<snn::Relu> relu_layer3(new snn::Relu);
                std::shared_ptr<snn::Relu> relu_layer4(new snn::Relu);
                //std::shared_ptr<Softmax> softmax_layer(new Softmax);
				
				snn::Sequential net;
                net << conv_layer1 << relu_layer1 << pool_layer1
                    << conv_layer2 << relu_layer2 << pool_layer2
                    << aff1_layer << relu_layer3
                    << aff2_layer << relu_layer4
                    <<aff3_layer;

也可以直接封裝成一個類,參考models目錄下各hpp文件:

#include <../include/SimpleNN.hpp>

namespace snn
{
    // Simplified LeNet-5 model
    class LeNet : public Sequential
    {
        public:
            LeNet():Sequential()
            {
               /* ... */

                *this << conv_layer1 << relu_layer1 << pool_layer1
                    << conv_layer2 << relu_layer2 << pool_layer2
                    << aff1_layer << relu_layer3
                    << aff2_layer << relu_layer4
                    <<aff3_layer;
            }
    };
}

Train model

配置優(yōu)化器和loss層:

std::shared_ptr<SoftmaxWithLoss> loss_layer(new SoftmaxWithLoss(true));
net.set_loss_layer(loss_layer);
std::cout << "Loss layer ready!" << std::endl;

std::vector<Matrix_d> init_params = net.get_params();
std::vector<Matrix_d> init_grads = net.get_grads();
 std::shared_ptr<AdaGrad> opt(new AdaGrad(init_params, init_grads, 0.012));
 net.set_optimizer(opt);

加載數(shù)據(jù)

Dataset train_set(true);
Dataset test_set(true);
    
 if (train_set.load_data(train_data_file_path, train_label_file_path))
     std::cout << "Train set loading finished!" << std::endl;
else
     std::cout << "Failed to load train set data!" << std::endl;

if (test_set.load_data(test_data_file_path, test_label_file_path))
     std::cout << "Test set loading finished!" << std::endl;
else
     std::cout << "Failed to load test set data!" << std::endl;

訓(xùn)練并保存模型

net.fit(train_set, test_set, 256, 2);

if (!net.save_net("../../../examples/mnist/LeNet.net"))
{
     std::cout << "Failed to save net!" << std::endl;
     return 0;
}
if (!net.save_weights("../../../examples/mnist/LeNet.weights"))
{
     std::cout << "Failed to save weights!" << std::endl;
     return 0;
}

Load model

if (!net.load_net(net_path))
{
     std::cerr << "Failed to load net!" << std::endl;
     return -1;
    
}
if (!net.load_weights(weight_path))
{
     std::cerr << "Failed to load weights!" << std::endl;
     return -1;
    
}

或者直接

if (!net.load_model(net_path, weight_path))
{
     std::cerr << "Failed to load model!" << std::endl;
     return -1;
    
}

如果網(wǎng)絡(luò)結(jié)構(gòu)和權(quán)重分開加載,則先加載結(jié)構(gòu)再加載權(quán)重。

Predict

y = net.predict(x);

到此這篇關(guān)于用C++實現(xiàn)的簡易神經(jīng)網(wǎng)絡(luò)框架:SimpleNN的文章就介紹到這了,更多相關(guān)C++實現(xiàn)神經(jīng)網(wǎng)絡(luò)框架SimpleNN內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Swift編程中的泛型解析

    Swift編程中的泛型解析

    這篇文章主要介紹了Swift編程中的泛型解析,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • C++圖文并茂分析講解內(nèi)存管理

    C++圖文并茂分析講解內(nèi)存管理

    本章主要介紹C語言與C++的內(nèi)存管理,以C++的內(nèi)存分布作為引入,介紹C++不同于C語言的內(nèi)存管理方式(new delete對比 malloc free),感興趣的朋友來看看吧
    2022-09-09
  • C語言 array數(shù)組的用法詳解

    C語言 array數(shù)組的用法詳解

    數(shù)組是指一組數(shù)據(jù)的集合,(容器)數(shù)組中的每個數(shù)據(jù)稱為元素。在Java中,數(shù)組也是Java對象。數(shù)組中的元素可以是任意類型(包括基本類型和引用類),但同一個數(shù)組里只能存放類型相同的元素
    2021-10-10
  • 如何利用tinyxml操縱xml及注意問題

    如何利用tinyxml操縱xml及注意問題

    這篇博客,我們詳細講述如何利用tinyxml操縱xml。以及在操作的過程中,我們應(yīng)該注意的問題
    2013-01-01
  • C++無痛實現(xiàn)日期類的示例代碼

    C++無痛實現(xiàn)日期類的示例代碼

    凡是要寫類必須要提到六大默認成員(六位大爺):構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值重載函數(shù)、取地址重載函數(shù)(包括const對象和普通對象);那么這次的日期類又需要伺候哪幾位大爺呢?本文就來詳細說說
    2022-10-10
  • Qt創(chuàng)建并顯示柱狀圖的方法

    Qt創(chuàng)建并顯示柱狀圖的方法

    Qt Charts 模塊提供了一套易于使用的圖表組件,本文主要介紹了Qt創(chuàng)建并顯示柱狀圖,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • QT中窗口關(guān)閉自動銷毀的實現(xiàn)示例

    QT中窗口關(guān)閉自動銷毀的實現(xiàn)示例

    這篇文章主要介紹了QT中窗口關(guān)閉自動銷毀,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C語言判定一棵二叉樹是否為二叉搜索樹的方法分析

    C語言判定一棵二叉樹是否為二叉搜索樹的方法分析

    這篇文章主要介紹了C語言判定一棵二叉樹是否為二叉搜索樹的方法,結(jié)合實例形式綜合對比分析了C語言針對二叉搜索樹判定的原理、算法、效率及相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2018-08-08
  • C語言示例代碼講解棧與隊列

    C語言示例代碼講解棧與隊列

    棧和隊列,嚴格意義上來說,也屬于線性表,因為它們也都用于存儲邏輯關(guān)系為?"一對一"?的數(shù)據(jù),但由于它們比較特殊,本章講解分別用隊列實現(xiàn)棧與用棧實現(xiàn)隊列
    2022-05-05
  • 深入理解c++模板中的class與typename

    深入理解c++模板中的class與typename

    在c++Template中很多地方都用到了typename與class這兩個關(guān)鍵字,而且好像可以替換,是不是這兩個關(guān)鍵字完全一樣呢?下面這篇文章主要給大家介紹了關(guān)于c++模板中class與typename的相關(guān)資料,需要的朋友可以參考下。
    2017-07-07

最新評論