用tensorflow實現SVM


環境配置

win10

Python 3.6

tensorflow1.15

scipy

matplotlib (運行時可能會遇到module tkinter的問題)

sklearn 一個基於Python的第三方模塊。sklearn庫集成了一些常用的機器學習方法。

 

代碼實現

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import datasets
from tensorflow.python.framework import ops
ops.reset_default_graph()

sess = tf.Session()

Session API

Session的詳細作用

Session是tensorflow中的一個執行OP和計算tensor的一個類。

framework API

補充:

  • 張量(tensor):TensorFlow程序使用tensor數據結構來代表所有的數據,計算圖中,操作間傳遞的數據都是tensor,你可以把TensorFlow tensor看做一個n維的數組或者列表。
  • 變量(Variable):常用於定義模型中的參數,是通過不斷訓練得到的值。比如權重和偏置。
  • 占位符(placeholder):輸入變量的載體。也可以理解成定義函數時的參數。
  • 圖中的節點操作(op):一個op獲得0個或者多個Tensor,執行計算,產生0個或者多個Tensor。op是描述張量中的運算關系,是網絡中真正結構

 

# Load the data
# 加載iris數據集並為每類分離目標值。
# 因為我們想繪制結果圖,所以只使用花萼長度和花瓣寬度兩個特征。
# 為了便於繪圖,也會分離x值和y值
# iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]
iris = datasets.load_iris()
x_vals = np.array([[x[0], x[3]] for x in iris.data])
y_vals1 = np.array([1 if y==0 else -1 for y in iris.target])
y_vals2 = np.array([1 if y==1 else -1 for y in iris.target])
y_vals3 = np.array([1 if y==2 else -1 for y in iris.target])
y_vals = np.array([y_vals1, y_vals2, y_vals3])
#取前兩項作為圖的橫縱坐標
class1_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==0]
class1_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==0]
class2_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==1]
class2_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==1]
class3_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==2]
class3_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==2]

datasets是sklearn中的 一個包,提供了一些經典的數據集以作模型的運算。

特征存儲在iris.data中,標簽存儲在iris.target中

enumerate()

# Declare batch size
# 變量的最高維度
batch_size = 50
 
# Initialize placeholders
# 數據集的維度在變化,從單類目標分類到三類目標分類。
# 我們將利用矩陣傳播和reshape技術一次性計算所有的三類SVM。
# 注意,由於一次性計算所有分類,
# y_target占位符的維度是[3,None],模型變量b初始化大小為[3,batch_size]
x_data = tf.placeholder(shape=[None, 2], dtype=tf.float32)
y_target = tf.placeholder(shape=[3, None], dtype=tf.float32)
prediction_grid = tf.placeholder(shape=[None, 2], dtype=tf.float32)
 
# Create variables for svm
b = tf.Variable(tf.random_normal(shape=[3,batch_size]))
 
# Gaussian (RBF) kernel 核函數只依賴x_data
gamma = tf.constant(-10.0)
#dist = tf.reduce_sum(tf.square(x_data), 1)
#dist = tf.reshape(dist, [-1,1])
sq_dists = tf.multiply(2., tf.matmul(x_data, tf.transpose(x_data)))

my_kernel = tf.exp(tf.multiply(gamma, tf.abs(sq_dists)))

tf.placeholder()--占位符相當於預先分配

Variable API

reduce()--減小矩陣維數,求和

reshape--重新構造矩陣

注:

multiply--實現元素相乘,相同位置的元素相乘

matmul--實現矩陣相乘

Python 矩陣傳播--Python為優化矩陣計算的一系列方法

高斯核函數

# Declare function to do reshape/batch multiplication
# 最大的變化是批量矩陣乘法。
# 最終的結果是三維矩陣,並且需要傳播矩陣乘法。
# 所以數據矩陣和目標矩陣需要預處理,比如xT·x操作需額外增加一個維度。
# 這里創建一個函數來擴展矩陣維度,然后進行矩陣轉置,
# 接着調用TensorFlow的tf.batch_matmul()函數
# 轉置后的矩陣與原矩陣相乘(增維可能是為了消除參數項中的常數項)
def reshape_matmul(mat):
  v1 = tf.expand_dims(mat, 1)
  v2 = tf.reshape(v1, [3, batch_size, 1])
  return(tf.matmul(v2, v1))
 
# Compute SVM Model 計算對偶損失函數
first_term = tf.reduce_sum(b)
b_vec_cross = tf.matmul(tf.transpose(b), b)
y_target_cross = reshape_matmul(y_target)
 
second_term = tf.reduce_sum(tf.multiply(my_kernel, tf.multiply(b_vec_cross, y_target_cross)),[1,2])
loss = tf.reduce_sum(tf.negative(tf.subtract(first_term, second_term)))

tf.expend_dims()

# Gaussian (RBF) prediction kernel
# 現在創建預測核函數。
# 要當心reduce_sum()函數,這里我們並不想聚合三個SVM預測,
# 所以需要通過第二個參數告訴TensorFlow求和哪幾個
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)))
 
# 實現預測核函數后,我們創建預測函數。
# 與二類不同的是,不再對模型輸出進行sign()運算。
# 因為這里實現的是一對多方法,所以預測值是分類器有最大返回值的類別。
# 使用TensorFlow的內建函數argmax()來實現該功能
prediction_output = tf.matmul(tf.multiply(y_target,b), pred_kernel)
prediction = tf.arg_max(prediction_output-tf.expand_dims(tf.reduce_mean(prediction_output,1), 1), 0)
accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction, tf.argmax(y_target,0)), tf.float32))
 
# Declare optimizer
my_opt = tf.train.GradientDescentOptimizer(0.01)
train_step = my_opt.minimize(loss)
 
# Initialize variables
init = tf.global_variables_initializer()
sess.run(init)

tf.cast()//類型轉化

# Save graph
write_log = tf.summary.FileWriter('./log',tf.get_default_graph())
 
# Training loop
loss_vec = []
batch_accuracy = []
for i in range(100):
  #取隨機數訓練模型
  rand_index = np.random.choice(len(x_vals), size=batch_size)
  rand_x = x_vals[rand_index]
  rand_y = 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)%25==0:
    print('Step #' + str(i+1))
    print('Loss = ' + str(temp_loss))
 
# 創建數據點的預測網格,運行預測函數
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)

np.random.choice()

# 測試random.choice程序
import numpy as np
x=np.array([[0,1],[1,2],[2,3]])
randx=np.random.choice(len(x), size=3)
print(x)
#print('\n')
print(randx)
print(x[randx])
#print(x[:,randx])
print(len(x))

image.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM