tiny_cnn实现了LeNet的字符识别功能,实现的方式也是利用卷集神经网络,整个网络共有6层,依次为convolution_layer<32,32,5,1,6>,average_pooling_layer<28,28,6,2>,
convolution_layer<14,14,5,6,16,connection_table>,average_pooling_layer<10,10,16,2>,convolution_layer<5,5,5,16,120>,fully_connected_layer<120,10>。
首先,第一层:convolution_layer<32,32,5,1,6>是对输入图像进行卷积,卷积核的大小是5x5,对输入图像使用了6个不同的卷积和分别进行卷积,目的是提取输入图像的不同特征,最后得出6个不同的输出。
第二层:average_pooling_layer<28,28,6,2>是对第一层的输出进行下采样,第一层的输出是28x28的数据,这里使用2x2的窗口对其进行求均值,然后下采样,得出14x14的输出。
第三层:convolution_layer<14,14,5,6,16,connection_table>,是再次对第二层的输出进行卷积,卷积核仍然采用的是5x5的窗口,这层的卷积是用一定规定的,这一层共有16个卷积核,每一个卷积核分别与多个输入相连,所以这里会有一个connection_table来标记每个卷积与对应的哪些输入相连接,connection_table的数据如下:
#define O true
#define X false
static const bool connection [] = {
O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O,
O, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O,
O, O, O, X, X, X, O, O, O, X, X, O, X, O, O, O,
X, O, O, O, X, X, O, O, O, O, X, X, O, X, O, O,
X, X, O, O, O, X, X, O, O, O, O, X, O, O, X, O,
X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O
};
#undef O
#undef X
第四层:average_pooling_layer<10,10,16,2>,这一层的输入就是前一层的10x10的输出,16表示输入的个数,同样下采样窗口还是用2x2的窗口,采样的输出就是16个5x5的输出。
第五层:convolution_layer<5,5,5,16,120>,这里的输入就是16个5x5的数据,然后继续利用窗口为5x5的卷积核对其进行卷积,这一层共有120个卷积核,而且每个卷积核都和16个输入想连接,最终的输出是120个1x1的输出。
第六层:fully_connected_layer<120,10>,这一层是一个普通的BP神经网络,这层网络中的每个神经元都和所有的120个输入相连接,最后的输出个数是10个,用来表示0到9的数字。
网络的整体架构到这里就已经完成,下面要做的就是对网络进行训练,训练主要就是怎么求梯度,求出梯度之后利用什么算法作optimization,这一部分留作以后总结。