用tensorflow實現svm的線性和非線性分類
阿新 • • 發佈:2018-12-29
線性分割:
# coding: utf-8 # In[1]: import matplotlib.pyplot as plt import numpy as np from sklearn import datasets import tensorflow as tf # In[2]: iris = datasets.load_iris() x_vals = np.array([[x[0],x[3]] for x in iris.data]) y_vals = np.array([1 if y == 0 else -1 for y in iris.target]) # In[3]: x_vals[:5],y_vals[:5] # In[4]: from sklearn import model_selection train_data,test_data,train_target,test_target = model_selection.train_test_split(x_vals,y_vals,test_size=0.2) # In[5]: train_data.shape,test_data.shape # In[6]: batch_size = 100 x_data = tf.placeholder(shape=[None,2],dtype=tf.float32) y_target = tf.placeholder(shape=[None,1],dtype=tf.float32) A = tf.Variable(tf.random_normal(shape=[2,1])) b = tf.Variable(tf.random_normal(shape=[1,1])) # In[7]: model_output = tf.subtract(tf.matmul(x_data,A),b) # In[8]: l2_norm = tf.reduce_sum(tf.square(A)) alpha = tf.constant([0.1]) classification_term=tf.reduce_mean(tf.maximum(0.,tf.subtract(1.,tf.multiply(model_output,y_target)))) loss = tf.add(classification_term,tf.multiply(alpha,l2_norm)) # In[9]: prediction = tf.sign(model_output) accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction,y_target),tf.float32)) # In[10]: my_opt = tf.train.GradientDescentOptimizer(0.01) train_step = my_opt.minimize(loss) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) # In[11]: loss_vec = [] train_accuracy = [] test_accuracy = [] for i in range(500): rand_index = np.random.choice(len(train_data),size = batch_size) rand_x = train_data[rand_index] rand_y = np.transpose([train_target[rand_index]]) sess.run(train_step,feed_dict={x_data:rand_x,y_target:rand_y}) temp_loss = sess.run(loss,feed_dict={x_data:rand_x,y_target:rand_y}) loss_vec.append(temp_loss) train_acc_temp = sess.run(accuracy,feed_dict={x_data:train_data,y_target:np.transpose([train_target])}) train_accuracy.append(train_acc_temp) test_acc_temp = sess.run(accuracy,feed_dict={x_data:test_data,y_target:np.transpose([test_target])}) test_accuracy.append(test_acc_temp) if (i+1)% 100 ==0: print('step # '+str(i+1)+'A='+str(sess.run(A))+'b='+str(sess.run(b))) print('Loss = '+str(temp_loss)) # In[12]: [[a1],[a2]]= sess.run(A) [[b]]=sess.run(b) slope=-a2/a1 y_intercept=b/a1 x1_vals = [d[1] for d in x_vals] best_fit = [] for i in x1_vals: best_fit.append(slope*i+y_intercept) setosa_x = [d[1] for i,d in enumerate(x_vals) if y_vals[i]==1] setosa_y = [d[0] for i,d in enumerate(x_vals) if y_vals[i]==1] not_setosa_x = [d[1] for i,d in enumerate(x_vals) if y_vals[i]==-1] not_setosa_y = [d[0] for i,d in enumerate(x_vals) if y_vals[i]==-1] best_fit # In[13]: plt.plot(setosa_x,setosa_y,'o',label='I setosa') plt.plot(not_setosa_x,not_setosa_y,'x',label='Non-setosa') plt.plot(x1_vals,best_fit,'r-',label='Linear separator',linewidth=3) plt.ylim([0,10]) plt.legend(loc='lower right') plt.title('sepal length vs edal width') plt.xlabel('pedal width') plt.ylabel('sepal length') plt.show() plt.plot(train_accuracy,'k-',label='Training Accuracy') plt.plot(test_accuracy,'r--',label='Test Accuracy') plt.title('Train and Test Set Accuracy') plt.xlabel('Generation') plt.ylabel('Accuracy') plt.legend(loc='lower right') plt.show() plt.plot(loss_vec,'k--') plt.title('Loss per Generation') plt.xlabel('Generation') plt.ylabel('Loss') plt.show()
非線性分割:
# coding: utf-8 # In[1]: import matplotlib.pyplot as plt import numpy as np import tensorflow as tf from sklearn import datasets # In[11]: sess = tf.Session() x_vals,y_vals = datasets.make_circles(n_samples = 1000,factor=0.5,noise=0.1) y_vals = np.array([1 if y==1 else -1 for y in y_vals]) class1_x = [x[0] for i,x in enumerate(x_vals) if y_vals[i]==1] class1_y = [x[1] for i,x in enumerate(x_vals) if y_vals[i]==1] class2_x = [x[0] for i,x in enumerate(x_vals) if y_vals[i]==-1] class2_y = [x[1] for i,x in enumerate(x_vals) if y_vals[i]==-1] # In[12]: batch_size = 250 x_data = tf.placeholder(shape=[None,2],dtype=tf.float32) y_target = tf.placeholder(shape=[None,1],dtype=tf.float32) prediction_grid = tf.placeholder(shape=[None,2],dtype=tf.float32) b = tf.Variable(tf.random_normal(shape=[1,batch_size])) # In[13]: gamma = tf.constant(-50.0) dist = tf.reduce_sum(tf.square(x_data),1) dist = tf.reshape(dist,[-1,1]) sq_dists = tf.add(tf.subtract(dist,tf.multiply(2.,tf.matmul(x_data,tf.transpose(x_data)))),tf.transpose(dist)) my_kernel = tf.exp(tf.multiply(gamma,tf.abs(sq_dists))) # In[14]: model_output = tf.matmul(b,my_kernel) first_term = tf.reduce_sum(b) b_vec_cross = tf.matmul(tf.transpose(b),b) y_target_cross = tf.matmul(y_target,tf.transpose(y_target)) second_term = tf.reduce_sum(tf.multiply(my_kernel,tf.multiply(b_vec_cross,y_target_cross))) loss = tf.negative(tf.subtract(first_term,second_term)) # In[15]: rA = tf.reshape(tf.reduce_sum(tf.square(x_data),1),[-1,1]) rB= tf.reshape(tf.reduce_sum(tf.square(prediction_grid),1),[-1,1]) pred_sq_dist = tf.add(tf.subtract(rA,tf.multiply(2.,tf.matmul(x_data,tf.transpose(prediction_grid)))),tf.transpose(rB)) pred_kernel = tf.exp(tf.multiply(gamma,tf.abs(pred_sq_dist))) prediction_output = tf.matmul(tf.multiply(tf.transpose(y_target),b),pred_kernel) prediction = tf.sign(prediction_output- tf.reduce_mean(prediction_output)) accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.squeeze(prediction),tf.squeeze(y_target)),tf.float32)) # In[16]: my_opt = tf.train.GradientDescentOptimizer(0.001) train_step = my_opt.minimize(loss) init = tf.global_variables_initializer() sess.run(init) # In[17]: loss_vec = [] batch_accuracy = [] for i in range(500): rand_index = np.random.choice(len(x_vals),size=batch_size) rand_x = x_vals[rand_index] rand_y = np.transpose([y_vals[rand_index]]) sess.run(train_step,feed_dict={x_data:rand_x,y_target:rand_y}) temp_loss = sess.run(loss,feed_dict={x_data:rand_x,y_target:rand_y}) loss_vec.append(temp_loss) acc_temp = sess.run(accuracy,feed_dict={x_data:rand_x,y_target:rand_y,prediction_grid:rand_x}) batch_accuracy.append(acc_temp) if (i+1)%100==0: print('Step #'+str(i+1)) print('Loss = '+str(temp_loss)) # In[18]: x_min,x_max = x_vals[:,0].min()-1,x_vals[:,0].max()+1 y_min,y_max = x_vals[:,1].min()-1,x_vals[:,1].max()+1 xx,yy = np.meshgrid(np.arange(x_min,x_max,0.02),np.arange(y_min,y_max,0.02)) grid_points = np.c_[xx.ravel(),yy.ravel()] [grid_predictions] = sess.run(prediction,feed_dict={x_data:rand_x,y_target:rand_y,prediction_grid:grid_points}) grid_predictions = grid_predictions.reshape(xx.shape) # In[19]: plt.contourf(xx,yy,grid_predictions,cmap = plt.cm.Paired,alpha=0.8) plt.plot(class1_x,class1_y,'ro',label='Class 1') plt.plot(class2_x,class2_y,'kx',label='Class -1') plt.legend(loc='lower right') plt.ylim([-1.5,1.5]) plt.xlim([-1.5,1.5]) plt.show() plt.plot(batch_accuracy,'k-',label='Accuracy') plt.title('Batch Accuracy') plt.xlabel('Generation') plt.ylabel('Accuracy') plt.legend(loc='lower right') plt.show() plt.plot(loss_vec,'k-') plt.title('Loss per Generation') plt.xlabel('Generation') plt.ylabel('Loss') plt.show()