1. 程式人生 > 其它 >學習機器學習-二分類問題分類器,梯度下降法,程式碼展示。

學習機器學習-二分類問題分類器,梯度下降法,程式碼展示。

要求:自己生成一個樣本總數為20的兩類資料集,每類分別為10個樣本。實現線性分類器。

基礎知識參考了這份部落格,它是我找到的最詳細的一篇講解。

神經網路系列之五 -- 線性二分類的方法與原理

另外附上GitHub地址:https://github.com/microsoft/ai-edu

這份作業快到截止時間了,我還沒學會神經網路,又沒有找到相關程式碼,於是自己用笨辦法寫了一下程式碼來實現線性分類器。

import matplotlib.pyplot as plt
import numpy as np

#樣本特徵值
def randrange(n, vmin, vmax):
    return (vmax - vmin)*np.random.rand(n) + vmin


x1_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100)))
x2_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100)))
#標籤值
list_y=[]

for i in range(20):
    if(i/10<1):
        list_y.append(0)
    else:
        list_y.append(1)
y_data = np.asarray(list_y)
x_train = np.stack((x1_data,x2_data,y_data))
print(x_train)

這裡生成兩類資料集做訓練用,在生成時要附上標籤值,用來判斷其為哪一類資料。

資料集展示
[[23.56666375 25.09075631 47.12803743  5.8850233  39.49089641 16.8659462
   9.44996442 10.05850374 36.45182739 11.74453997 78.19518409 99.49470411
  66.32145363 73.78367965 57.99214184 62.30056474 97.47532927 75.63052221
  62.84388756 66.49887471]
 [37.35435583 26.14989834  1.75216991 26.70968015  1.33685583 23.60078884
  24.64790623 47.900654   30.20381661 22.00034265 75.20267327 57.68395067
  65.05356895 59.25574098 86.86977068 94.68262277 68.93671045 89.87274462
  78.86753854 65.03568956]
 [ 0.          0.          0.          0.          0.          0.
   0.          0.          0.          0.          1.          1.
   1.          1.          1.          1.          1.          1.
   1.          1.        ]]
#展示樣本資料集
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()

這裡可視化了生成的資料集。

#初始化引數
W=np.array([1,1])
rate=0.01              #學習速率
B=40
temp=1000              #學習次數  

這一步是初始化訓練相關的引數,在神經網路的介紹裡也能看到對應的值,猶豫我還不會神經網路,所以我將其提出來直接使用。



#訓練函式
def training(W,B,rate,temp):
    for j in range(temp):
        for i in range(20): 
            Z=np.dot(x_train[0:2,i],W)+B
            a =1.0 / (1.0 + np.exp(-Z))
            loss=a-x_train[2,i]
            W=W-np.dot(x_train[0:2,i],loss)*rate
            B=B-loss*rate
    #         print(x_train[0:2,i])
    #         print("W=",W)
    #         print("B=",B)
    #         print(Z)
    #         print(a)
    #         print(x_train[2,i])
    #         print(loss)
    print("W=",W)
    print("B=",B)
    return(W,B)
#驗證函式
def verify(x):
    Z=np.dot(x,W)+B
    a =1.0 / (1.0 + np.exp(-Z))
    if (a<0.5):
        print(a)
        return 0
    else:
        print(a)
        return 1

這裡定義了兩個函式

 for i in range(20): 
            Z=np.dot(x_train[0:2,i],W)+B
            a =1.0 / (1.0 + np.exp(-Z))
            loss=a-x_train[2,i]
            W=W-np.dot(x_train[0:2,i],loss)*rate
            B=B-loss*rate

訓練函式裡這一段算是主要函式,在我開頭提到的部落格中有介紹這些公式是怎麼產生的,以及其意義是什麼。

在我的理解中,Z即分類的直線,a即物體所屬的分類,W,B按照loss函式的結果與rate的值進行更新。

後面驗證時算出物體的a的值,即可知道其屬於哪一類。

#訓練過程展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
for i in range(20):
    x1 = np.linspace(0, 100, 100)
    W,B=training(W,B,rate,temp)
    y1=-(W[0]*x1+B)/W[1]
    plt.plot(x1, y1)    

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()
W,B的值隨訓練的變化情況

W= [0.35948076 0.1748828 ]
B= 13.26780449826064
W= [0.77210068 0.75313404]
B= -6.3703509972183925
W= [0.14469182 0.10921083]
B= -10.477108967713642
W= [0.15191845 0.11642575]
B= -11.117629746272264
W= [0.15417136 0.12109126]
B= -11.661601613466757
W= [0.15539298 0.12437233]
B= -12.108067343382372
W= [0.15685185 0.12712868]
B= -12.481884452303593
W= [0.15848816 0.12957921]
B= -12.803578372149296
W= [0.16017228 0.13179975]
B= -13.08645575299053
W= [0.16183213 0.13383368]
B= -13.339239644353153
W= [0.16343551 0.1357114 ]
B= -13.567933719883142
W= [0.16497061 0.13745581]
B= -13.776863359466688
W= [0.16643522 0.13908479]
B= -13.969261581756376
W= [0.16783145 0.14061275]
B= -14.147615946501244
W= [0.16916313 0.14205153]
B= -14.313885256376384
W= [0.17043466 0.14341102]
B= -14.469641425088682
W= [0.17165047 0.14469957]
B= -14.616166033139798
W= [0.17281475 0.14592431]
B= -14.754518171875178
W= [0.17393139 0.14709136]
B= -14.88558338672208
W= [0.17500392 0.14820602]
B= -15.010109775334383
#訓練結果展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)    

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()

以上出現的展示程式碼多是重複的,建議去學習一下matplotlib的畫圖操作,自己按需更改程式碼。

#驗證一個點(55,55)的分類
x=[55,55]

print(verify(x))

fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
ax.scatter(x[0], x[1], marker="^")

x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)   

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

plt.show()
0.9408349606570592
1

 

綠色三角點,即x點,為自己選擇驗證那個點。也可以用上測試集來驗證。

 

關於訓練函式部分開頭給出的部落格講的比我清楚,我便不再贅述,程式碼不分,我也不是最好的,但自認為適合初學者參考來理解數學原理與程式碼的結合。

其他部分程式碼都可簡單搜出,不懂可留言討論。