从MLP到SVM

任务简报

目标:把全连接层的特征保存下来,然后训练SVM分类器
第一步:提取训练数据和验证数据的特征
第二步:训练SVM分类器
第三步:在验证集上进行测试

这是一个隔靴搔痒的答案。此举的真实意图是,用SVM换掉现在的网络中使用的多层感知机(两个全连接层),并寄希望于这个小动作能够带来更好的分类结果。

预备工作

治大国,如烹小鲜,以道莅天下,其鬼不神。 ——《道德经》

在前人的代码上工作,最忌大刀阔斧。此事最温和的解决方案莫过于重建一如当年的工作环境。此事颇有几分艰辛,但尚且用得。随便挑选一个顺手的位置,创建一个复古的virtualenv

virtualenv TF011
cd TF011
source bin/activate
pip install tensorlayer==1.2.8
# 下面这句话取决于你具体把这个古老的TF放在了哪里
pip install tensorflow-0.11.0-cp27-none-linux_x86_64.whl

接下来克隆原始的代码

git clone https://github.com/GuangmingZhu/Conv3D_CLSTM.git

就可以上路了。

提取训练数据和验证数据的特征

这一步的主要思路是,把原来的训练代码中控制网络训练的代码换成用来计算特征值的代码,然后借用原有的绝大多数代码完成工作。这么做可以绕开读取数据这个天大的麻烦。

截胡

先前的代码是仅仅关心最终产物,也就是动作的分类结果的。但是我们现在想要的已经训练好的网络产生的中间特征。所以,在大刀阔斧地开始之前,我们总先要找出访问全连接层的特征的办法。所幸拿到些个东西并不很难,对c3d_clstm.py的141行稍动手脚

    return concat_spp, classes

就可以拿到分类器的前一层——SPP模块计算出的特征。

拿到简单,用却是另外一个故事。在training_isogr_rgb.py的48行,先为接收特征做点准备工作:

feature_layer, networks = net.c3d_clstm(x, num_classes, False, True)

这里的feature_layernetworks都是使用TensorLayer构造的层。要拿到他们的产出,只消有样学样地复制一下后面一行(training_isogr_rgb.py第49行)

feature = feature_layer.outputs

贴在下面就好。这里的feature是TF计算图模型中的一个Tensor。

初始化网络

加载TL由保存的网络参数的代码可以直接从http://tensorlayercn.readthedocs.io/zh/latest/modules/files.html
借来

load_params = tl.files.load_npz(path='', name='isogr_rgb_model_strategy_4.npz')
tl.files.assign_params(sess, load_params, networks)

把这两行放在101行初始化所有变量之后就好。

另外,毕竟我们并不需要训练这个网络,221-223行用于保存训练结果的东西是需要删掉的。

计算特征

使用一个网络远比训练一个网络要省心得多,只要保证所有的数据都被送进网络计算一次就万事大吉了。所以,

  • 174行n_epoch的可以放心地改成1
  • 178行batch_size的可以放心地改成1
  • 179行shuffle可以放心的改成False关掉
  • 196-218行留之无用,删掉

接下来是全文的重点,第194行。

_,loss_value,lr_value,acc = sess.run([train_op,cost,lr,networks_accu], feed_dict=feed_dict)

这里先执行了一次训练迭代train_op,然后计算损失函数的值cost、更新学习率lr,并评估了一下目前网络的靠谱程度networks_accu。然而这四件事情与我们的目标——提取训练数据和验证数据的特征——一点关系都没有。
为了实现最初的目的,我们需要把这段控制网络训练的代码换成计算特征值的代码

feature_value = sess.run(feature, feed_dict=feed_dict)

保存结果

我们需要同时保存特征和标记。到目前为止,特征是feature_value,标记则在原有的代码里,可以通过feed_dict[y]拿到。这两个东西都是numpy格式的,直接使用np.save就能保存成文件。原始的代码里有一个现成的计数器step,可以借用来创建不同的文件名。

另外,feature_value的形状是[1, 26880], feed_dict[y]的形状是[1],这显然有些别扭。为了让后面的事情更顺手,在保存的时候可以直接把这个碍事的维度裁掉。

np.save('train_{}.npy'.format(step), (feature_value[0, :], feed_dict[y][0]))

至此,训练集中所有样本的特征值和标记都可以被保存成train_xxx.npy这样的文件了。
对源文件的251行前后做类似的事情,可以获得验证集中所有数据的特征值和标记,把它们保存成val_xxx.npy之类的文件,第一步就算大功告成。

训练SVM分类器

第二步,使用刚刚保存的train_xxx.npy训练一个SVM分类器。
第三步:在验证集上进行测试

整理数据

现在,看看文件的编号就可以知道一共有多少个训练数据了。不过,为了更省心的训练一个SVM,我们最好先把这些零碎的数据拼起来。

现在,姑且假设一共有2333个训练数据、517个验证数据吧……至少这两个数字足够惹眼,抄代码的时候不会漏掉。

import numpy as np

x_train = np.ndarray([2333, 26880], dtype=np.float32)
y_train = np.ndarray([2333,], dtype=np.float32)
for i in range(2333):
    x, y = np.load('train_{}.npy'.format(i))
    x_train[i, ...] = x
    y_train[i] = y

x_val = np.ndarray([517, 26880], dtype=np.float32)
y_val = np.ndarray([517,], dtype=np.float32)
for i in range(517):
    x, y = np.load('val_{}.npy'.format(i))
    x_val[i, ...] = x
    y_val[i] = y

训练一个SVM并在验证集上进行测试

大概没有比sklearn更简单的方法了吧。在开始使用之前可能需要先安装一下:

pip install -U scikit-learn

随后是一段异常简单(5行)的代码

import sklearn.svm
# SVC 中的 C 是分类器的意思
# ovr, one-over-rest, 要求分类器最后给出输入分别属于各个类别的可能性
svm = sklearn.svm.SVC(decision_function_shape='ovr')
# 训练可能并不很快
svm.fit(x_train, y_train)
# decision_function 是SVM训练好之后得到的决策函数
# argmax 用来找到每个验证数据最可能属于的类别的序号
h_val = svm.decision_function(x_val).argmax(1)
# 准确率 = 被正确分类的样本数目 / 验证集大小
acc = (h_val == y_val).sum() / len(y_val)
print('Accuracy = {}.format(acc))

全文完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容