[tensorflow应用之路]10行代码实现一个完整的SVM分类器

8 篇文章 0 订阅
1 篇文章 0 订阅

SVM是一种常用的机器学习分类器模型,其原理为最大化类间隔(被称为支持向量),来达到分类的目的。它是一种有监督的模型。

SVM原理简述

SVM通过预测值 y=wx+b y ′ = w x + b 与真实值 y y 之间的差值实现最大间隔分类。即

wx+b1,y=1wx+b1,y=1

非常简单,两个支持向量的间隔为 2w2 2 ‖ w ‖ 2 ,所以最小化 w2 ‖ w ‖ 2 ,就可以使支持向量的间隔最大化。
由拉格朗日变换,可得最终的损失定义为:

loss=hinge(y,y)+w2hinge(y,y)=max(1y(wx+b),0) l o s s = h i n g e ( y ′ , y ) + ‖ w ‖ 2 h i n g e ( y ′ , y ) = m a x ( 1 − y ( w x + b ) , 0 )

ref: Computing the SVM classifier

7行代码实现SVM核心

import tensorflow as tf

w = tf.Variable(tf.random_uniform([1, 2]))
b = tf.Variable(tf.random_uniform((1,)))
logit = tf.matmul(w, next_x, transpose_b=True) + b
logit = tf.tanh(logit)
prediction = tf.tanh(tf.matmul(w, next_x, transpose_b=True) + b)
loss = tf.losses.hinge_loss(next_y, logit) + tf.norm(w, 2)
opt = tf.train.RMSPropOptimizer(1e-2).minimize(loss)

传统的SVM使用SMO算法求解,但是既然我们有RMS/ADAM这样的局部优化方法,也可以直接用这种方法。
ref:Implementation

The parameters of the maximum-margin hyperplane are derived by solving the optimization. There exist several specialized algorithms for quickly solving the QP problem that arises from SVMs, mostly relying on heuristics for breaking the problem down into smaller, more-manageable chunks.
\
Another approach is to use an interior point method that uses Newton-like iterations to find a solution of the Karush–Kuhn–Tucker conditions of the primal and dual problems.[34] Instead of solving a sequence of broken down problems, this approach directly solves the problem altogether. To avoid solving a linear system involving the large kernel matrix, a low rank approximation to the matrix is often used in the kernel trick.
\
Another common method is Platt’s **sequential minimal optimization (SMO)**algorithm, which breaks the problem down into 2-dimensional sub-problems that are solved analytically, eliminating the need for a numerical optimization algorithm and matrix storage. This algorithm is conceptually simple, easy to implement, generally faster, and has better scaling properties for difficult SVM problems

测试结果

构造数据输入

我们构造一个线性的分类问题,使得 y<x y < x 为-1类, y>x y > x 为1类,注意这里写的xy只是表示二维数据中的第一位和第二位,实际上同属于输入数据(input),(-1,1)构成输入数据的真实标签(label)。数据生成器如下:

def generate_point():
    while True:
        input = (np.random.rand(2) - 0.5) * 20
        output = input[1] > input[0]
        yield input, output.astype(np.float32)

利用tensorflow.data生成batch序列:

    gen = generate_point
    data = tf.data.Dataset.from_generator(gen, (tf.float32, tf.float32))
    data = data.batch(batchsize).prefetch(2)
    data = data.make_one_shot_iterator()
    next_x, next_y = data.get_next()

完整实现代码

以下是实现线性SVM分类器的完整代码

import tensorflow as tf
import numpy as np
import os
import matplotlib.pyplot as plt


def generate_point():
    while True:
        input = (np.random.rand(2) - 0.5) * 20
        output = input[1] > input[0]
        yield input, output.astype(np.float32)


def SVM():
    batchsize = 256
    # 构建数据输入
    gen = generate_point
    data = tf.data.Dataset.from_generator(gen, (tf.float32, tf.float32))
    data = data.batch(batchsize).prefetch(2)
    data = data.make_one_shot_iterator()
    next_x, next_y = data.get_next()

    # 构建SVM
    w = tf.Variable(tf.random_uniform([1, 2]))
    b = tf.Variable(tf.random_uniform((1,)))
    logit = tf.matmul(w, next_x, transpose_b=True) + b
    logit = tf.tanh(logit)
    prediction = tf.tanh(tf.matmul(w, next_x, transpose_b=True) + b)
    loss = tf.losses.hinge_loss(next_y, logit) + tf.norm(w, 2)
    opt = tf.train.RMSPropOptimizer(1e-2).minimize(loss)

    xy = []
    for i in range(batchsize):
        xy += [next(gen())[0]]
    xy = np.stack(xy, 0)
    i = 0
    gpu_options = tf.GPUOptions(allow_growth=True)
    with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:
        sess.run(tf.global_variables_initializer())
        while True:
            sess.run(opt)
            prd = sess.run(prediction, {next_x:xy})
            for p, l in zip(xy, np.squeeze(prd)):
                if l > 0:
                    plt.scatter(p[0], p[1], c='red')
                else:
                    plt.scatter(p[0], p[1], c='green')
            plt.show()
            i += 1


if __name__ == '__main__':
    os.environ['CUDA_VISIBLE_DEVICES'] = '1'
    SVM()

结果

这里写图片描述

为什么没有非线性SVM

SVM的非线性是通过核函数实现的。在实现核函数的后,还需要用到标注数据y和训练数据x才可以完成结果预测。也就是说,非线性SVM的时间复杂度不仅和模型本身有关系,还和训练数据的数量有关系,从公式看,大概是平方反比的关系。那么就会造成一种情况:理论上来说训练数据愈多,模型的泛化能力越强,但训练数据增多,反而会减慢非线性SVM的预测速度
基于此,我认为这种方法的用处太有限,所以没有实现它。
有兴趣的朋友可以参照tensorflow_cookbook/nonliner_SVM

结论

我写这篇的目的是为了让更多刚接触tf的人看到,tensorflow不仅是一个深度学习的框架,而更多的是——正如google当初的愿景一样——做成一个机器学习通用的工具包。你可以用它实现Adaboost,random forest,Conditional random field, naive bayes等所有你想得到的经典机器学习算法。
我刚接触tensorflow时也认为这个库太大,冗余api太多。但是实际上,tf的冗余另一方面也带来了更多的可能性。所以加油吧,你越多的接触这个库,你越会喜欢上这个库!

最后,祝您身体健康,再见!

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Convex对图像进分类学习是一种常用的机器学习方法,其代码实现包括以下步骤: 1. 数据准备:从图像数据集中获取训练数据和测试数据。训练数据应包括已经标记好的图像和对应的分类标签,例如猫、狗、汽车等。测试数据是用来验证模型性能的。 2. 特征提取:将图像转化为数值型的特征向量。常见的特征提取方法包括颜色直方图、局部二值模式(LBP)等。特征提取的目的是保留图像的有用信息,减少冗余。 3. 模型训练:使用Convex进图像分类的代码实现,可以使用Python的机器学习库如Scikit-learn、Tensorflow等。首先,选择一个合适的分类算法,如支持向量机(SVM)、随机森林(Random Forest)等。然后,将训练数据输入到模型中,通过模型训练得到分类器。 4. 模型评估:使用测试数据对训练好的模型进评估,评估指标可以包括准确率、召回率、F1-score等。评估结果可以帮助我们了解模型的性能和泛化能力。 5. 模型应用:将训练好的模型用于实际的图像分类任务。给定一个新的图像,通过特征提取和经过训练的分类器,可以将其归类到对应的标签中。这样,就可以实现对图像的分类。 Convex对图像进分类学习的代码实现需要注意的是数据的准备和特征的选择,不同的数据集和特征选择可能会对结果产生重要影响。此外,模型训练的过程中需要谨慎选择超参数,以提高模型的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值