#coding: utf8 import math # x1, x2输入神经元 x1=1 x2=2 # w1,w2分别为x1,x2的权重 w1=0.2 w2=0.3 # b为输出神经元的偏移量 b = 0.1 target = 1 # 目标值 def f(w1, w2, b): return x1 * w1 + x2 * w2+ b def loss(x, target): return (target - x) ** 2 def printInfo(): print('w1:', w1) print('w2:', w2) print('b:', b) o1 = f(w1, w2, b) print('f(w1, w2, b):', o1) o1 = math.tanh(o1) print('激活输出:', o1) print('损失值:', loss(o1, target)) print('----------------') printInfo() # 核心问题:如果降低损失? 其实就是让损失函数的输出变小 # 那么就变成数学题了,如何求一个函数的极小值 # 数学理论: # 要求一个函数的极小值,可以使用求导数的方法,具体步骤如下: # 1. 对函数进行求导,得到其导函数。 # 2. 将导函数等于0的解作为函数的极值。 # 3. 判断左正右负极大值,左负右正极小值 # 根据上面的步骤操作 # 第1步: loss 的导函数 def lossGrad(x): # return -2*(1-x) return 2*x-2 # 第2步 lossGrad(x) = 0 ->解得 x = 1 # 第3步 lossGrad(0)=-2 lossGrad(2)=2 属于左负右正极小值,那么x=1时loss函数有极小值 # 其实第三步还有一个小技巧,就是对lossGrad再次求导,得到常数2。 大于0就是极小值。 不懂的同学可以补习下这块知识 # 回到核心问题,如果降低损失? 目标变成了怎么让x=1. 即怎么让tanh的值为1, 可惜tanh的值域不包括1, 那么我们尽可能接近它 # 我们求反函数就可以知道,math.atanh(0.9999) = 4.9517 # 现在问题就又变成了 如何让 x1*w1 + x2*w2 + b = 4.9517 # 其实就是怎么调整 w1 w2 和 b 三个变量的值,使其尽可能输出向4.9517靠拢 # 目标:f(w1, w2, b) = 4.9517 看到这个玩意我知道有很多解,但是没法直接求,所以只能一点一点迭代接近它了。后面训练网络模型的时候其实就是调整所有的w和b # 一个三元函数怎么接近这个4.9517它, 又变成一个数学问题, 求这个三元函数的导函数(也就是偏导数) # 这个分别求导得到: def fGradW1(): return x1 def fGradW2(): return x2 def fGradB(): return 1 # 根据求导结果可知,导函数都是常数 # 当前的损失值 lossTmp = f(w1, w2, b) - 4.9517 print('当前损失值:', lossTmp) w1 = w1 - 0.01 * fGradW1() * lossTmp w2 = w2 - 0.01 * fGradW2() * lossTmp b = b - 0.01 * fGradB() * lossTmp lossTmp = f(w1, w2, b) - 4.9517 print('当前损失值:', lossTmp) w1 = w1 - 0.01 * fGradW1() * lossTmp w2 = w2 - 0.01 * fGradW2() * lossTmp b = b - 0.01 * fGradB() * lossTmp lossTmp = f(w1, w2, b) - 4.9517 print('当前损失值:', lossTmp) w1 = w1 - 0.01 * fGradW1() * lossTmp w2 = w2 - 0.01 * fGradW2() * lossTmp b = b - 0.01 * fGradB() * lossTmp lossTmp = f(w1, w2, b) - 4.9517 print('当前损失值:', lossTmp) w1 = w1 - 0.01 * fGradW1() * lossTmp w2 = w2 - 0.01 * fGradW2() * lossTmp b = b - 0.01 * fGradB() * lossTmp lossTmp = f(w1, w2, b) - 4.9517 print('当前损失值:', lossTmp) printInfo() # 从前面几次迭代可以看出,损失值在不断减小 # 现在把这个迭代过程分装成一个函数 def train(n): global w1, w2, b for i in range(n): lossTmp = f(w1, w2, b) - 4.9517 w1 = w1 - 0.01 * fGradW1() * lossTmp w2 = w2 - 0.01 * fGradW2() * lossTmp b = b - 0.01 * fGradB() * lossTmp train(100) printInfo()
从结果看出已经损失值已经无限接近0了, 还是非常完美, 这个是数学分析后,一点一点拼凑出来的代码,下一篇将对这个代码进行归纳
标签:lossTmp,0.01,雏形,反向,w2,w1,print,前向,4.9517 From: https://www.cnblogs.com/dzqdzq/p/17255765.html