BP简单反向传播 Python和C语言实现

原创
01/10 14:12
阅读数 619
# 反向传播: Python版本

import numpy as np

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

def sigmoidDerivationx(x):
    x = sigmoid(x)
    return x * (1.0 - x)

if __name__ == "__main__":
    # 初始化
    x = [0.457612, 0.859165]

    y = [0.876594, 0.582614]

    w = [[0.471232, 0.235498],
         [0.577832, 0.781413]]

    b = [0.373267, 0.891235]

    row = len(w)
    print('row = %d' % row)

    col = len(w[0])
    print('col = %d' % col)

    o = [0.0] * row

    lr = 0.5        # 学习速率
    epochs = 3000   # 迭代次数

    for epoch in range(epochs):
        # forward
        for j in range(col):
            o[j] = 0.0
            for i in range(row):
                z = w[i][j] * x[i] + b[i]
                o1 = sigmoid(z)
                o[j] += o1
            #print('%f '%o[j])

        # backward
        dpb = 0.0
        for i in range(row):
            for j in range(col):
                dpW = (o[j] - y[j]) * sigmoidDerivationx(o[j]) * x[i]
                w[i][j] -= lr * dpW

            dpb += (o[i] - y[i]) * sigmoidDerivationx(o[i]) * row
            b[i] -= lr * dpb

    for i in range(row):
        for j in range(col):
            print('%f ' % w[i][j], end='')
        print(' %f ' % b[i])

    predOutput = 0.0

    for j in range(col):
        o[j] = 0.0
        for i in range(row):
            z = w[i][j] * x[i] + b[i]
            o1 = sigmoid(z)
            o[j] += o1

        print('%f, %f'%(o[j], y[j]))
        predOutput += 0.5 * pow(y[j] - o[j], 2)

    print('loss = %f' % predOutput)
// 反向传播: C语言版本

#include <stdio.h>
#include <math.h>

#define ROW 2
#define COL 2

double sigmoid(double x)
{
    return 1.0 / (1.0 + exp(-x));
}

double sigmoidDerivationx(double x)
{
    x = sigmoid(x);
    return x * (1.0 - x);
}

int main(void)
{
    //初始化
    double x[ROW] = { 0.457612, 0.859165 };
    double y[ROW] = { 0.876594, 0.582614 };
    double w[ROW][COL] = { {0.471232, 0.235498},
                           {0.577832, 0.781413} };
    
    double b[ROW] = { 0.373267, 0.891235 };
    double o[ROW] = { 0.0, 0.0 };

    double lr = 0.5;      // 学习速率
    int epochs = 3000;    // 迭代次数
    int i, j;
    double z, o1;
    
    for (int epoch = 0; epoch < epochs; ++epoch)
    {
        // forward
        for(j = 0; j < COL; ++j)
        {
            o[j] = 0.0;
            for(i = 0; i < ROW; ++i)
            {
                z = w[i][j] * x[i] + b[i];
                o1 = sigmoid(z);
                o[j] += o1;
            }

            //printf("%lf ", o[j]);
        }
        //printf("\n");

        // backward
        double dpb = 0.0;
        for(i = 0; i < ROW; ++i)
        {
            for(j = 0; j < COL; ++j)
            {
                double dpW = (o[j] - y[j]) * sigmoidDerivationx(o[j]) * x[i];
                w[i][j] -= lr * dpW;
            }
            
            dpb += (o[i] - y[i]) * sigmoidDerivationx(o[i]) * ROW;        
            b[i] -= lr * dpb;        
        }        
    }

    for(i = 0; i < ROW; ++i)
    {
        for(j = 0; j < COL; ++j)
        {
            printf("%lf ", w[i][j]);
        }
        
        printf("%lf\n", b[i]);
    }

    double dLoss = 0.0;

    for(j = 0; j < COL; ++j)
    {
        o[j] = 0.0;
        for(i = 0; i < ROW; ++i)
        {
            z = w[i][j] * x[i] + b[i];
            o1 = sigmoid(z);
            o[j] += o1;
        }
    
        printf("%lf, %lf\n", o[j], y[j]);
        dLoss += 0.5 * pow(y[j] - o[j], 2.0);
    }
    
    printf("loss = %lf\n", dLoss);
    return 0;
}
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部