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

01/10 14:12

# 反向传播: 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