感知器收敛但返回奇数结果

奥尔莱根

我用c ++编写了一个简单的感知器来学习AI,甚至读了一本书(pt_br)我也无法使感知器返回预期的结果,我尝试调试并发现错误,但没有成功。

我的算法与门结果(A和B = Y):

0 && 0 = 0 
0 && 1 = 1
1 && 0 = 1
1 && 1 = 1

基本上,它作为“或”门或随机门工作。

我试图跳至Peter Norving和Russel的书,但他对此事进行了深入探讨,没有深入介绍一种感知器训练。

我真的很想学习这些内容的每一寸,所以我不想在不做简单的工作的情况下跳到多层感知器,您能帮上忙吗?

以下代码是操作的基本代码,并带有一些解释:

锐利功能:

int signal(float &sin){
    if(sin < 0)
        return 0;
    if(sin > 1)
        return 1;

    return round(sin);

}

感知器结构(W为重量):

struct perceptron{
    float w[3];
};

感知器训练:

perceptron startTraining(){
    //- Random factory generator
    long int t = static_cast<long int>(time(NULL));
    std::mt19937 gen;
    gen.seed(std::random_device()() + t);
    std::uniform_real_distribution<float> dist(0.0, 1.0);
    //--

    //-- Samples (-1 | x | y)
    float t0[][3] = {{-1,0,0},
                     {-1,0,1},
                     {-1,1,0},
                     {-1,1,1}};

    //-- Expected result
    short d [] = {0,0,0,1};

    perceptron per;

    per.w[0] = dist(gen);
    per.w[1] = dist(gen);
    per.w[2] = dist(gen);

    //-- print random numbers
    cout <<"INIT "<< "W0: " << per.w[0]  <<" W1: " << per.w[1] << " W2: " << per.w[2] << endl;

    const float n = 0.1; // Lerning rate N
    int saida =0;        // Output Y
    long int epo = 0;    // Simple Couter
    bool erro = true;    // Loop control

    while(erro){
        erro = false;
        for (int amost = 0; amost < 4; ++amost) {           // Repeat for the number of samples x0=-1, x1,x2
            float u=0;                                      // Variable for the somatory
            for (int entrad = 0; entrad < 3; ++entrad) {    // repeat for every sinaptic weight W0=θ , W1, W2
                u = u + (per.w[entrad] * t0[amost][entrad]);// U <- Weights * Inputs
            }
            // u=u-per.w[0];                                // some references sau to take θ and subtract from U, i tried but without success
            saida = signal(u);                              // returns 1 or 0
            cout << d[amost] << " <- esperado | encontrado ->   "<< saida<< endl;
            if(saida != d[amost]){                          // if the output is not equal to the expected value
                for (int ajust = 0; ajust < 3; ++ajust) {
                    per.w[ajust] = per.w[ajust] + n * (d[amost] - saida) * t0[amost][ajust]; // W <- W + ɳ * ((d - y) x) where
                    erro = true;                                                             // W: Weights, ɳ: Learning rate
                }                                                                            // d: Desired outputs, y: outputs
            }                                                                                // x: samples
            epo++;

        }
    }
    cout << "Epocas(Loops): " << epo << endl;
    return per;
}

主要与测试部分:

int main()
{
    perceptron per = startTraining();
    cout << "fim" << endl;
    cout << "W0: " << per.w[0]  <<" W1: " << per.w[1] << " W2: " << per.w[2] << endl;
    while(true){
        int x,y;
        cin >> x >> y;

        float u=0;
        u = (per.w[1] * x);
        u = u + (per.w[2] * y);
        //u=u-per.w[0];

        cout << signal(u) << endl;


}
    return 0;
}
索恩加德

在中main(),重新启用您注释掉的行。另外,您可以这样写,使其更具启发性:

float u = 0.0f;

u += (per.w[0] * float (-1));
u += (per.w[1] * float (x));
u += (per.w[2] * float (y));

事情是,您用三个输入来训练感知器,第一个被硬连线到“ -1”(使第一个权重w[0]像一个恒定的“ bias”)。因此,在您的训练功能中,您u就是那三项重量输入产品的总和。但是,在发布的main()中,您完全省略了w [0],从而产生了错误的结果。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章