神经网络解决的问题是有确定的输入和输出,但是决定输入和输出的函数不清楚,通过神经网络的训练最终得出输入和输出之间的函数关系,从而使得机器具备了归纳推广的能力。比如:y=ax这样一个函数,x和y确定,但是系数a是多少不清楚,神经网络就是解决这个问题的,通过不断的训练,找到最合适的系数a,然后这个函数关系就确定了。以后不管再输入任何x都会有准确的y输出。
前馈网络由以下几个部分组成:
一、神经元:
struct SNeuron
{
intm_iInputNumbers;
vectorm_vecWeight;
SNeuron(intinput);
};
神经元由输入数量和权重向量组成。输入数量决定了这个神经元有多少个输入,同时初始化相同数量的(-1,1)之间的随机数作为权重。
SNeuron::SNeuron(intinput):m_iInputNumbers(input+1)
{
for(int i=0;i
{
m_vecWeight.push_back(RandomClamped());
}
}
此处input为什么要+1,原因是:
权重*输入的累加得到activation:w1*x1+w2*x2,,,,,,+wn*xn=activation,当activation大于某个阈值t时,网络回输出1,小于阈值t,网络输出。由于所有的权重都要不断的演化,阈值也会跟随进化,所以可以把阈值t也看成一个权重,也就是:
w1*x1+w2*x2,,,,,,+wn*xn>t,
w1*x1+w2*x2,,,,,,+wn*xn+(-1)t>0
阈值t就可以看成是一个输入固定为-1的权重,所以我们在神经元的输入input要加上一个1.
二、神经细胞层:
struct SNeuronLayer
{
intm_iNeuronNumbers;
vectorm_vecNeurons;
SNeuronLayer(intneuron,int inputperneuron);
};
SNeuronLayer::SNeuronLayer(intneuron,int inputperneuron):m_iNeuronNumbers(neuron)
{
for(int i=0;i
{
m_vecNeurons.push_back(SNeuron(inputperneuron));
}
}
多个神经元组成一个神经细胞层。
三、神经网络:
class CNeuralNet
{
private:
intm_iInputNumbers;
intm_iOutputNumbers;
intm_iHiddenLayersNumbers;
intm_iNeuronPerLayers;
vectorm_vecNet;
private:
voidCreateNet();
public:
inlinedouble Sigmoid(double activation,double response)
public:
CNeuralNet(void);
~CNeuralNet(void);
voidPutWeights(vector& weights);
vectorUpdate(vector& input);
vectorGetWeight()const;
intGetNumberOfWeight()const;
};
网络生成函数:
voidCNeuralNet::CreateNet()
{
if(m_iHiddenLayersNumbers>0)
{
m_vecNet.push_back(SNeuronLayer(m_iNeuronPerLayers,m_iInputNumbers));
for(inti=0;ii++)
{
m_vecNet.push_back(SNeuronLayer(m_iNeuronPerLayers,m_iNeuronPerLayers));
}
m_vecNet.push_back(SNeuronLayer(m_iOutputNumbers,m_iNeuronPerLayers));
}else
{
m_vecNet.push_back(SNeuronLayer(m_iOutputNumbers,m_iInputNumbers));
}
}
如果隐藏层大于,就要一层一层建立网络,如果没有隐藏层,就直接输入对输出。这样一个网络就建成了。下面就是给每一个节点赋予权重:
voidCNeuralNet::PutWeights(vector&weights)
{
intpos=0;
for(inti=0;ii++)
{
for(intj=0;ji].m_iNeuronNumbers;j++)
{
for(intk=0;ki].m_vecNeurons[j].m_iInputNumbers;k++)
{
m_vecNet[i].m_vecNeurons[j].m_vecWeight[k]=weights[pos++];
}
}
}
}
下面是取出权重和权重数量:
vectorCNeuralNet::GetWeight()const
{
vectorweight;
for(inti=0;ii++)
{
for(intj=0;ii].m_iNeuronNumbers;j++)
{
for(intk=0;ki].m_vecNeurons[j].m_iInputNumbers;k++)
{
weight.push_back(m_vecNet[i].m_vecNeurons[j].m_vecWeight[k]);
}
}
}
returnweight;
}
intCNeuralNet::GetNumberOfWeight()const
{
intnum=0;
for(inti=0;ii++)
{
for(intj=0;ji].m_iNeuronNumbers;j++)
{
for(intk=0;ki].m_vecNeurons[j].m_iInputNumbers;k++)
{
num++;
}
}
}
returnnum;
}
最后是神经网络的大脑,真正的运算在这里:
vectorCNeuralNet::Update(vector& input)
{
vectoroutputs;
intpos=0;
if(m_iInputNumbers!=input.size())
{
returnoutputs;
}
for(int i=0;i
{
{
input=outputs;
}
outputs.clear();
pos=0;
for(int j=0;j
{
doublenetinput=0;
intnuminput=m_vecNet[i].m_vecNeurons[j].m_iInputNumbers-1;
for(int k=0;k
{
netinput+=m_vecNet[i].m_vecNeurons[j].m_vecWeight[k]*input[pos++];
}
netinput-=m_vecNet[i].m_vecNeurons[j].m_vecWeight[numinput];
outputs.push_back(Sigmoid(netinput,CParams::ActivationResponse));
pos=0;
}
}
returnoutputs;
}
领取专属 10元无门槛券
私享最新 技术干货