问题形容
咱们的问题是四个人,甲、乙、丙、丁,上面是他们之前去不去看电影的数据:
当初的问题是,如果下次能够确定:甲去、乙去、丙不去,那么丁去的概率是多少?
单节点神经网络
咱们的模型如下:
x1、x2、x3 别离示意甲、乙、丙去不去的值,去就是 1,不去是 0。输入 y 示意丁去不去的值。
其中 w1、w2、w3 别离示意甲、乙、丙的权重,激活函数应用的是 sigmoid,也就是:
权重进行随机,而后利用已知的值进行训练,不停调整权重,最终,把须要求解的数据输出获取后果即可。
代码实现
// 曾经产生的事件,作为训练种子
let seedData = [
// 甲、乙、丙、丁去不去,0 示意不去,1 示意去
[0, 0, 1, 0], // 第一次
[1, 1, 1, 1], // 第二次
[1, 0, 1, 1], // 第三次
[0, 1, 1, 0] // 第四次
];
// 甲、乙、丙去不去对丁影响的权重的初始随机值: -1 ~ 1
let weights = [Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1];
// 循环应用屡次种子进行训练
for (let i = 0; i < 10000; i++) {
// 每次循环都利用一遍所有的种子
for (let j = 0; j < seedData.length; j++) {
// 应用 sigmoid 激活函数
// y = 1/(1+exp(-x))
let output = 1 / (1 + Math.exp(-1 * (seedData[j][0] * weights[0] + seedData[j][1] * weights[1] + seedData[j][2] * weights[2])));
// 对甲、乙、丙的权重别离进行调整
for (let k = 0; k < 3; k++) {
// 而后求解和理论值的差距
let error = seedData[j][3] - output;
// 每次求解结束后,依据差距 error 进行调整权重 weights
/**
* 在这里,调整的幅度取决于“差距”和“后果”*
* 1. 差距越大,调整的幅度也越大
* 2. 对后果而言,output * (1 - output) 是一个二次函数,如果后果越凑近 0 或 1,幅度越小,反之越大
*/
let delta = error * output * (1 - output);
weights[k] += seedData[j][k] * delta;
}
}
}
let input = [1, 0, 0];
console.log(weights);
console.log(1 / (1 + Math.exp(-1 * (input[0] * weights[0] + input[1] * weights[1] + input[2] * weights[2])))
);
答疑
对于权重调整为什么要乘上输出值的了解?
weights[k] += seedData[j][k] * delta;
能够看见,权重的调整最终减少的值是 seedData[j][k] * delta
为什么?
delta 的值和 error 的正负性上保持一致,激活函数是枯燥递增的,如果 error 大于 0,那么调整后激活函数的输出应该变大,可是输出可能大于 0 也可能小于 0,怎么办?
如果减少的权重乘上输出,那么理论激活函数输出的扭转就是:
seedData[j][k] * seedData[j][k] * delta = seedData[j][k] 的平方 * delta
也就是扭转量的正负和 delta 保持一致,这样,目标就达到了。