larsupilami73

XOR classification animation

Dec 15th, 2020
1,076
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.62 KB | None | 0 0
  1. #!/usr/bin/python3
  2. #
  3. #XOR 2D function classification:
  4. #The XOR function in the plane is not linearly separable: a single straight line in the cannot divide the classes (reds and blues),
  5. #so a simple logistic regression (LR) fails.
  6. #Using a (large) number of randomly-chosen radial basis functions (RBFs) enables linear separation.
  7. #The individual RBFs 'measure' the distance from their centres to a point in the dataset.
  8. #Note there's no separare test set, as this would make the script a bit more complicated and
  9. #the performance is obvious from the images.
  10. #
  11. #larsupilami73
  12.  
  13.  
  14. #imports
  15. import os,sys
  16. from scipy import *
  17. import matplotlib.pyplot as plt
  18. from sklearn.linear_model import LogisticRegression
  19. from sklearn.model_selection import cross_val_score
  20.  
  21.  
  22. #generator for the xor dataset
  23. def xor(n=10000):
  24.     while (n>0):
  25.         n -=1
  26.         x = random.uniform(0,1)
  27.         y = random.uniform(0,1)
  28.         if (x<0.5 and y<0.5) or (x>0.5 and y>0.5):
  29.             c = 0
  30.         else:
  31.             c = 1        
  32.         yield (x,y,c)
  33.  
  34.    
  35. #main    
  36. if __name__ == '__main__':
  37.    
  38.     numframes = 25
  39.     try:
  40.         os.mkdir('frames')
  41.     except:
  42.         pass
  43.     try:
  44.         os.system('rm -f ./frames/*.png')   #remove previous run frames
  45.     except:
  46.         pass
  47.        
  48.     #generate the 'ground truth' dataset
  49.     L,C = [],[]
  50.     X,Y = [[],[],[],[]],[[],[],[],[]]
  51.     for x,y,c in xor():
  52.         L.append([x,y,c])
  53.         C.append(c)
  54.         X[c].append(x)
  55.         Y[c].append(y)
  56.        
  57.     L = array(L)
  58.     #savetxt('xor.txt',L,fmt='%.6f %.6f %i',header='xor dataset.\nX   Y   Class') #save it
  59.    
  60.     #plot the ground truth
  61.     fig,(ax1,ax2) = plt.subplots(1,2,figsize=(8,4))    
  62.     colors = ['blue','red']
  63.     for c in range(2):
  64.         ax1.scatter(X[c],Y[c],s=5,c=colors[c],label='class %i'%c)
  65.     ax1.legend(loc='upper right',ncol=1,markerscale=2.0)
  66.     ax1.set_xlabel('X')
  67.     ax1.set_ylabel('Y')
  68.     ax1.set_title('Ground truth XOR')
  69.    
  70.     #lets first try a logistic regression on the ground truth
  71.     P = array([[x_,y_] for x_,y_,c_ in L])
  72.     clf = LogisticRegression(random_state=0,solver='lbfgs',multi_class='auto')
  73.     scores = cross_val_score(clf, P, C, cv=5)
  74.     print('Only LR scores: ',scores)
  75.     print("Only LR accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
  76.    
  77.     #make a drawing to show what the logistic regression resulted in
  78.     clf.fit(P,C)
  79.     score = clf.score(P,C)
  80.     print('Train score entire dataset: %2.3g'%score)
  81.     prediction = clf.predict(P)
  82.     XP,YP = [[],[],[],[]],[[],[],[],[]]
  83.     for c,p in zip(prediction,P):
  84.         XP[c].append(p[0])
  85.         YP[c].append(p[1])
  86.    
  87.     for c in range(2):
  88.         ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label='class %i'%c)
  89.     #draw the errors more clearly
  90.     fe = False
  91.     for ce,p,c in zip(prediction,P,C):
  92.         if ce != c:
  93.             if fe:
  94.              ax2.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label=None)
  95.             else:
  96.                 ax2.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label='errors')
  97.                 fe = True
  98.    
  99.     ax2.legend(loc='upper right',ncol=1,markerscale=2.0)
  100.     ax2.set_xlabel('X')
  101.     ax2.set_ylabel('Y')
  102.     ax2.set_title('LR only. Score: %2.3g'%score)
  103.     plt.savefig('./frames/frame%05d.png'%0)
  104.     ax2.cla()
  105.    
  106.    
  107.     #Now lets construct new features which are nonlinear functions of X and Y.
  108.     #Here we choose random radial basis functions (RBF).
  109.     #Then check how well the LR does when fed by these new features
  110.     R,S = [],[] #center positions and radii of the RBFs
  111.     for frame in range(1,numframes+1):
  112.         print('frame %i/%i'%(frame,numframes))
  113.         nrbf = frame
  114.         R.append(random.normal(size=2,loc=[0.5,0.5],scale=0.25))  #center positions of the RBFs
  115.         S.append(random.uniform(low=0.1,high=0.3))             #radii of the RBFs
  116.         Z = array([[ exp(-((p_[0]-r_[0])**2+(p_[1]-r_[1])**2)/s_**2) for r_,s_ in zip(R,S) ] for p_ in P])
  117.         clf2 = LogisticRegression(random_state=0,solver='lbfgs',multi_class='multinomial',max_iter=1000)
  118.         clf2.fit(Z,C)
  119.         score = clf2.score(Z,C)
  120.         print('Train score with %i RBFs: %2.3g'%(nrbf,score))
  121.         XP,YP = [[],[],[],[]],[[],[],[],[]]
  122.         prediction = clf2.predict(Z)
  123.         for c,p in zip(prediction,P):
  124.             XP[c].append(p[0])
  125.             YP[c].append(p[1])
  126.            
  127.         for c in range(2):
  128.             ax2.scatter(XP[c],YP[c],s=5,c=colors[c],label='class %i'%c)
  129.        
  130.         #draw the errors more clearly
  131.         fe = False
  132.         for ce,p,c in zip(prediction,P,C):
  133.             if ce != c:
  134.                 if fe:
  135.                  plt.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label=None)
  136.                 else:
  137.                     plt.scatter([p[0]],[p[1]],s=8,c='none',edgecolors= "black",label='error')
  138.                     fe = True
  139.        
  140.         ax2.legend(loc='upper right',ncol=1,markerscale=2.0)
  141.         ax2.set_xlabel('X')
  142.         ax2.set_label('Y')
  143.         ax2.set_title('%i RBFs --> LR. Score: %2.3g' %(nrbf,score))
  144.         #draw the RBFs position and radius
  145.         for r,s in zip(R,S):
  146.             ax2.add_artist(plt.Circle(r,s,linestyle='--',linewidth=0.5,alpha=0.7,fill=False))
  147.    
  148.         plt.savefig('./frames/frame%05d.png'%frame)
  149.         ax2.cla()
  150.    
  151.  
  152. plt.close()
  153.  
  154. #now assemble all the pictures in a movie
  155. print('converting to gif!')
  156. os.system('convert -delay 40 -loop 0 ./frames/*.png xor.gif')
  157. #or to mp4 with .mp4
  158. #print('converting to mp4!')
  159. #os.system("ffmpeg -y -r 40 -i ./frames/frame%05d.png -c:v libx264 -vf fps=20 xor.mp4")
  160.  
Advertisement
Add Comment
Please, Sign In to add comment