项目 | 内容 |
---|---|
这个作业属于哪个课程 | 人工智能实战2019 |
这个作业的要求在哪里 | 第二次作业 - 双变量的反向传播 |
我在这个课程的目标是 | 了解人工智能,提高编程能力 |
这个作业在哪个具体方面帮助我实现目标 | 了解神经网络的基本工作原理,理解线性反向传播 |
迭代的反向传播
代码
w=3
b=4
x = 2*w + 3*b #第一遍运算
y = 2*b + 1
z = x*y
target_z = 150
delta_z = z - target_z
print ("b=",b,"\tw=",w,"\tz=",z,"\tdelta_z=",delta_z)
while (abs(delta_z) >= 1e-5 ):
diff_b = 3*y + 2*x #偏导数
diff_w = 2*y
delta_b = delta_z / diff_b /2
delta_w = delta_z / diff_w /2
b = b - delta_b #修正自变量
w = w - delta_w
x = 2*w + 3*b #修正后距离目标值的偏差
y = 2*b + 1
z = x*y
delta_z = z - target_z
print ("b=",b,"\tw=",w,"\tz=",z,"\tdelta_z=",delta_z)
输出结果
b= 4 w= 3 z= 162 delta_z= 12
b= 3.9047619047619047 w= 2.6666666666666665 z= 150.18140589569163 delta_z= 0.18140589569162557
b= 3.903263272264059 w= 2.661518661518661 z= 150.0000443352674 delta_z= 4.4335267403994294e-05
b= 3.9032629057674404 w= 2.661517402927456 z= 150.00000000000267 delta_z= 2.6716406864579767e-12
不迭代的反向传播
代码
w=3
b=4
x = 2*w + 3*b #第一遍运算
y = 2*b + 1
z = x*y
target_z = 150
delta_z = z - target_z
print ("b=",b,"\tw=",w,"\tz=",z,"\tdelta_z=",delta_z)
diff_b = 3*y + 2*x #偏导数
diff_w = 2*y
while (abs(delta_z) >= 1e-5 ):
delta_b = delta_z / diff_b /2
delta_w = delta_z / diff_w /2
b = b - delta_b #修正自变量
w = w - delta_w
x = 2*w + 3*b #修正后距离目标值的偏差
y = 2*b + 1
z = x*y
delta_z = z - target_z
print ("b=",b,"\tw=",w,"\tz=",z,"\tdelta_z=",delta_z)
print("done!")
print("final_b=",b,"\tfinal_w=",w)
输出结果
b= 4 w= 3 z= 162 delta_z= 12
b= 3.9047619047619047 w= 2.6666666666666665 z= 150.18140589569163 delta_z= 0.18140589569162557
b= 3.903322175431019 w= 2.661627614008566 z= 150.00552613957618 delta_z= 0.005526139576176092
b= 3.903278317180414 w= 2.66147411013145 z= 150.00016964328123 delta_z= 0.0001696432812252624
b= 3.9032769708051664 w= 2.6614693978180823 z= 150.00000520898345 delta_z= 5.2089834525759215e-06
done!
final_b= 3.9032769708051664 final_w= 2.6614693978180823
思考
偏导数是根据当前w、b求出来的,当w、b发生变化的时候,为什么不更新偏导数的值呢?显然每次迭代中重新计算Δb、Δw贡献值,能够提高效率,而且结果更加精确。
此外,w和b对z的影响,简化起见,直接按1:1算。实际上肯定不是1:1,如果按照梯度改变分配比例,效率会更高。