机器学习(西瓜书)-BP神经网络实现
扫测资讯 2024-11-19 18:07 8 0
原理在书上
1、首先定义两个激活函数,越阶函数和sigmoid函数
2、用感知机实现线性可分的与,或,非问题,然后用多层感知机实现线性不可分的异或问题。
3、之后搭建了一个三层神经网络,任务是判断一个数字是否>0.5。
所有的参数还有变量依托于周志华的机器学习(西瓜书)p97-p104
import numpy as np
import matplotlib.pyplot as plt
def sgn(x):
if x>=0:
return 1
else:
return 0
def sigmoid(x):
return 1/(1+np.e**(-x))
# return x
x=np.linspace(-10,10,100)
y=[]
for i in x:
y.append(sigmoid(i))
plt.plot(x,y)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
def sgn(x):
if x>=0:
return 1
else:
return 0
def sigmoid(x):
return 1/(1+np.e**(-x))
# return x
x=np.linspace(-10,10,100)
y=[]
for i in x:
y.append(sigmoid(i))
plt.plot(x,y)
plt.show()
w1=1
w2=1
d=2
print("\n与运算")
print("x1 x2 y")
for x1 in range(2):
for x2 in range(2):
y = sgn(x1 * w1 + x2 * w2 -d)
print(x1,x2,y)
w1=1
w2=1
d=0.5
print("\n或运算")
print("x1 x2 y")
for x1 in range(2):
for x2 in range(2):
y = sgn(x1 * w1 + x2 * w2 -d)
print(x1,x2,y)
w1=-0.6
w2=0
d=-0.5
print("\n非运算")
print("x1 y")
for x1 in range(2):
for x2 in range(2):
y = sgn(x1 * w1 + x2 * w2 -d)
print(x1,y)
w1_1=1
w1_2=-1
w2_1=-1
w2_2=1
wh_1=1
wh_2=1
d=0.5
print("\n异或运算")
print("x1 x2 y")
for x1 in range(2):
for x2 in range(2):
h1 = sgn(x1 * w1_1 + x2 * w2_1 -d)
h2 = sgn(x1 * w1_2 + x2 * w2_2 - d)
y=sgn(h1 * wh_1 + h2 * wh_2 - d)
print(x1,x2,y)
import numpy as np
import matplotlib.pyplot as plt
def sgn(x):
if x>=0:
return 1
else:
return 0
def sigmoid(x):
return 1/(1+np.e**(-x))
# return x
#
# o j={0}
# / | \ whj[3,1]
# o o o h={0,1,2}
# \ | / vih[1,3]
# o i={0}
x=np.random.random(100)
y=(x>0.5)*1.0
v=np.random.random([1,3])#v_ih
w=np.random.random([3,1])#w_hj
dh=np.random.random(3)#隐层的阈值
dy=np.random.random(1)#输出层阈值
def ah(h,xk): #隐层h的输入
sum=0
for i in range(1):
sum+=v[i][h]*xk
return sum
def bh(h,xk): #隐层h的输出
return sigmoid(ah(h,xk)-dh[h])
def Bj(j,xk): #输出层的输入
sum=0
for h in range(3):
sum+=w[h][j]*bh(h,xk)
return sum
def yj(j,xk): #输出层的输出
return sigmoid(Bj(j,xk)-dy[j])
def Ek(xk,k): #损失
sum=0
for j in range(1):
sum+=(yj(j,xk)-y[k])**2
return (1/2)*sum
def gj(j,xk,k): #梯度计算
return yj(j,xk)*(1-yj(j,xk))*(y[k]-yj(j,xk))
def eh(h,xk,k): #梯度项
sum=0
for j in range(1):
sum+=w[h][j]*gj(j,xk,k)
return bh(h,xk)*(1-bh(h,xk))*sum
def Model(x):
a1=ah(0,x)
a2=ah(1,x)
a3=ah(2,x)
b1=bh(0,x)
b2=bh(1,x)
b3=bh(2,x)
B0=Bj(0,x)
y_=yj(0,x)
return y_>=0.5
def Precsion():
good=0
for k in range(100):
# print(y[k]==Model(x[k])*1.0)
if y[k] == Model(x[k]) * 1.0:
good+=1
print("准确率:",good,"%")
def train():
n=0.1
j=0#输出节点编号,只有一个节点
loss=[]#记录损失变化
c=0
for b in range(200):#循环迭代次数
for k in range(100):#对每个样本进行训练
c+=1
xk=x[k]
loss.append(Ek(xk, k))
d_whj_0=n*gj(j,xk,k)*bh(0,xk)
d_whj_1=n*gj(j,xk,k)*bh(1,xk)
d_whj_2=n*gj(j,xk,k)*bh(2,xk)
d_dyj_0=-1*n*gj(j,xk,k)
d_vih_0=n*eh(0,xk,k)*xk
d_vih_1=n*eh(1,xk,k)*xk
d_vih_2=n*eh(2,xk,k)*xk
d_dh_0=-1*n*eh(0,xk,k)
d_dh_1=-1*n*eh(1,xk,k)
d_dh_2=-1*n*eh(2,xk,k)
w[0][0] = w[0][0] + d_whj_0
w[1][0] = w[1][0] + d_whj_1
w[2][0] = w[2][0] + d_whj_2
# print("w",w[0][0],w[1][0],w[2][0])
dy[0] = dy[0] + d_dyj_0
# print("dy",dy[0])
v[0][0] = v[0][0] + d_vih_0
v[0][1] = v[0][1] + d_vih_1
v[0][2] = v[0][2] + d_vih_2
# print("v",v[0][0],v[0][1],v[0][2])
dh[0]=dh[0]+d_dh_0
dh[1]=dh[1]+d_dh_1
dh[2]=dh[2]+d_dh_2
# print("dh",dh[0],dh[1],dh[2])
# print("loss===========================================", Ek(k))
Precsion()
train()
print(Model(0.54))
print(Model(0.44))
# plt.plot(range(c),loss)
# plt.show()