机器学习0003 简单神经元

来源:互联网 发布:三网合一cms 编辑:程序博客网 时间:2024/05/01 01:35


机器学习0003 简单神经元


我们从学前班开始接触数学,小学学习了一元一次方程,初中开始学习了一次函数二次函数和多元方程二次方程,高中和大学学了更多关于方程和函数的知识,特别是高等数学中,讲述了函数和方程更深入的知识。也许每一个有思想的人都曾思考过:学这些有什么用?实际上,数学很有用,可以解决各种生活中的问题:买菜,最优化问题,游戏...对于某些编程语言来说,万事万物皆为对象。对于数学来说:万事万物皆为函数。自由落体s=0.5gt*t,匀速运动 s=vt,价格=单价*数量还有很多,我们要相信数学可以解决任何问题。前几天同事玩了一款很复杂的游戏,有一关很难。我看了这个游戏后发现可以抽象成“图”(这个图是图论中的概念,图论是数学中很重要的一个分支),然后就顺利的把这一关过去了。

如果我知道神经网络中用的数学知识很多,当年一定会好好学习高数,概率论的,数到用时方恨少。看了我上面的一段描述,你可能一头雾水,还不明白我想干嘛。上面说,一切问题是函数问题,我们通过函数可以解决任何问题。但是这和神经网络,神经元有什么关系,看下面的解释:


我们都知道鸡兔同笼问题(不知道的看这里:鸡和兔子共处一个笼子,一共有10个头,30条腿,问鸡有多少只?),是一个很经典的数学问题,对于很多小学生来说,这仍然是一个难题,在这里我们就用简单的神经元来解决这个困扰部分小学生的问题。


正常做法有很多中,这里只写一种:

设鸡有x,兔子有y

x+y=10

2x+4y=30

解得x=5,y=5



一个神经元的解法:


1.什么是神经元


画了一个简单的丑图,将就看一下吧:


这就是一个简单的神经元。3,12,5是输入的数据,神经元中有一些数字这些数字w0,w1,w2...wn,其中w0是偏置,w1到wn是权重。只需要让对应的输入和对应的权重相乘再相加上w0即可,f(x)是对结果进行处理,被称为激活函数。激活函数决定了神经元的类型。

假设

数据是 A:a1,a2,a3...an

权重是W:w1,w2,w3...wn

偏置是w0

神经元的输出是:

f(a1*w1+a2*w2+...+ai*wi+...an*wn  + w0)

很简单吧。

我们这里的激活函数 f(x)=x ,此外还有其他类型的激活函数,f(x)=max(0,x)    f(x)=1/(1+e^-x)等,理论上任何可导函数都可以做为激活函数。


2.现在问题转换成了


现在我们的任务是求w0,w1,w2的值应该是多少


3.计算权重和偏置

(1)首先给权重和偏置随机初始化成几个接近0的数字

w0=0.3

w1=-0.2

w2=0.1

(2)计算结果

产生新的头数,脚数和鸡数

res=头数*w1+脚数*w2+w0

e=鸡数-res

e代表输出和实际结果的差值

(3)更新权值和偏置

 e的值有3种:

注意:ai代表神经元的第i个输入

<1> e>0,表示神经元的输出太小了,需要增大输出,这时wi的变化是

    如果ai>0

    wi=e*ai+wi 这时e和ai是正数,wi*ai增加会使神经元输出结果增大一些

    如果ai<0

    wi=e*ai+wi ai小于0,e大于0,wi减小,wi*ai增大

    如果ai=0,该权重对结果没有影响

    wi=e*ai+wi  ai=0 -----> wi=wi

<2> e=0,表示神经元的输出和实际结果没有差异,不需要更新权重

    wi=e*ai+wi 其中e=0 ----->wi=wi

<3> e<0,表示神经元的输出太大了,需要减小输出,这时wi的变化是

    如果ai>0

    wi=e*ai+wi     e<0 , ai>0 , e*ai<0 ,  wi会减小 wi*ai会减小

    如果ai<0

    wi=e*ai+wi     e<0 , ai<0  ,  e*ai>0,wi会增大, wi*ai会减小 

    如果ai=0,该权重对结果没有影响

    wi=e*ai+wi  ai=0 -----> wi=wi

综上所述 wi=e*ai+wi

对于w0的处理,我们需要补充一个a0

a1*w1+a2*w2+...+ai*wi+...an*wn  + w0

由上面式子变成a1*w1+a2*w2+...+ai*wi+...an*wn  + a0*w0,显然a0=1

这样w0=e*a0+w0


(4)重复(2)(3)(4)操作直到结果非常逼近正确答案


4.下面是python对上面的算法进行实现


#鸡兔同笼import random as rd#(1)随机初始化神经元权值w0=0.3w1=-0.2w2=0.1for i in range(10000):        #这里是循环2,3操作        #(2)计算结果    #<1>产生正确的头数heads,脚数legs和鸡的数量chickens    #兔子数量    rabbit=rd.randint(0,10)    #鸡的数量    chickens=rd.randint(0,10)        #头的数量    heads=rabbit+chickens    #腿的数量    legs=rabbit*4+chickens*2            #<2>计算神经元输出结果,和正确结果的差值    a1=heads    a2=legs        res=a1*w1+a2*w2+w0    e=chickens-res    #这里对e做了限制避免对权重影响过大    if e>1.0:        e=1.0    elif e<-1.0 :        e=-1.0;    e*=0.001        #(3)更新权值和偏置    w1=e*a1+w1    w2=e*a2+w2    a0=1    w0=e*a0+w0    #已经训练完毕了,下面开始使用#鸡和兔子共处一个笼子,一共有10个头,30条腿,问鸡有多少只?heads=10legs=30a1=headsa2=legsres=a1*w1+a2*w2+w0print(res,w0,w1,w2)#某几次运行输出
5.073595116899521 0.11500408173399584 1.991363016946072 -0.4985013044765065
4.96734930028768 0.11104094502477757 1.9890304126201197 -0.5011331923646098
4.991091991393172 0.10861962962525538 1.9875744051914601 -0.4997757230048895我们只需要对结果进行四舍五入,res=5
ok了



原创粉丝点击