TensorFlow实现简单非线性分类问题
对于一个非线性问题,如果在不是使用隐藏层的情况下,是很难做到合理分类的,具体代码如下:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
#数据生成和数据处理
def generate(sample_size,mean,cov,diff,regression,num_classes):
"""sample_size:样本个数;mean:不同特征的分布均值;cov:不同特征的分布方差;diff:特征分布的偏移量;regression:是否One Hot;num_classes:分类个数。"""
sample_size_per_class=int(sample_size//num_classes)
X0=np.random.multivariate_normal(mean,cov,sample_size_per_class)
Y0=np.zeros(sample_size_per_class)
for ci, d in enumerate(diff):
Xtmp=np.random.multivariate_normal(mean+d,cov,sample_size_per_class)
Ytmp=(ci+1)*np.ones(sample_size_per_class)
X0=np.concatenate((X0,Xtmp))
Y0=np.concatenate((Y0,Ytmp))
if regression==False:
class_ind=[Y0==class_number for class_number in range(num_classes)]
Y0=np.asarray(class_ind)
Y0=Y0.T
X,Y=shuffle(X0,Y0)
return X0,Y0
np.random.seed(10)
input_dim=2
num_classes=3
mean=np.random.randn(input_dim)
cov=np.eye(input_dim)
X,Y=generate(2000,mean,cov,[[3.0,3.0],[3.0,0]],False,num_classes)
aa=[np.argmax(l) for l in Y]
colors=['r' if l==0 else 'b' if l==1 else 'y' for l in aa[:] ]
plt.scatter(X[:,0],X[:,1],c=colors)
plt.xlabel('Scaled age(in yrs)')
plt.ylabel('Tumor size(in cm)')
plt.show()
lab_dim=num_classes
#定义占位符
input_features=tf.placeholder(tf.float32,[None,input_dim])
input_lables=tf.placeholder(tf.float32,[None,lab_dim])
#定义变量
W=tf.Variable(tf.random_normal([input_dim,lab_dim]),name="Weight")
b=tf.Variable(tf.zeros([lab_dim],name="bias"))
output=tf.matmul(input_features,W)+b
z=tf.nn.softmax(output)
#统计分类错误个数
predict=tf.argmax(z,axis=1)
test=tf.argmax(input_lables,axis=1)
err=tf.count_nonzero(predict-test)
#定义损失函数
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=input_lables,logits=output)
loss=tf.reduce_mean(cross_entropy)
learning_rate=0.004
optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
maxEpochs=50
minbatch=25
W_out=[]
b_out=[]
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(maxEpochs):
sumerr=0
for batch in range(np.int32(len(Y)/minbatch)):
x1=X[batch*minbatch:(batch+1)*minbatch,:]
y1=Y[batch*minbatch:(batch+1)*minbatch,:]
_,lossval,errval=sess.run([optimizer,loss,err],feed_dict={input_features:x1,input_lables:y1})
sumerr+=errval/minbatch
print("Epoch=","%04d"%(epoch+1),"cost=","{:9f}".format(lossval),"err=",sumerr/minbatch)
print("Finish!")
W_out.append(sess.run(W))
b_out.append(sess.run(b))
aa=[np.argmax(l) for l in Y]
colors=['r' if l==0 else 'b' if l==1 else 'y' for l in aa[:] ]
plt.scatter(X[:,0],X[:,1],c=colors)
x=np.linspace(-1,8,200)
y=-x*(W_out[0][0][0]/W_out[0][1][0])-b_out[0][0]/W_out[0][1][0]
plt.plot(x,y,label='Fitted line 1')
x=np.linspace(1,3,200)
y=-x*(W_out[0][0][1]/W_out[0][1][1])-b_out[0][1]/W_out[0][1][1]
plt.plot(x,y,label='Fitted line 2')
x=np.linspace(-1,8,200)
y=-x*(W_out[0][0][2]/W_out[0][1][2])-b_out[0][2]/W_out[0][1][2]
plt.plot(x,y,label='Fitted line 3')
plt.xlabel('Scaled age(in yrs)')
plt.ylabel('Tumor size(in cm)')
plt.legend()
plt.show()
运行结果:
增加隐藏层后的代码:
num_classes=3
input_dim=2
lab_dim=num_classes
n_hidden=2
mean=np.random.randn(input_dim)
cov=np.eye(input_dim)
#定义占位符
X,Y=generate(2000,mean,cov,[[3.0,3.0],[3.0,0]],False,num_classes)
input_features=tf.placeholder(tf.float32,[None,input_dim])
input_labels=tf.placeholder(tf.float32,[None,lab_dim])
#定义变量
weight={
'h1':tf.Variable(tf.random_normal([input_dim,n_hidden]),name='h1_weight'),
'h2':tf.Variable(tf.random_normal([n_hidden,lab_dim]),name='h2_weight')
}
bias={
'h1':tf.Variable(tf.zeros([n_hidden]),name='h1_bias'),
'h2':tf.Variable(tf.zeros([lab_dim]),name='h2_bias')
}
#定义计算节点
layer_1=tf.nn.relu(tf.add(tf.matmul(input_features,weight['h1']),bias['h1']))
output=tf.add(tf.matmul(layer_1,weight['h2']),bias['h2'])
softmaxOutput=tf.nn.softmax(output)
#定义损失函数和计算精度
prediction=tf.argmax(softmaxOutput,axis=1)
test=tf.argmax(input_features,axis=1)
err=tf.count_nonzero(prediction-test)
print(input_lables,output)
cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=input_lables,logits=output)
loss=tf.reduce_mean(cross_entropy)
learning_rate=0.0001
train=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
maxEpochs=1000
minbatch=25
prediction_out=[]
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(maxEpochs):
sumerr=0
for batch in range(np.int32(len(Y)/minbatch)):
x1=X[batch*minbatch:(batch+1)*minbatch,:]
y1=Y[batch*minbatch:(batch+1)*minbatch,:]
_,lossval,errval=sess.run([train,loss,err],feed_dict={input_features:x1,input_lables:y1})
sumerr+=errval/minbatch
if(epoch+1)%50==0:
print("Epoch=","%04d"%(epoch+1),"cost=","{:9f}".format(lossval),"err=",sumerr/minbatch)
print("Finish!")
prediction_out.append(sess.run([softmaxOutput],feed_dict={input_features:X}))
aa=[np.argmax(l,axis=1) for l in prediction_out[0]]
colors=['r' if l==0 else 'b' if l==1 else 'y' for l in aa[0][:] ]
plt.scatter(X[:,0],X[:,1],c=colors)
plt.xlabel('Scaled age(in yrs)')
plt.ylabel('Tumor size(in cm)')
plt.legend()
plt.show()
运行结果:
可以看出模型已经做到了非线性分类的效果。
代码参考《深度学习之TensorFlow入门、原理与进阶实战》