翻了下以前的blog,08年12月写过一个感知器的程序。一下子已经2011年6月了。期间看过一些bp,cnn,svm的资料,大多是生吞活剥,不甚了了。虽然,现在的热门似乎是贝叶斯,概率,svm。我始终对bp更感兴趣。可能是bp足够简单吧。
真的动手code,还有很长的一段路,走到哪里算哪里了。--2011-6-8
首先是神经元的设计。一个神经元包括输入,输出,权值,传输函数。各个层的神经元有一致的结构。
neuro
{
neuro** pre;
neuro** next;
float output;
float* w;
float b;
int f;
}
输入应该是一既定长度的向量Xn,因此输入前,需要对输入的原始数据做尺度归一化。
设计时输入代表的是一个接口,从这个接口中可以读到输入数据。因此neuro*=pre;是一个指向神经元的指针。
程序将通过指针指向的神经元读取output。 定义中neuro**=pre,是因为输入可以是一个变长的向量。
输出是一个标量,float 类型。不解释。
考虑到网络需要前向传播。,还需要一个指针指向下面的神经元neuro**=next;
有了这两个指针后,神经元爱怎么连就怎么连了。。这种愿景当然只能意淫下。所以说神经网络更像是神经树。
权值w是和输入同长的向量Wn。涉及到初始化和更新的问题。b是一个标量。有些神经元需要共享权值。如cnn中,一个featuremap中的所有神经元共用一个5*5的权值向量。本来想通过共享内存的方式解决,但是我想featuremap,更像是神经元之间的一种协作方式。
因此在神经元外来解决共享的问题。可以定义featuremap为一种协作机制。其实整个bp网络也是一种协作机制。
传输函数f是根据f值到函数表中找的。
神经元是神经网络中的最小单元。
输入层的神经元,f函数为-1,表示不计算output。
网络的保存。一种考虑是用cv::filestorage,另一中是序列化。改天继续。。2011-6-8