深度學習之路, 從邏輯迴歸開始, 手寫一個分類器.
阿新 • • 發佈:2019-02-15
要給同事講神經網路和tensorflow. 需要普及一些前導知識.
所以我準備了一個課件, 寫了下面這個不使用工具和庫,全手寫的分類器. . 個人感覺, 對於幫助理解機器學習的具體實現過程是很有幫助的. (僅僅為了演示原理,實現寫的比較粗糙,談不上效能. )
放在這裡, 希望可以幫到其他同學.
宣告 : The MIT License
有需要的隨便拿去用.
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import math
import sys
dataset_raw = [
[0.051267 ,0.69956,1 ],
[-0.092742,0.68494,1 ],
[-0.21371,0.69225,1 ],
[-0.375,0.50219,1 ],
[-0.51325,0.46564,1 ],
[-0.52477,0.2098,1 ],
[-0.39804,0.034357,1 ],
[-0.30588,-0.19225,1 ],
[0.016705,-0.40424,1 ],
[0.13191,-0.51389,1 ],
[0.38537,-0.56506,1 ],
[0.52938,-0.5212,1 ],
[0.63882,-0.24342,1 ],
[0.73675,-0.18494,1 ],
[0.54666,0.48757 ,1 ],
[0.322,0.5826,1 ],
[0.16647,0.53874,1 ],
[-0.046659,0.81652,1 ],
[-0.17339,0.69956,1 ],
[-0.47869,0.63377,1 ],
[-0.60541,0.59722,1 ],
[-0.62846,0.33406,1 ],
[-0.59389,0.005117,1 ],
[-0.42108,-0.27266,1 ],
[-0.11578,-0.39693,1 ],
[0.20104,-0.60161,1 ],
[0.46601,-0.53582,1 ],
[0.67339,-0.53582,1 ],
[-0.13882,0.54605 ,1 ],
[-0.29435,0.77997,1 ],
[-0.26555,0.96272,1 ],
[-0.16187,0.8019,1 ],
[-0.17339,0.64839,1 ],
[-0.28283,0.47295,1 ],
[-0.36348,0.31213,1 ],
[-0.30012,0.027047,1 ],
[-0.23675,-0.21418,1 ],
[-0.06394,-0.18494,1 ],
[0.062788,-0.16301,1 ],
[0.22984,-0.41155,1 ],
[0.2932,-0.2288,1 ],
[0.48329,-0.18494,1 ],
[0.64459,-0.14108,1 ],
[0.46025,0.012427,1 ],
[0.6273,0.15863,1 ],
[0.57546,0.26827,1 ],
[0.72523,0.44371,1 ],
[0.22408,0.52412,1 ],
[0.44297,0.67032,1 ],
[0.322,0.69225,1 ],
[0.13767,0.57529,1 ],
[-0.0063364,0.39985,1 ],
[-0.092742,0.55336,1 ],
[-0.20795,0.35599,1 ],
[-0.20795,0.17325,1 ],
[-0.43836,0.21711,1 ],
[-0.21947,-0.016813,1 ],
[-0.13882,-0.27266,1 ],
[0.18376,0.93348,0 ],
[0.22408,0.77997,0 ],
[0.29896,0.61915,0 ],
[0.50634,0.75804,0 ],
[0.61578,0.7288,0 ],
[0.60426,0.59722,0 ],
[0.76555,0.50219,0 ],
[0.92684,0.3633,0 ],
[0.82316,0.27558,0 ],
[0.96141,0.085526,0 ],
[0.93836,0.012427,0 ],
[0.86348,-0.082602,0 ],
[0.89804,-0.20687,0 ],
[0.85196,-0.36769,0 ],
[0.82892,-0.5212,0 ],
[0.79435,-0.55775,0 ],
[0.59274,-0.7405,0 ],
[0.51786,-0.5943,0 ],
[0.46601,-0.41886,0 ],
[0.35081,-0.57968,0 ],
[0.28744,-0.76974,0 ],
[0.085829,-0.75512,0 ],
[0.14919,-0.57968,0 ],
[-0.13306,-0.4481,0 ],
[-0.40956,-0.41155,0 ],
[-0.39228,-0.25804,0 ],
[-0.74366,-0.25804,0 ],
[-0.69758,0.041667,0 ],
[-0.75518,0.2902,0 ],
[-0.69758,0.68494,0 ],
[-0.4038,0.70687,0 ],
[-0.38076,0.91886,0 ],
[-0.50749,0.90424,0 ],
[-0.54781,0.70687,0 ],
[0.10311,0.77997,0 ],
[0.057028,0.91886,0 ],
[-0.10426,0.99196,0 ],
[-0.081221,1.1089,0 ],
[0.28744,1.087,0 ],
[0.39689,0.82383,0 ],
[0.63882,0.88962,0 ],
[0.82316,0.66301,0 ],
[0.67339,0.64108,0 ],
[1.0709,0.10015,0 ],
[-0.046659,-0.57968,0 ],
[-0.23675,-0.63816,0 ],
[-0.15035,-0.36769,0 ],
[-0.49021,-0.3019,0 ],
[-0.46717,-0.13377,0 ],
[-0.28859,-0.060673,0 ],
[-0.61118,-0.067982,0 ],
[-0.66302,-0.21418,0 ],
[-0.59965,-0.41886,0 ],
[-0.72638,-0.082602,0 ],
[-0.83007,0.31213,0 ],
[-0.72062,0.53874,0 ],
[-0.59389,0.49488,0 ],
[-0.48445,0.99927,0 ],
[-0.0063364,0.99927,0 ],
[0.63265,-0.030612,0 ],
]
dataset_np = np.array(dataset_raw)
#feature engineering
def prep_feature(x):
x = np.insert(x, 2, np.power(x[:,0],2), axis=1)
x = np.insert(x, 3, np.power(x[:,1],2), axis=1)
x = np.insert(x, 4, np.multiply( x[:,0],x[:,1] ), axis=1)
x = np.insert(x, 0, 1, axis=1)
return x
dataset_np = prep_feature(dataset_np)
dataset_positive = dataset_np[ dataset_np[:,6] == 1 ]
dataset_nagtive = dataset_np[ dataset_np[:,6] == 0 ]
fig, ax = plt.subplots()
ax.hold(True)
ax.plot(dataset_positive[:,1], dataset_positive[:,2], 'o')
ax.plot(dataset_nagtive[:,1], dataset_nagtive[:,2], 'x')
#sys.exit()
#extract the Y.
dataset_y = dataset_np[:,6]
#3 steps
# define the model.
theta = np.ones(6)
learning_rate = 0.01
loss = []
def Sigmoid(z):
# 1/(1+e^-z)
s = np.frompyfunc(lambda x: 1/(1 + math.e**-z) , 1, 1)
return s(z)[0]
def Model(theta_,dataset_):
# h(theta) theta' * dataset
biased_dataset = dataset_.copy()
#biased_dataset = np.insert(biased_dataset, 0, 1, axis=1)
mt = np.matrix(biased_dataset)[:,:6].transpose()
tt = np.matrix(theta)
z = np.squeeze(np.asarray(tt * mt))
return Sigmoid(z),z
def Cost(theta,predict,y):
#J(theta) -y*log(h_theta(x)) - (1-y)log(1-h_theta(x))
part_1 = np.multiply(-y ,np.log( predict ) )
part_2 = np.multiply(1-y ,np.log( 1- predict ))
total = np.subtract( part_1 , part_2)
return np.sum(total) / len(y) / 2
#for test
try:
while True:
theta_copy = theta.copy()
predict_test,z = Model(theta_copy,dataset_np)
cost_test = Cost(theta,predict_test,dataset_y)
print(cost_test)
loss.append(cost_test)
for i in range(6):
diff = np.subtract(predict_test , dataset_y)
i_col_dataset = dataset_np[:,i]
mt_diff = np.matrix(diff)
mt_x = np.matrix(i_col_dataset).transpose()
g = np.sum(mt_diff * mt_x) / len(dataset_np) * learning_rate
#print("g(%d) is %f"%(i,g))
theta_copy[i] -= g
theta = theta_copy
except KeyboardInterrupt as e:
print("stop traning...")
# draw the decision bundry
bundry_set = []
for i in range(200):
for j in range(200):
bundry_set.append([i/100-1,j/100 -1])
bundry_set_np = np.array(bundry_set)
bundry_set_np_featured = prep_feature(bundry_set_np)
predict_test,z = Model(theta,bundry_set_np_featured)
dundry = bundry_set_np_featured[ np.logical_and( predict_test > 0.5 ,predict_test < 0.51 ) ]
ax.plot(dundry[:,1], dundry[:,2], '.')
print("end program...")
執行後自動開始訓練, 控制檯輸出loss, 當loss可以接受之後,按ctrl+c停止訓練.
稍等片刻, 可以看到程式影象輸出如下, 點為1, x為0, 綠色的圈是decision bundry.