keras分类猫狗数据(番外篇)深度学习CNN连接SVM分类

承接上文,
keras分类猫狗数据(上)数据预处理
keras分类猫狗数据(中)使用CNN分类模型
keras分类猫狗数据(下)迁移学习
keras分类猫狗数据(番外篇)深度学习CNN连接SVM分类


2019年2月23日补充:
(引用回复biyandong)这个是我初学时的代码,有关误解还请见谅。 完整的讲,cnn+svm指的是cnn提取特征,然后由svm再训练,可以看作两步。cnn提取特征可以由Model构建“半截”并输出。这个“半截”从原始图像输入到哪由你来定(调参,玄学)。Svm的输入是这个“半截”cnn的输出。
个人认为svm不能直接加到cnn参与反向传播,一个是梯度问题,或者还有收敛问题(前期的特征不够健壮)。 目前而言,这种拼接普遍是分步进行的。不当之处,敬请指正。以下代码是找到的我的一个实验提取特征部分供参考:

"""
@Time    : 2018/8/27 10:18
@Author  : Lishihang
@File    : exc_feather.py
@Software: PyCharm
@desc: 
"""
from keras import models,Model
import lastExp.Integrate_432_321 as lig
import numpy as np
import pandas as pd

cnn_model=models.load_model("model.h5")
cnn_model.trainable=False
# cnn_model.summary()
#
dense1_layer_model = Model(inputs=cnn_model.input,outputs=cnn_model.get_layer(name='dense_3').input)
dense1_layer_model.trainable=False
dense1_layer_model.summary()

tiffgen=lig.Tiff(fea_src="../data/train_pos_label.txt",size=15).get_one_beatch(batch_size=50)

# while tiffgen.nex

feas=np.zeros(shape=(0,512))
ls=[]
i=0
while True:
    try:
        img, label = tiffgen.__next__()


        res = dense1_layer_model.predict(img)
        feas = np.concatenate((feas, res), axis=0)
        label = np.array(label)
        ls=np.hstack((np.argmax(label,axis=1),ls))
        i+=1
        if i%10==0:
            print("step_i: ",i)
    except StopIteration:
        break
# print(feas.shape)

ls=np.array(ls,dtype=np.int).reshape(-1,1)
feasls=np.concatenate((feas,ls),axis=1)
feasls=pd.DataFrame(feasls)
print(feasls.shape)
# print(feasls.head())
feasls.to_csv("output/train_feasls.csv",index=None,header=None,sep='\t')

如下为原文:

本文使用深度学习的CNN进行特征提取,并使用机器学习经典算法(使用pca降维?)svm在此基础上进行分类。模型参数使用上文迁移学习第一部分训练结果。

from keras.applications import VGG16
from keras.models import Sequential,Model
from keras.layers import Flatten,Dense
from sklearn.decomposition import PCA

########### 加载原模型 ###############
conv_base=VGG16(weights='imagenet',include_top=False,input_shape=(128,128,3))

model = Sequential()
model.add(conv_base)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.trainable=False
model.summary()

model.load_weights('outputs/weights_vgg16_use.h5')

###构建cnn_svm模型,并完成训练#############

def predict_cnnsvm(k,pca=None):#测试批数,共用数据32*k
    s,al=0,0
    for i in range(k):
        res=mp.test_flow.next()
        x,y=res[0],res[1]
        x_temp=dense1_layer_model.predict(x)
        if pca!=None:
            y_temp=clf.predict(pca.transform(x_temp))
        else:
            y_temp = clf.predict(x_temp)
        s+=np.sum(y_temp==y)
        al+=len(y)
    return s*1.0/al

import catvsdogs.morph as mp
dense1_layer_model = Model(inputs=model.input,outputs=model.layers[-2].output)

from sklearn.svm import SVC
import numpy as np
clf=SVC()

X=np.ones((0,256))#原特征维度个数256
Y=np.array([])
for i in range(100): #共用数据100*32个
    res=mp.train_flow.next()
    x,y=res[0],res[1]
    x_temp=dense1_layer_model.predict(x)
    X=np.row_stack((X,x_temp))
    Y=np.append(Y,y)
    print("%d inserted!"%(i*32+32))
print(X.shape)
print(Y.shape)

print("no use pca:")
clf.fit(X,Y)
for _ in range(5):
    pre=predict_cnnsvm(20)
    print("correct_rate:%.3f"%(pre))

print("use pca:")
pca = PCA(n_components=10)
pca.fit(X)
X_new = pca.transform(X)
clf.fit(X_new,Y)
for _ in range(5):
    pre=predict_cnnsvm(20,pca)
    print("correct_rate:%.3f"%(pre))
    

这里写图片描述

这里写图片描述

可以看出,VGG16_SVM(no pca)正确率比之之前的VGG16特征提取全连接层(约88%)有轻微提高,VGG16_SVM(use pca)正确率下降。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值