最近在做毕业设计,其中涉及到使用预训练网络的内容,网上关于这方面的资源也有很多,但是有一些代码有问题,经过一些尝试本小白还是成功的完成了这个功能,主要利用的keras库,关于keras库安装直接在命令行窗口使用pip inatall keras就可以了。在这里把我的代码发出来,望与各位同学一起进步!小白的代码写的比较渣……
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 27 15:30:38 2018
@author: 13260
"""
"""
功能:提取VGG19卷积层特征并保存
"""
#from keras.applications.resnet50 import ResNet50
from keras.applications.densenet import DenseNet201,preprocess_input
from keras.preprocessing import image
#from keras.applications.resnet50 import preprocess_input
from keras.models import Model
from sklearn.cluster import MiniBatchKMeans
from keras.utils import plot_model
from sklearn import preprocessing
import numpy as np
import os
"""
功能:读取所有图片路径
输入:数据库路径
输出:所有图片路径
"""
def read_all_imgs(data_dir):
catalogs = os.listdir(data_dir)
imgSet = []
for i in range(len(catalogs)):
catalog_path = data_dir + catalogs[i]
for img in os.listdir(catalog_path):
#imgs = [catalog_path + "/" + img for img in catalog_path]
img_path = catalog_path + "/" + img
imgSet.append(img_path)
#print(len(imgSet))
print("[INFO]There are " + str(len(imgSet)) + " images……")
return imgSet
"""
功能:提取图像对应模型的卷积层特征
输入:1、CNN模型 2、图片路径
输出:图像对应特征
"""
def extract_conv_feature(model,img_path):
img = image.load_img(img_path)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
conv_features = model.predict(x)
#print("[INFO]Feature has been extracted !")
return conv_features
"""
功能:读取卷积层特征文件
输入:特征文件路径
输出:特征
"""
def load_conv_feature(feature_path):
conv_feature = np.load(feature_path)
return conv_feature
"""
功能:提取卷积特征图中的局部特征
输入:图像的卷积层特征,形式(samples,rows,cols,filters)
输出:图像卷积特征向量的集合,形式(rows*cols,filters)
"""
def flatten_conv_feature(conv_feature):
num_c = conv_feature.shape[2]
num_r = conv_feature.shape[1]
tmp_feature = []
for i in range(num_c):
for j in range(num_r):
tmp_feature.append(conv_feature[0,i,j,:].flatten())
tmp_feature = np.array(tmp_feature)
return tmp_feature
"""
功能:提取所有图像的卷积层特征(展开)
输入:图片路径
输出:所有图像的卷积层特征
"""
def get_all_local_feature(model,imgSet):
all_feature = []
max_num = len(imgSet)
for i in range(max_num):
conv_feature = extract_conv_feature(model,imgSet[i])
if i % 500 == 0:
print("[INFO]" + str(i) + " images'conv_feature has been extracted !")
#flatten_feature = flatten_conv_feature(conv_feature)
flatten_feature = flatten_conv_feature(conv_feature)
all_feature.append(flatten_feature)
all_feature = np.array(all_feature)
print("[INFO] All conv_feature has been extracted !")
return all_feature
"""
功能:提取所有图像的卷积层特征(未展开)
"""
def get_no_flatten_feature(model,imgSet):
all_feature = []
max_num = len(imgSet)
for i in range(max_num):
conv_feature = extract_conv_feature(model,imgSet[i])
if i % 500 == 0:
print("[INFO]" + str(i) + " images'conv_feature has been extracted !")
all_feature.append(conv_feature)
all_feature = np.array(all_feature)
print("[INFO] All conv_feature has been extracted !")
return all_feature
def save_feature(feature,path):
np.save(path,feature)
print("[INFO] File has been saved !")
def main():
img_dir = "F:/shiyan/TensorFlow/retrain/data/train/" #图像数据路径
imgSet = read_all_imgs(img_dir)
# 如果提取卷积层特征的话,模型include_top属性设置为False,若提取全连接层特征则include_top属性设置为True
# 加载DenseNet201预训练模型,如果需要用其他的模型则直接替换模型即可,别的代码都不用动
base_model = DenseNet201(weights='imagenet', include_top=False)
#base_model = ResNet50(weights='imagenet', include_top=False)
# 根据keras种网络结构中每一层网络的名字,直接用get_layer(网络层名称).output就可以获取对应层的输出结果
# 如果不知道网络层名称,可以使用model.summery()将模型每一层打印出来即可
model = Model(inputs=base_model.input, outputs=base_model.get_layer('conv5_block32_concat').output)
#model = Model(inputs=base_model.input, outputs=base_model.get_layer('block5_conv3').output)
print("[INFO] Model has been loaded !")
"""未展开"""
all_conv_feature = get_no_flatten_feature(model,imgSet)
print(all_conv_feature.shape)
path = "F:/python/features/DenseNet/DenseNet201_conv_feature.npy"
save_feature(all_conv_feature,path)
if __name__ == "__main__":
main()
