學(xué)長大大給了個(gè)小作業(yè),自定義分類規(guī)則(二分類,最好包含了二次冪以上的運(yùn)算),輸入樣本隨機(jī)產(chǎn)生,真實(shí)的分類0和1基本達(dá)到五五開,然后用keras構(gòu)建神經(jīng)網(wǎng)絡(luò),實(shí)現(xiàn)較好的擬合到自定義的分類規(guī)則。
#!/usr/bin/python
#-*-coding:utf-8-*-
from keras.models import Sequential
from keras.layers import Dense
import numpy
from numpy import random
#在需要隨機(jī)初始化的時(shí)候,最好先設(shè)定隨機(jī)種子,因?yàn)殡S機(jī)種子確定下來之后,每一次運(yùn)行代碼得到的都
#一樣的隨機(jī)序列,保證了實(shí)驗(yàn)結(jié)果的一致性。如果需要每一次隨機(jī)種子都不同,可以用當(dāng)前時(shí)間來做seed
seed=7
numpy.random.seed(seed)
#產(chǎn)生一個(gè)隨機(jī)1000x2的數(shù)組作為輸入樣本
randArray=random.random(size=(1000,2))
print(randArray)
#分別求兩個(gè)維度的均值
avg1=numpy.mean(randArray[:,0])
avg2=numpy.mean(randArray[:,1])
y=numpy.zeros([1000,1])
j=0
#自定義分類規(guī)則,當(dāng) (x1-avg1+x2-avg2 )**2> 0.1時(shí),將其x1與x2的輸出定義為1,否則為0
#將自定義的分類結(jié)果保存在y上。
for i in range(0,1000):
x1=randArray[i,0]
x2=randArray[i,1]
if (x1-avg1+x2-avg2 )**2> 0.09:
y[j,0]=1
j+=1
#為了使分類基本實(shí)現(xiàn)五五開,對于上面閾值0.1通過計(jì)算y的元素總和來看,因?yàn)槭?,1分類,
#y.sum()就代表了分類為1的數(shù)量,若y.sum()>500,將閾值0.1增大,反之亦然。
#這里測試到閾值為0.1時(shí),y.sum()也就是分類為1的數(shù)量為470多,
#修改閾值為0.09,分類1達(dá)到493個(gè),接近50%,就采用0.09作為分類閾值
print(y.sum())
print(y.T)
x=randArray
#初始化序貫?zāi)P?model=Sequential()
#依次增加全連接層,input_dim=2,因?yàn)檩斎霕颖镜木S度為2,每個(gè)樣本輸入只有x1與x2
model.add(Dense(4,activation="relu",kernel_initializer="random_normal",input_dim=2))
model.add(Dense(3,activation='sigmoid',kernel_initializer="random_normal"))
model.add(Dense(2,activation='sigmoid‘,kernel_initializer="random_normal"))
#要實(shí)現(xiàn)二分類,最后一層定義神經(jīng)元個(gè)數(shù)為1
model.add(Dense(1,activation="sigmoid",kernel_initializer="random_normal"))
#神經(jīng)網(wǎng)絡(luò)構(gòu)建好之后,就是編譯網(wǎng)絡(luò),設(shè)定一些參數(shù)。
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
#訓(xùn)練網(wǎng)絡(luò),一共1000個(gè)樣本,就選擇迭代200次,每一批取5個(gè)樣本
#(這里不是一定的,上面的構(gòu)建也不是一定的)
model.fit(x,y,epochs=200,batch_size=5)
scores=model.evaluate(x,y)
print("%s: %.2f%%" % (model.metrics_names[1],scores[1]*100))
#更換隨機(jī)種子,避免相同隨機(jī)種子產(chǎn)生的樣本進(jìn)行干擾(其實(shí)可能也無所謂,大概是想多了),
#2+產(chǎn)生100x2的隨機(jī)輸入樣本,對訓(xùn)練好的模型進(jìn)行檢驗(yàn)
seed=3
numpy.random.seed(seed)
test_x=random.random(size=(100,2))
test_avg1=numpy.mean(test_x[:,0])
test_avg2=numpy.mean(test_x[:,1])
test_y=numpy.zeros([100,1])
j=0
#for循環(huán)產(chǎn)生在自定義規(guī)則下的100個(gè)測試樣本的真實(shí)分類
for i in range(0,100):
x1=test_x[i,0]
x2=test_x[i,1]
if (x1-test_avg1+x2-test_avg2 )**2> 0.09:
test_y[j,0]=1
j+=1
print('測試樣本的真實(shí)分類:')
print(test_y.T)
predictions=model.predict(test_x)
#因?yàn)槟P妥詈蟮募せ詈瘮?shù)為sigmoid,整個(gè)函數(shù)的輸出在0到1之間,
#所以對輸出進(jìn)行簡單的四舍五入,就可以達(dá)到真正的二分類了。
rounded = [round(w) for w in predictions]
print('模型對樣本的預(yù)測分類:')
print(["%.0f"%n for n in rounded])
a_array=numpy.array(test_y.T)
b_array=numpy.array(rounded)
#100個(gè)測試樣本中,真實(shí)的輸出與模型的預(yù)測輸出,兩數(shù)組相減,得到的結(jié)果數(shù)組就很直觀了。
#因?yàn)槭?,1分類,相減結(jié)果只有哪幾種可能?
result_array = a_array - b_array
numpy.set_printoptions(threshold='nan')
print('結(jié)果對比,真實(shí)減去預(yù)測:')
print(result_array)
最后,上個(gè)圖吧。。可以看到,模型在迭代過程中,精度到達(dá)了99%。
在測試模型的時(shí)候,用重新隨機(jī)生成的100個(gè)二維輸入,用訓(xùn)練好的模型來做分類,與實(shí)際的分類結(jié)果相比,一百個(gè)只有1個(gè)不一致,可以認(rèn)為模型較好地達(dá)到了在這種自定義分類下進(jìn)行分類的目的。
2017-07-09 16-03-14屏幕截圖.png