写在前面:
上一个学期一直都在看deep learning的一些理论知识,着重看了一些关于卷积神经网络(convolutional neural network)。趁现在暑假,时间比较充裕写点程序完善一下之前看的知识。
先给大家上点开胃菜,这两天写了个可扩展的多层神经网络,里面没什么新东西,没rbm也没卷积,就是一个普普通通的神经网络,写完这个再打算写卷积神经网络。
这个程序是基于反向传播算法写的,不熟悉的同学可以看下UFLDL 里面关于bp的那一部分,我是基于那一部分讲解写得程序 ,当然这个程序写得还是比较简陋的,只把bp的大概框架搭了起来,应该比较容易各位初学者的理解。
程序一共可以分为三个部分:NeuralNetwork主要用来确定整个网络的结构,以及训练的测试;HiddenLayer部分顾名思义就是中间层,每个对象是一层,所以可以堆叠起来构建一个深层的网络;最后一个部分是LogisticRegressionLayer,是整个网络的最后一层,我采用了比较常用的softmax来进行误差计算。
NeuralNetwork.h
#include "HiddenLayer.h"
#include "LogisticRegressionLayer.h"
class NeuralNetwork
{
public:
NeuralNetwork(int n, int n_i, int n_o, int nhl, int*hls);
~NeuralNetwork();
void train(double** in_data, double** in_label, double lr, int epochs);
void predict(double** in_data, int n);
private:
int N; //样本数量
int n_in; //输入维数
int n_out; //输出维数
int n_hidden_layer; //隐层数目
int* hidden_layer_size; //中间隐层的大小 e.g. {3,4}表示有两个隐层,第一个有三个节点,第二个有4个节点
HiddenLayer **sigmoid_layers;
LogisticRegressionLayer *log_layer;
};
NeuralNetwork.cpp
#include <iostream>
#include "NeuralNetwork.h"
using namespace std;
NeuralNetwork::NeuralNetwork(int n, int n_i, int n_o, int nhl, int *hls)
{
N = n;
n_in = n_i;
n_out = n_o;
n_hidden_layer = nhl;
hidden_layer_size = new int [n_hidden_layer];
hidden_layer_size = hls;
//构造网络结构
sigmoid_layers = new HiddenLayer* [n_hidden_layer];
for(int i = 0; i < n_hidden_layer; ++i)
{
if(i == 0)
{
sigmoid_layers[i] = new HiddenLayer(n_in, hidden_layer_size[i]);//第一个隐层
}
else
{
sigmoid_layers[i] = new HiddenLayer(hidden_layer_size[i-1], hidden_layer_size[i]);//其他隐层
}
}
log_layer = new LogisticRegressionLayer(hidden_layer_size[n_hidden_layer-1], n_out);//最后