学长大大给了个小作业,自定义分类规则(二分类,最好包含了二次幂以上的运算),输入样本随机产生,真实的分类0和1基本达到五五开,然后用keras构建神经网络,实现较好的拟合到自定义的分类规则。
#!/usr/bin/python
#-*-coding:utf-8-*-
from keras.models import Sequential
from keras.layers import Dense
import numpy
from numpy import random
#在需要随机初始化的时候,最好先设定随机种子,因为随机种子确定下来之后,每一次运行代码得到的都
#一样的随机序列,保证了实验结果的一致性。如果需要每一次随机种子都不同,可以用当前时间来做seed
seed=7
numpy.random.seed(seed)
#产生一个随机1000x2的数组作为输入样本
randArray=random.random(size=(1000,2))
print(randArray)
#分别求两个维度的均值
avg1=numpy.mean(randArray[:,0])
avg2=numpy.mean(randArray[:,1])
y=numpy.zeros([1000,1])
j=0
#自定义分类规则,当 (x1-avg1+x2-avg2 )**2> 0.1时,将其x1与x2的输出定义为1,否则为0
#将自定义的分类结果保存在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
#为了使分类基本实现五五开,对于上面阈值0.1通过计算y的元素总和来看,因为是0,1分类,
#y.sum()就代表了分类为1的数量,若y.sum()>500,将阈值0.1增大,反之亦然。
#这里测试到阈值为0.1时,y.sum()也就是分类为1的数量为470多,
#修改阈值为0.09,分类1达到493个,接近50%,就采用0.09作为分类阈值
print(y.sum())
print(y.T)
x=randArray
#初始化序贯模型
model=Sequential()
#依次增加全连接层,input_dim=2,因为输入样本的维度为2,每个样本输入只有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"))
#要实现二分类,最后一层定义神经元个数为1
model.add(Dense(1,activation="sigmoid",kernel_initializer="random_normal"))
#神经网络构建好之后,就是编译网络,设定一些参数。
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
#训练网络,一共1000个样本,就选择迭代200次,每一批取5个样本
#(这里不是一定的,上面的构建也不是一定的)
model.fit(x,y,epochs=200,batch_size=5)
scores=model.evaluate(x,y)
print("%s: %.2f%%" % (model.metrics_names[1],scores[1]*100))
#更换随机种子,避免相同随机种子产生的样本进行干扰(其实可能也无所谓,大概是想多了),
#2+产生100x2的随机输入样本,对训练好的模型进行检验
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循环产生在自定义规则下的100个测试样本的真实分类
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('测试样本的真实分类:')
print(test_y.T)
predictions=model.predict(test_x)
#因为模型最后的激活函数为sigmoid,整个函数的输出在0到1之间,
#所以对输出进行简单的四舍五入,就可以达到真正的二分类了。
rounded = [round(w) for w in predictions]
print('模型对样本的预测分类:')
print(["%.0f"%n for n in rounded])
a_array=numpy.array(test_y.T)
b_array=numpy.array(rounded)
#100个测试样本中,真实的输出与模型的预测输出,两数组相减,得到的结果数组就很直观了。
#因为是0,1分类,相减结果只有哪几种可能?
result_array = a_array - b_array
numpy.set_printoptions(threshold='nan')
print('结果对比,真实减去预测:')
print(result_array)
最后,上个图吧。。可以看到,模型在迭代过程中,精度到达了99%。
在测试模型的时候,用重新随机生成的100个二维输入,用训练好的模型来做分类,与实际的分类结果相比,一百个只有1个不一致,可以认为模型较好地达到了在这种自定义分类下进行分类的目的。