2017-07-26 59 views
1

我一直在關注吳教授的講座,並試圖在我的jupyter筆記本上使用tensorflow實現SVM。但是,我的模型似乎沒有正確收斂。支持向量機Tensorflow的實現

Scattered plot after 5000 steps of training

我想我有錯的損失函數,並且最終可能會不恰當地適合我的模型。

而且下面是我的模型的全圖構建代碼:

tf.reset_default_graph() 

#training hyper parameters 

learning_rate = 0.000001 
C = 20 
gamma = 50 

X = tf.placeholder(tf.float32, shape=(None,2)) 
Y = tf.placeholder(tf.float32, shape=(None,1)) 
landmark = tf.placeholder(tf.float32, shape=(None,2)) 

W = tf.Variable(np.random.random((num_data)),dtype=tf.float32) 
B = tf.Variable(np.random.random((1)),dtype=tf.float32) 

batch_size = tf.shape(X)[0] 

#RBF Kernel 
tile = tf.tile(X, (1,num_data)) 
diff = tf.reshape(tile, (-1, num_data, 2)) - landmark 
tile_shape = tf.shape(diff) 
sq_diff = tf.square(diff) 
sq_dist = tf.reduce_sum(sq_diff, axis=2) 
F = tf.exp(tf.negative(sq_dist * gamma)) 

WF = tf.reduce_sum(W * F, axis=1) + B 

condition = tf.greater_equal(WF, 0) 
H = tf.where(condition, tf.ones_like(WF),tf.zeros_like(WF)) 

ERROR_LOSS = C * tf.reduce_sum(Y * tf.maximum(0.,1-WF) + (1-Y) * tf.maximum(0.,1+WF)) 
WEIGHT_LOSS = tf.reduce_sum(tf.square(W))/2 

TOTAL_LOSS = ERROR_LOSS + WEIGHT_LOSS 

optimizer = tf.train.GradientDescentOptimizer(learning_rate) 
train = optimizer.minimize(TOTAL_LOSS) 

我使用高斯核和餵養整個訓練設置爲地標。

只要我有正確的實施,損失函數是完全相同的演講中顯示。

Loss function on the lecture

我敢肯定,我失去了一些東西。

回答

2

請注意,內核矩陣應該有batch_size^2條目,而您的張量WF已經形成(batch_size, 2)。這個想法是計算數據集中每對(x_i,x_j)的K(x_i,x_j),然後將這些內核值用作SVM的輸入。

我在支持向量機上使用Andrew Ng's lecture notes作爲參考;在第20頁,他得出了最終的優化問題。您將需要用內核功能替換內部產品<x_i, x_j>

我建議從線性內核開始,而不是RBF,並將您的代碼與開箱即用的SVM實現(如sklearn's)進行比較。這將幫助您確保優化代碼正常工作。

最後一點:雖然應該有可能使用梯度下降訓練SVM,但他們在實踐中幾乎從未受過這種訓練。支持向量機優化問題可以通過二次規劃解決,大多數訓練支持向量機的方法利用了這一點。

+0

感謝您的回答!我需要開始檢查講義。 – goofcode

+0

很高興幫助,希望你找到有用的筆記。有時他們可能很密集,但他們寫得很好 –