使用Keras预训练模型ResNet50进行图像分类

使⽤Keras预训练模型ResNet50进⾏图像分类
版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。 blog.csdn/u010632850/article/details/77926679
Keras提供了⼀些⽤ImageNet训练过的模型:Xception,VGG16,VGG19,ResNet50,InceptionV3。在使⽤这些模型的时候,有⼀个参数include_top表⽰是否包含模型顶部的全连接层,如果包含,则可以将图像分为ImageNet中的1000类,如果不包含,则可以利⽤这些参数来做⼀些定制的事情。在运⾏时⾃动下载有可能会失败,需要去⽹站中⼿动下载,放在“~/.keras/models/”中,使⽤WinPython 则在“settings/.keras/models/”中。
修正:表⽰当前是训练模式还是测试模式的参数K.learning_phase()⽂中表述和使⽤有误,在该函数说明中可以看到:
The learning phase flag is a bool tensor (0 = test, 1 = train),所以0是测试模式,1是训练模式,部分⽹络结构下两者有差别。
我使⽤的版本:
1.      Ubuntu 16.04.3
2.      Python 2.7
3.      Keras 2.0.8
4.      Tensoflow 1.3.0
5.      Numpy 1.13.1
6.      python-opencv 2.4.9.1+dfsg-1.5ubuntu1
7.      h5py 2.7.0
从⽂件夹中提取图像数据的⽅式:
函数:
def eachFile(filepath):                #将⽬录内的⽂件名放⼊列表中
pathDir =  os.listdir(filepath)
out = []
for allDir in pathDir:
child = allDir.decode('gbk')    # .decode('gbk')是解决中⽂显⽰乱码问题
out.append(child)
return out
def get_data(data_name,train_left=0.0,train_right=0.7,train_all=0.7,resize=True,data_format=None,t=''):  #从⽂件夹中获取图像数据
file_name = os.path.join(pic_dir_out,data_name+t+'_'+str(train_left)+'_'+str(train_right)+'_'+str(Width)+"X"+str(Height)+".h5")
print file_name
if ists(file_name):          #判断之前是否有存到⽂件中
f = h5py.File(file_name,'r')
气囊止血带if t=='train':
X_train = f['X_train'][:]
y_train = f['y_train'][:]
f.close()
return (X_train, y_train)
elif t=='test':
X_test = f['X_test'][:]
y_test = f['y_test'][:]
f.close()
return (X_test, y_test)
else:
return
data_format = alize_data_format(data_format)
pic_dir_set = eachFile(pic_dir_data)
pic_dir_set = eachFile(pic_dir_data)
X_train = []
y_train = []
X_test = []
y_test = []
label = 0
for pic_dir in pic_dir_set:
print pic_dir_data+pic_dir
if not os.path.isdir(os.path.join(pic_dir_data,pic_dir)):
continue
pic_set = eachFile(os.path.join(pic_dir_data,pic_dir))
pic_index = 0
train_count = int(len(pic_set)*train_all)
train_l = int(len(pic_set)*train_left)
train_r = int(len(pic_set)*train_right)
for pic_name in pic_set:
if not os.path.isfile(os.path.join(pic_dir_data,pic_dir,pic_name)):                continue
img = cv2.imread(os.path.join(pic_dir_data,pic_dir,pic_name))            if img is None:
continue
if (resize):
img = size(img,(Width,Height))
img = shape(-1,Width,Height,3)
if (pic_index < train_count):
if t=='train':
if (pic_index >= train_l and pic_index < train_r):
X_train.append(img)
y_train.append(label)
else:
if t=='test':
X_test.append(img)
y_test.append(label)
pic_index += 1
if len(pic_set) <> 0:
label += 1
f = h5py.File(file_name,'w')
if t=='train':
X_train = np.concatenate(X_train,axis=0)
y_train = np.array(y_train)
f.close()
return (X_train, y_train)
elif t=='test':
X_test = np.concatenate(X_test,axis=0)
y_test = np.array(y_test)
f.close()
return (X_test, y_test)
else:
return
调⽤:
global Width, Height, pic_dir_out, pic_dir_data
Width = 224
Height = 224
num_classes = 102              #Caltech101为102  cifar10为10
pic_dir_out = '/home/ccuux3/pic_cnn/pic_out/'
pic_dir_data = '/home/ccuux3/pic_cnn/pic_dataset/Caltech101/'
sub_dir = '224_resnet50/'
if not os.path.isdir(os.path.join(pic_dir_out,sub_dir)):
os.mkdir(os.path.join(pic_dir_out,sub_dir))
pic_dir_mine = os.path.join(pic_dir_out,sub_dir)
(X_train, y_train) = get_data("Caltech101_color_data_",0.0,0.7,data_format='channels_last',t='train')
y_train = _categorical(y_train, num_classes)
载⼊预训练模型ResNet50,并将训练图像经过⽹络运算得到数据,不包含顶部的全连接层,得到的结果存成⽂件,以后可以直接调⽤(由于我内存不够,所以拆分了⼀下):
input_tensor = Input(shape=(224, 224, 3))
base_model = ResNet50(input_tensor=input_tensor,include_top=False,weights='imagenet')
#base_model = ResNet50(input_tensor=input_tensor,include_top=False,weights=None)
get_resnet50_output = K.function([base_model.layers[0].input, K.learning_phase()],
[base_model.layers[-1].output])
file_name = os.path.join(pic_dir_mine,'resnet50_train_output'+'.h5')
if ists(file_name):
f = h5py.File(file_name,'r')
resnet50_train_output = f['resnet50_train_output'][:]
f.close()
else:
you商城resnet50_train_output = []
delta = 10
for i in range(0,len(X_train),delta):
print i
one_resnet50_train_output = get_resnet50_output([X_train[i:i+delta], 0])[0]
resnet50_train_output.append(one_resnet50_train_output)
resnet50_train_output = np.concatenate(resnet50_train_output,axis=0)
f = h5py.File(file_name,'w')
f.close()
将ResNet50⽹络产⽣的结果⽤于图像分类:
input_tensor = Input(shape=(1, 1, 2048))
x = Flatten()(input_tensor)
x = Dense(1024, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=input_tensor, outputs=predictions)
modelpile(optimizer=Adam(), loss='categorical_crossentropy',metrics=['accuracy'])现代主义绘画
训练图像数据集:
print('\nTraining ------------')    #从⽂件中提取参数,训练后存在新的⽂件中
cm = 0                              #修改这个参数可以多次训练
cm_str = '' if cm==0 else str(cm)
cm2_str = '' if (cm+1)==0 else str(cm+1)
if cm >= 1:
model.load_weights(os.path.join(pic_dir_mine,'cnn_model_Caltech101_resnet50_'+cm_str+'.h5'))
model.fit(resnet50_train_output, y_train, epochs=10, batch_size=128,)
model.save_weights(os.path.join(pic_dir_mine,'cnn_model_Caltech101_resnet50_'+cm2_str+'.h5'))
测试图像数据集:
(X_test, y_test) = get_data("Caltech101_color_data_",0.0,0.7,data_format='channels_last',t='test')
y_test = _categorical(y_test, num_classes)
file_name = os.path.join(pic_dir_mine,'resnet50_test_output'+'.h5')
if ists(file_name):
f = h5py.File(file_name,'r')
正交试验resnet50_test_output = f['resnet50_test_output'][:]
f.close()
else:
resnet50_test_output = []
delta = 10
for i in range(0,len(X_test),delta):
print i
one_resnet50_test_output = get_resnet50_output([X_test[i:i+delta], 0])[0]
resnet50_test_output.append(one_resnet50_test_output)
resnet50_test_output = np.concatenate(resnet50_test_output,axis=0)
f = h5py.File(file_name,'w')
f.close()
print('\nTesting ------------')    #对测试集进⾏评估
class_name_list = get_name_list(pic_dir_data)    #获取top-N的每类的准确率
pred = model.predict(resnet50_test_output, batch_size=32)
输出测试集各类别top-5的准确率:
N = 5
pred_list = []
for row in pred:
pred_list.append(row.argsort()[-N:][::-1])  #获取最⼤的N个值的下标
pred_array = np.array(pred_list)
test_arg = np.argmax(y_test,axis=1)
class_count = [0 for _ in xrange(num_classes)]
class_acc = [0 for _ in xrange(num_classes)]
for i in xrange(len(test_arg)):
class_count[test_arg[i]] += 1
if test_arg[i] in pred_array[i]:
class_acc[test_arg[i]] += 1
print('top-'+str(N)+' all acc:',str(sum(class_acc))+'/'+str(len(test_arg)),sum(class_acc)/float(len(test_arg)))    for i in xrange(num_classes):
print (i, class_name_list[i], 'acc: '+str(class_acc[i])+'/'+str(class_count[i]))
完整代码:
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import h5py
import os
from keras.utils import np_utils, conv_utils
dels import Model
from keras.layers import Flatten, Dense, Input
from keras.optimizers import Adam
from snet50 import ResNet50
from keras import backend as K
def get_name_list(filepath):                #获取各个类别的名字
pathDir =  os.listdir(filepath)
out = []
for allDir in pathDir:
for allDir in pathDir:
if os.path.isdir(os.path.join(filepath,allDir)):
child = allDir.decode('gbk')    # .decode('gbk')是解决中⽂显⽰乱码问题
out.append(child)
return out
def eachFile(filepath):                #将⽬录内的⽂件名放⼊列表中
pathDir =  os.listdir(filepath)
out = []
for allDir in pathDir:
child = allDir.decode('gbk')    # .decode('gbk')是解决中⽂显⽰乱码问题
out.append(child)
return out
def get_data(data_name,train_left=0.0,train_right=0.7,train_all=0.7,resize=True,data_format=None,t=''):  #从⽂件夹中获取图像数据    file_name = os.path.join(pic_dir_out,data_name+t+'_'+str(train_left)+'_'+str(train_right)+'_'+str(Width)+"X"+str(Height)+".h5")
print file_name
if ists(file_name):          #判断之前是否有存到⽂件中
f = h5py.File(file_name,'r')
if t=='train':
X_train = f['X_train'][:]
y_train = f['y_train'][:]
f.close()
return (X_train, y_train)
elif t=='test':
X_test = f['X_test'][:]
y_test = f['y_test'][:]
f.close()
return (X_test, y_test)
数字化
else:
return
data_format = alize_data_format(data_format)
pic_dir_set = eachFile(pic_dir_data)
X_train = []
y_train = []
X_test = []
y_test = []
label = 0
for pic_dir in pic_dir_set:
print pic_dir_data+pic_dir
if not os.path.isdir(os.path.join(pic_dir_data,pic_dir)):
continue
pic_set = eachFile(os.path.join(pic_dir_data,pic_dir))
pic_index = 0
train_count = int(len(pic_set)*train_all)
train_l = int(len(pic_set)*train_left)
train_r = int(len(pic_set)*train_right)
for pic_name in pic_set:
if not os.path.isfile(os.path.join(pic_dir_data,pic_dir,pic_name)):
continue
img = cv2.imread(os.path.join(pic_dir_data,pic_dir,pic_name))
if img is None:
continue
if (resize):
img = size(img,(Width,Height))
img = shape(-1,Width,Height,3)
if (pic_index < train_count):
if t=='train':
if (pic_index >= train_l and pic_index < train_r):
X_train.append(img)
y_train.append(label)
else:
if t=='test':
X_test.append(img)
y_test.append(label)
pic_index += 1
指路器

本文发布于:2024-09-22 01:45:32,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/452392.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图像   训练   数据   测试   模式   模型
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议