承接上文,
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)正确率下降。