2017-07-26 58 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

很高兴帮助,希望你找到有用的笔记。有时他们可能很密集,但他们写得很好 –