import cv2 import numpy as np from matplotlib import pyplot as plt from decimal import * #getcontext().prec = 4 #設定湖點數精度4位 #getcontext().rounding = ROUND_HALF_UP #4捨5入 #print(getcontext()) def Fx2(x0,s,w1,w2): r2 = (s-x0*w1)/w2 #print(r1) return r2 #最大疊代次數Pmax =預設1000次 意為最大訓練次數 Pmax=22 # 產生輸入一維矩陣 x1 ,序列為[0.,0.,1.,1.,0.,0.,1.,1.,0.,0.,1.,1.,........] xi1=[0.,0.,1.,1.] x1=xi1*(Pmax//4) #print(x1) # 產生輸入一維矩陣 x2 ,序列為[0.,1.,0.,1.,0.,1.,0.,1.,0.,1.,0.,1.,........] xi2=[0.,1.,0.,1.] x2=xi2*(Pmax//4) #print(x2) #Yd ,為x1 and x2 的預期輸出 ,故每次疊代後的預期輸出應為序列[0.,0.,0.,1., 0.,0.,0.,1.,0.,0.,0.,1.,....] Yt=[0.,0.,0.,1. ] #Yd ,為x1 or x2 的預期輸出 ,故每次疊代後的預期輸出應為序列[0.,0.,0.,1., 0.,0.,0.,1.,0.,0.,0.,1.,....] #Yt=[0.,1.,1.,1. ] Yd=Yt*(Pmax//4) #print(Yd) #初始權重w1,w2,及臨界值s=0.2 ,學習率a=0.1 w1=np.zeros(Pmax) #初始為0.0 w1[0]=0.3 #第一次疊代初始值為0.3 ,預設buffer為可疊代Pmax次 #print(w1[0:4]) w2=np.zeros(Pmax) #初始為0.0 w2[0]=-0.1 #第一次疊代初始值為-0.1 ,預設buffer為可疊代Pmax次 #print(w2[0:4]) s=0.2 a=0.1 #宣告初始権重差值矩陣為0,只是for程式設計使用預設值 #Dw 用來修正每次疊代後須修正的權值 Dw1 =np.zeros(Pmax) #初始為0.0 Dw2 =np.zeros(Pmax) #初始為0.0 #宣告初始誤差E為0,只是for程式設計使用預設值 #E 為每次疊代後,期望值與實際輸出值的誤差 E =np.zeros(Pmax) #初始為0.0 #宣告初始實際輸出值Y矩陣為0,只是for程式設計使用預設值 #第p次疊代實際輸出Y Y =np.zeros(Pmax) #初始為0.0 #Epoch ,疊代次數p print("疊代次數|輸入x1|輸入x2|初始權重w1|初始權重w2|期望輸出Yd|實際輸出Y| 誤差E |修正後權重w1|修正後權重w2|") for p in range(Pmax-2): #from 0,1...4 to Pmax #print("疊代次數:",p) #由於浮點數計算會有誤差,所以使用Decimal的quantize只取兩位並無條件捨去 Y[p]=Decimal(x1[p]*w1[p]+x2[p]*w2[p]-s).quantize(Decimal('.01'), rounding=ROUND_DOWN) #print("實際輸出before F(step):",Y[p]) #代入步階函數 if Y[p]>=0.0: Y[p]=1.0 else: Y[p]=0.0 #print("實際輸出2:",Y[p]) #計算誤差並修改權重 E[p]=Decimal(Yd[p]-Y[p]).quantize(Decimal('.01'), rounding=ROUND_HALF_UP) #print("誤差:",E[p]) Dw1[p]=a*x1[p]*E[p] w1[p+1]=Decimal(w1[p]+Dw1[p]).quantize(Decimal('.01'), rounding=ROUND_HALF_UP) Dw2[p]=a*x2[p]*E[p] w2[p+1]=Decimal(w2[p]+Dw2[p]).quantize(Decimal('.01'), rounding=ROUND_HALF_UP) #if (E[p,0]==0)&(E[p,1]==0)&(E[p,2]==0)&(E[p,3]==0) : #break #print("修正後權重1:",w1[p+1]) #print("修正後權重2:",w2[p+1]) #print("疊代次數|輸入x1|輸入x2|初始權重w1|初始權重w2|期望輸出Yd|實際輸出Y| 誤差E |修正後權重w1|修正後權重w2|") print(' {0:1d} {1:1d} {2:1d} {3:.2f} {4:.2f} {5:1d} {6:1d} {7:.2f} {8:.2f} {9:.2f} '.format(p, int(x1[p]),int(x2[p]),w1[p],w2[p],int(Yd[p]),int(Y[p]),E[p],w1[p+1],w2[p+1])) #得到最後訓練好的w1,w2 print("得到最後訓練好的權重w1,w2=",w1[p+1],w2[p+1]) print('代入原輸出方程式Y= {0:.2f}X1+ {1:.2f}X2- {2:.2f} '.format(w1[p+1],w2[p+1],s)) print("再代入Step 激勵函數Step(Y):If Y>=0 ,則Y=1 ,IF Y<0 ,則Y=0") print("因此可以得到當Y=0 時意即w1X1+w2X2-s=0為分界函數,在界線上方分類為A1區域=1,下方A2區域為0") #畫出函數 w1X1+w2X2-0.2=0 , 分類函數,在這裡用p1,p2取代原x1,x2於是 p1=np.linspace(-10.0, 10.0, 100) p2=np.array([Fx2(k,s,w1[p+1],w2[p+1]) for k in p1]) plt.subplot(1,1,1) plt.plot(p1, p2, 'b-',linewidth=3.0) #紅色線寬可以改成2.0或其他數值 ##X min=0 ~,max=10 ,Y axis min=0 ~max=24 plt.axis([-0,2.0, -0,2.0]) #分別設定X,Y軸的最小最大值 plt.title(' X1 and X2 function,UP area =1,Down area =0 ') plt.ylabel('X2') plt.xlabel('X1') plt.grid(True) plt.plot(0,0,'ro') plt.text(0, 0, r'P0(0,0)') plt.plot(0,1,'ro') plt.text(0, 1, r'P1(0,1)') plt.plot(1,1,'ro') plt.text(1, 1, r'P3(1,1)') plt.plot(1,0,'ro') plt.text(1, 0, r'P4(1,0)') plt.text(0.5,1.7, 'W1 =%s%s W2= %s '%(w1[p+1],'\n',w2[p+1]),fontsize=16 ) plt.text(0.5,1.5, '%sX1+%sX2-%s=%s'%(w1[p+1],w2[p+1],s,0),fontsize=16 ) plt.fill_between(p1, -0, p2, facecolor='green') plt.show()