在nodejs中运行
// 数据集
var datas = [
[[0, 0], 0],
[[0, 1], 1],
[[1, 0], 1],
[[1, 1], 1],
];
// 初始化权重值
var weights = [];
for (var i = 0; i < datas[0][0].length + 1; i++) {
// 有正有负
weights[i] = Math.random() - 0.5;
}
//计算
function calcOutput(inputs) {
// 最后一个为偏执
return sigmoid(inputs[0] * weights[0] + inputs[1] * weights[1] + weights[2]);
}
// sigmoid函数
function sigmoid(x) {
return 1 / (1 + Math.pow(Math.E, -x));
}
// 计算误差
function errRate(output, excepted) {
return Math.abs(output - excepted);
}
// 尝试调整权限
var num = 1; //计数
var d = 0.000001; //微调值
var trainRate = 0.1; //训练率(训练速度)
var threshold = 0.001; //设置停止条件
function train(inputs, excepted) {
var dw = [];
// 微调前计算误差
var err = errRate(calcOutput(inputs), excepted);
// 误差微调
weights.forEach(function (w, i) {
weights[i] += d;
// 微调后计算误差
var err2 = errRate(calcOutput(inputs), excepted);
// 微调产生的效果进行记录
dw[i] = (err2 - err) / d;
//权重值复位
weights[i] = w;
});
// 调整权重
weights.forEach(function (w, i) {
weights[i] -= dw[i] * trainRate;
});
// 打印错误率
num++;
if (num % 500 == 0) {
//设置运行多少次打印一次
console.log(calcError(err));
}
return calcError(err);
}
// 训练过程可视化
// 计算最近n次错误率的平均值
var errors = [];
var maxError = 20;
function calcError(err) {
errors.push(err);
if (errors.length > maxError) {
errors.shift();
}
return errors.reduce((tmp, item) => tmp + item) / errors.length;
}
for (var i = 0; ; i++) {
// 有限数据集重复训练
var data = datas[i % datas.length];
if (train(data[0], data[1]) <= threshold) {
break;
}
}
console.log(weights);