1 class CNNlayer 2 { 3 private: 4 CNNlayer* preLayer; 5 vector<CNNneural> m_neurals; 6 vector<double> m_weights; 7 public: 8 CNNlayer(){ preLayer = nullptr; } 9 // 创建卷积层 10 void createConvLayer(unsigned curNumberOfNeurals, unsigned preNumberOfNeurals, unsigned preNumberOfFeatMaps, unsigned curNumberOfFeatMaps); 11 // 创建 普通层 12 void createLayer(unsigned curNumberOfNeurals,unsigned preNumberOfNeurals); 13 void backPropagate(vector<double>& dErrWrtDxn, vector<double>& dErrWrtDxnm, double eta); 14 };
创建普通层,在前面介绍的多层神经网络中已经给出过,它接收两个参数,一个是前面一层结点数,一个是当前层结点数。
而卷积层的创建则复杂的多,所有连结线的索引值的确定需要对整个网络有较清楚的了解。这里设计的createConvLayer函数,它接收4个参数,分别对应,当前层结点数,前一层结点数,前一层特征图的个数和当前层特征图像的个数。
下面是C++代码,要理解这一部分可以会稍有点难度,因为特征图实际中都被按列展开了,所以邻域这个概念会比较抽象,我们考虑把特征图像还原,从图像的角度去考虑。
1 void CNNlayer::createConvLayer 2 (unsigned curNumberOfNeurals, unsigned preNumberOfNeurals, unsigned preNumberOfFeatMaps, unsigned curNumberOfFeatMaps) 3 { 4 // 前一层和当前层特征图的结点数 5 unsigned preImgSize = preNumberOfNeurals / preNumberOfFeatMaps; 6 unsigned curImgSize = curNumberOfNeurals / curNumberOfFeatMaps; 7 8 // 初始化权重 9 unsigned numberOfWeights = preNumberOfFeatMaps*curNumberOfFeatMaps*(5 * 5 + 1); 10 for (unsigned i = 0; i != numberOfWeights; i++) 11 { 12 m_weights.push_back(0.05*rand() / RAND_MAX); 13 } 14 // 建立所有连结线 15 16 for (unsigned i = 0; i != curNumberOfFeatMaps; i++) 17 { 18 unsigned imgRow = sqrt(preImgSize); //上一层特征图像的大小 ,imgRow=imgCol 19 // 间隙2进行取样,邻域周围25个点 20 for (int