敲开bp神经网络之门(二,mfcc中使用,c#)

写了186篇博客,刚好,家里门牌号186,所以在家里停留很久,现在又出发......

看到一篇bpnet好文章,有一种代码实现的冲动,还是先捋一遍,再代码化:

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

总误差由0.2983降到0.2910,迭代10000次后,输出o1,o2=0.0159,0.984;总误差0.000035085,说明已经收敛到【0.01,0.99】,bpnet学习结束。

我们实现以上过程,进行了简化,少了一个输出,多了两个输入:

敲开bp神经网络之门(二,mfcc中使用,c#)

敲开bp神经网络之门(二,mfcc中使用,c#)

为什么步长要取0.5?这个步长在机器学习中(人工智能)实在太重要,后面我们会专门再讨论他。

程序实现后,验证了上面给出的数据是正确的,然后继续改进,就用到mfcc语音数字特征(输入数据改进为5)的识别了,mfcc又进了一步,了却了心事两件,c#代码如下:

最后改进版,针对mfcc语音数字特征13取5:

   int   number_feature_vectors = (4096 - 256) / 128 + 1;//这是一个很特殊的值
         int m = 0;
            for (int j = 0; j < 5; j++)//mfcc13个数据只使用前面5个输入足够
            {
               
                int temp = 0;
                for (int i = 0; i < number_feature_vectors; i++)//number_feature_vectors=31
                {               
                    //如果(int)feature_vector1[i][0]>0,为有效特征帧,参与训练
                    if(feature_vector2[i][0]>0)
                    {//取[i][0],[i][1],[i][2],[i][3],[i][4]
                        m++;
                        bpnet改进((float)feature_vector2[i][0],(float)feature_vector2[i][1], (float)feature_vector2[i][2], (float)feature_vector2[i][3], (float)feature_vector2[i][4],

ref  weight1, ref weight2, ref weight3, ref weight4, ref weight5, ref weight6,
                            ref weight7, ref weight8, ref weight9, ref weight10, ref weight11, ref weight12);
                    }
                }
               
            }

   void bpnet改进(float input1, float input2, float input3, float input4, float input5, ref float weight1, ref float weight2, ref float weight3, ref float weight4,
           ref float weight5, ref float weight6, ref float weight7, ref float weight8, ref float weight9, ref float weight10, ref float weight11, ref float weight12)
        {//再改进留给数组或list<float>吧
            float i1 = input1;
            float i2 = input2;
            float w1 = weight1;
            float w2 = weight2;
            float w3 = weight3;
            float w4 = weight4;
            float w5 = weight5;
            float w6 = weight6;
            float b1 = 0.35f;
            float b2 = 0.6f;
            double neth1 = 0;
            double neth2 = 0;
            double outh1 = 0;
            double outh2 = 0;
            //增加输入i3,i4和权值w7,w8,w9,w10          
            float i3 = input3;
            float i4 = input4;
            float i5 = input5;
            float w7 = weight7;
            float w8 = weight8;
            float w9 = weight9;
            float w10 = weight10;
            float w11 = weight11;
            float w12 = weight12;
            neth1 = w1 * i1 + w2 * i2 + w7 * i3 + w8 * i4 + w11 * i5+ b1 * 1;
            neth2 = w3 * i1 + w4 * i2 + w9 * i3 + w10 * i4 + w12 * i5 + b1 * 1;
            outh1 = 1 / (1 + Math.Exp(-neth1));
            outh2 = 1 / (1 + Math.Exp(-neth2));
            //hide->out
            double netho1 = outh1 * w5 + outh2 * w6 + b2 * 1;
            double outho1 = 1 / (1 + Math.Exp(-netho1));
            //error
            double etotal = 0;
            double EO = 0.85;//逼近1,但不等于1
            etotal = 0.5 * (EO - outho1) * (EO - outho1);//总误差小于0.00001时认为学习ok,退出,权值学习成功,以后直接使用。
            textBox总误差.Text = etotal.ToString();
            if (etotal < 0.00001) { return; }
            //w5 update
            double 吆西 = -(EO - outho1) * outho1 * (1 - outho1);
            double 吆西1 = outh1 * (1 - outh1);
            double 吆西2 = outh2 * (1 - outh2);
            double etotal对于w5的偏导 = 吆西 * outh1;
            double w5update = w5 - 0.5 * etotal对于w5的偏导;
            weight5 = (float)w5update;
            //w6 update
            double etotal对于w6的偏导 = 吆西 * outh2;
            double w6update = w6 - 0.5 * etotal对于w6的偏导;
            weight6 = (float)w6update;
            //w1 update
            double etotal对于w1的偏导 = 吆西 * w5 * 吆西1 * i1;
            double w1update = w1 - 0.5 * etotal对于w1的偏导;
            weight1 = (float)w1update;
            //w2 update
            double etotal对于w2的偏导 = 吆西 * w5 * 吆西1 * i2;
            double w2update = w2 - 0.5 * etotal对于w2的偏导;
            weight2 = (float)w2update;
            //w7 update
            double etotal对于w7的偏导 = 吆西 * w5 * 吆西1 * i3;
            double w7update = w7 - 0.5 * etotal对于w7的偏导;
            weight7 = (float)w7update;
            //w8 update
            double etotal对于w8的偏导 = 吆西 * w5 * 吆西1 * i4;
            double w8update = w8 - 0.5 * etotal对于w8的偏导;
            weight8 = (float)w8update;
            //w11update
            double etotal对于w11的偏导 = 吆西 * w5 * 吆西1 * i5;
            double w11update = w11 - 0.5 * etotal对于w11的偏导;
            weight11 = (float)w11update;
            //w3 update
            double etotal对于w3的偏导 = 吆西 * w6 * 吆西2 * i1;
            double w3update = w3 - 0.5 * etotal对于w3的偏导;
            weight3 = (float)w3update;
            //w4 update
            double etotal对于w4的偏导 = 吆西 * w6 * 吆西2 * i2;
            double w4update = w4 - 0.5 * etotal对于w4的偏导;
            weight4 = (float)w4update;
            //w9 update
            double etotal对于w9的偏导 = 吆西 * w6 * 吆西2 * i3;
            double w9update = w9 - 0.5 * etotal对于w9的偏导;
            weight9 = (float)w9update;
            //w10 update
            double etotal对于w10的偏导 = 吆西 * w6 * 吆西2 * i4;
            double w10update = w10 - 0.5 * etotal对于w10的偏导;
            weight10 = (float)w10update;
            //w12 update
            double etotal对于w12的偏导 = 吆西 * w6 * 吆西2 * i5;
            double w12update = w10 - 0.5 * etotal对于w12的偏导;
            weight12 = (float)w12update;
        }

上一篇:Python音频信号分类MFCC特征神经网络


下一篇:如何将mfcc向量与注释中的标签组合以传递给神经网络