初尝二分类神经网络

mac2024-12-22  48

二分类神经网络

初次接触到神经网络,在略知一二的情况下,初步实现了神经网络的目标二分类。

简单神经网络结构

神经网络一般分为输入层,隐藏层和输出层三层。具体结构网上随处可见,这里便不再赘述。直接上最基础的神经网络结构图。也是本次实现二分类的网络结构。 这个简单的神经网络由3个感知器搭建而成,其中一层输入层,一层隐藏层,一层输出层。 接下来说一说具体的传播方法。

前向传播

简单来说,前向传播就是将每一层的输入向量与其待定权值矩阵相乘,可以理解为每个输入与对应权值相乘后线性叠加作为输出。如上图结构中,前向传播可以表示为: L1=W1X+W3Y+B1 L2=W2X+W4Y+B1 T=L1W5+L2W6+B2 这样看来,是不是就是简单的线性叠加呢,答案是肯定的。因此,如果面对非线性问题,这个网络就尴尬了。因此不得不引入一个东西----激活函数。你可以理解为是将线性结构非线性化的一个过程。当然他可以将输出映射到0~1之间等的功能,这取决于不同的激活函数。 本例使用的激活函数:f(x)=1/1+e^(-x) 这样每一次感知器输出结果经过激活后,在叠加,就变成非线性的咯。 将上式没行下增加激活函数即可。例如L1`=1/1+E^(-L1) 如此,一次前向传播结束。

损失函数

理解为误差即可。在监督学习中,就是可以看作前向传播输出值和实际真实值之间的偏差。 最简单的为:E=(R-T)^2 其中R为真实值,T为输出值。就是方差啦。 当然他会有不少弊端。而在二分类中,常用的损失函数一般为交叉熵。 公式:E=-(RlnT+(1-R)ln(1-T)) 具体推导可自行百度

反向传播

反向传播也就是网络的学习过程,将前向传播获得的损失值,计算在对应权值上的偏导值作为更新量。具体理论可以参看梯度下降法,是对这个的直观解释哦。 具体代码: ww[0]=ww[0]-xxl*(z-tt)*w[4]l1(1-l1)x ww[2]=ww[2]-xxl(z-tt)*w[4]l1(1-l1)y ww[1]=ww[1]-xxl(z-tt)w[5]l2(1-l2)x ww[3]=ww[3]-xxl(z-tt)w[5]l2(1-l2)y bb[0]=bb[0]-xxl(z-tt)(w[4]l1(1-l1)+w[5]l2(1-l2)) ww[4]=ww[4]-xxl(z-tt)l1 ww[5]=ww[5]-xxl(z-tt)l2 bb[1]=bb[1]-xxl(z-tt) 就不敲公示了,上面是代码中反向传播的公式,其中xxl表示学习率(原谅我用拼音首字母),可以人为设置。(z-tt)为损失函数对应输出的偏导,可以自行验证。后面相乘量都是对应权值路径上的偏导计算值。 具体百度反向传播算法,基本很明确了。

上全部python代码

import matplotlib.pyplot as plt import numpy as np import math

x=y=l1=l2=z=e=0.0 w=np.random.random(6) b=np.random.random(2)

def gofront(xx,yy): x=xx y=yy l1=w[0]*x+w[2]*y+b[0] l1=1/(1+math.exp(-l1)) l2=w[1]x+w[3]y+b[0] l2=1/(1+math.exp(-l2)) z=l1w[4]+l2w[5]+b[1] z=1/(1+math.exp(-z)) return x,y,l1,l2,z

def geterror(tt): ee=-(tt*math.log(z)+(1-tt)*math.log(1-z)) return ee

def goback(tt): ww=w bb=b ww[0]=ww[0]-xxl*(z-tt)*w[4]l1(1-l1)x ww[2]=ww[2]-xxl(z-tt)*w[4]l1(1-l1)y ww[1]=ww[1]-xxl(z-tt)w[5]l2(1-l2)x ww[3]=ww[3]-xxl(z-tt)w[5]l2(1-l2)y bb[0]=bb[0]-xxl(z-tt)(w[4]l1(1-l1)+w[5]l2(1-l2)) ww[4]=ww[4]-xxl(z-tt)l1 ww[5]=ww[5]-xxl(z-tt)l2 bb[1]=bb[1]-xxl(z-tt) return ww,bb

xxl=0.3 x=np.random.uniform(-2,2,[20,2]) y1=np.array([6,7]) y2=np.array([0,4]) y3=np.array([3,0]) m1=x[0:8]+y1 m2=x[8:14]+y2 m3=x[14:20]+y3 m=np.vstack((m1,m2,m3)) print(m) input() t=np.array([0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1])

i=0 j=0 x,y,l1,l2,z=gofront(m[i][0],m[i][1]) print(z,l1,l2) e=geterror(t[i]) while(e>=0.0015 or j<=5000): j=j+1 w,b=goback(t[i]) i=i+1 if i>19: i=0 x,y,l1,l2,z=gofront(m[i][0],m[i][1]) e=geterror(t[i]) print(e)

print("------------------")

i=-3 j=-3 while(i<10): i=i+0.3 j=-3 while(j<10): j=j+0.3 x,y,l1,l2,z=gofront(i,j) if z>0.8: plt.scatter(i,j,s=5,c=‘r’,marker=’.’) elif z<0.2: plt.scatter(i,j,s=5,c=‘g’,marker=’.’)

‘’’ for i in range(-4,11): for j in range(-4,11): x,y,l1,l2,z=gofront(i,j) if z>0.5: plt.scatter(i,j,c=‘r’) else: plt.scatter(i,j,c=‘g’)

‘’’ ‘’’ for j in range(0,14): x,y,l1,l2,z=gofront(m[j][0],m[j][1]) print(z) ‘’’

plt.scatter(m[0:8,0],m[0:8,1],c=‘b’) plt.scatter(m[8:20,0],m[8:20,1],c=‘y’) plt.show()

分类结果

从图中分类结果看,模型是比较成功的,损失函数值小于0.001,结果基本可靠。

最新回复(0)