机器学习路径

我接触机器学习的入门书籍是:《机器学习实践指南:案例应用解析》,在这本书上学了python和R的基本语法,还有少量机器学习基础知识。然后是在学校图书馆借了几本AI相关书籍,这些书的最后一章是介绍决策树的,都比较老,具体是哪些书已经找不到了,看完就搁置了一段时间。

再次看机器学习是从Andrew Ng的视频开始,顺便看了台大林轩田机器学习基石的视频,看得云里雾里,顺便翻了一下李航的统计学习方法,无法确定看懂了多少,然后又搁置了很久。

再次看机器学习相关是第一次偶然看到CNN的时候,顺便了解了相关知识,比如CNN原理,用Keras框架CNN进行图像分类,看了很多遍Keras文档,使用预训练模型等。发现R-CNN、Fast R-CNN、Faster R-CNN系列,做了一个Faster R-CNN Caffe版本的PyQt5可视化界面,可以训练、测试、查看每张图像的标注和识别结果,然后又搁置了一段时间。

再次看机器学习相关是参加Kaggle竞赛,第一个参加的竞赛可以不用机器学习,可以转化为最小费用最大流,是在论坛里面学到的,学到之前是采用暴力搜索加优化做的。接下来做了很久的Kaggle竞赛,比如第一个图像分类的竞赛,当时写了一个融合常见预训练模型的框架,可惜那时候除了全连接层的参数都冻结了,试了各种预处理方法,统统效果很差。在接下来的图像分类竞赛,学到了Random Crop,多进程预处理,类别平衡,Test Time Augmentation等方法,离顶尖队伍还有很大的距离,想要提高技巧得查看很多图像竞赛的前几名的解题思路,例如模型的修改和损失函数自定义可能也会有用。然后是一个比较少见的文字分类的竞赛,学习方法就是Kernels里面他人的代码和Discussion里他人提到的思路,需要研究一些预处理的方法,还有word2vec,预训练词向量模型和训练词向量的方法,SpatialDropout1D、BiLSTM、BiGRU,N-Fold平均。

这里有个问题是我比较好奇的,就是假设我自己得到一个还可以的结果,但是公开的Kernels里也有一些还不错的结果,他采用的方法和我不同,分数差不多,这种情况只要和他平均,就可以得到更高的分数,而且过拟合的概率也很小。从规则上来说,这是允许的,私下分享但不组队才是违反规则。假设某人A凭借融合公开的结果,得到某个分数,某人只靠自己得到和A相同的分数,另外一个团队分工合作使用各个方法得到和A相同的分数,这三种情况的数量不同会导致成绩的含金量不同,不过一般公开的结果最终都不会进前10%,据我猜测使用公开Kernel的情况是比较普遍的,不过事实是怎样呢?

在一个竞赛里体验了一下Mask R-CNN,顺便体验了一下2阶段比赛的风险,1阶段小测试集,结束时要上传代码,然后发放大测试集,1星期后2阶段结束。假设在1阶段时经验不足,一味提高分数,没有考虑测试集变化的一些情况(图像尺寸、识别目标大小、图像颜色分布等等),就有可能跌落几百名。

在一个竞赛里发现了LightGBM和它的前身,曾经我以为很弱的决策树竟然可以这么强。文档里参数好多,数据集好大,作为新手依然在公开Kernels里学会了不少东西。可惜有人在最后12小时发布了一个分数和我差不多的Kernel,然后有人用它和一些公开Kernels融合了一下发布了,分数就比我高了一些,导致排名下降了300名,嘿嘿这次我就没有融合公开Kernel,所以说邪恶无法阻止,除非能碾压邪恶。

到这里基本上常见比赛都见过了,后面看到的比赛很多都可以直接用以前的代码来跑了,不过还是有一些新型的比赛出没。比如一个可以用DBSCAN的比赛,预测粒子轨迹,我一开始看到这个比赛的时候第一反应就是不做这个比赛,可惜有一些多余的时间,我就看了它好几次,作为学习聚类的一个途径了解一下,这题的最优解不是聚类。大概就是瞎构造一些已有变量的组合,用贝叶斯优化找线性组合的参数,有时手工调整一下参数看看效果,多看Discussion找方法,时间不多,自己没想出什么思路。还有比如说目标检测的竞赛,刚好是个大数据集,谷歌还提供了一笔赠金跑谷歌云,体验了一下多卡训练的感觉。

我总觉得我在面临重要选择的时候,都会做出错误的决定,就比如说我两个月多前面临做一些准备去找工作的问题,当时有一些备选:1.打比赛得好成绩去找,2.刷leetcode中等难度的题,3.用以前学过的知识做一个靠谱小应用,4.复习和学习机器学习基本知识。只能说我水平确实有限,基础知识不牢,没有办法取得前十的成绩,表面Kaggle银牌已经没啥用了,硬实力才是关键,似乎现在大家要求都挺高。我花了10天去试了一下天池的比赛,感觉有一批人很强,不过实际认真参与的大概是300人,说明很多人不需要参加竞赛,直接就可以去实际应用,想靠竞赛找到工作得进天池决赛。很多公司喜欢考算法题,听说leetcode刷完中等难度就行,可惜我没有选择全刷leetcode,这应该就是一个错误,leetcode我只试了前50题中等难度的,不参考资料会45题,间隔的做花了10天,不过不是一整天都在刷,比较难的一些知识我现在肯定不会,如果多刷一些可能才能看到更多的不足,补完应该会强一些。想做一个完整的小应用至少得花1个月,风险不小,做了不够好人家肯定看不上。机器学习基础知识感觉挺难,想在短时间内灌输进去也不知道有没有用,不过这些基础知识学起来挺快的,暂时不清楚学会了有多大用,可惜了少了论文的积累,估计只能做一些边角的工作。

python中使用opencv进行CLAHE处理

 限制对比度自适应直方图均衡(CLAHE算法)进行预处理有时可以增加识别的准确率。使用方法如下:

import cv2
path = '1.jpg'
image = cv2.imread(path,cv2.IMREAD_COLOR)
cv2.imwrite('image.jpg',image,[cv2.IMWRITE_JPEG_QUALITY, 50])
b,g,r = cv2.split(image)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
b = clahe.apply(b)
g = clahe.apply(g)
r = clahe.apply(r)
image = cv2.merge([b,g,r])
cv2.imwrite('clahe.jpg',image,[cv2.IMWRITE_JPEG_QUALITY, 50])

输出结果:

image.jpg

clahe.jpg


使用jpeg4py读取jpg图像

不同的读取方法速度不同,对jpg图像来说,jpeg4py是较快的读取方法。使用方法如下:

import jpeg4py as jpeg
from PIL import Image
import numpy as np
import glob
load_img_fast_jpg  = lambda img_path: jpeg.JPEG(img_path).decode()
load_img  = lambda img_path: np.array(Image.open(img_path))

path_list = glob.glob('train/*.jpg')
for path in path_list:
    try:
        img = load_img_fast_jpg(path)
    except:
        img = load_img(path)
    print (img.shape)

python中使用glob模块获得图像路径

python中glob模块可以获得图像路径,目录中的文件名分别为:1.jpg,2.jpg,3.jpg,4.png,5.png。

使用方法为:

import glob
image_path_list = glob.glob(r"train/*")
image_path_list.sort()
print (image_path_list)
jpg_path_list = glob.glob(r"train/*.jpg")
jpg_path_list.sort()
print (jpg_path_list)

输出:

['train/1.jpg', 'train/2.jpg', 'train/3.jpg', 'train/4.png', 'train/5.png']
['train/1.jpg', 'train/2.jpg', 'train/3.jpg']

对于使用mask-rcnn的数据集,目录下为多个以图像名称为名的文件夹,每个文件夹中有image和masks文件夹,其中image文件夹中有一张图像,表示原图,masks文件夹中有多个与原图大小相同的图像,表示图像中的各个目标。

读取方法为:

import glob
import os
image_list = glob.glob(r"dataset/*")
image_list.sort()
print (image_list)
for image_path in image_list:
    image = glob.glob(os.path.join(image_path,'image','*'))[0]
    print (image)
    mask_list = glob.glob(os.path.join(image_path,'masks','*'))
    print (mask_list)

输出结果为:

['dataset/1', 'dataset/2']
dataset/1/image/1.jpg
['dataset/1/masks/1_1.jpg', 'dataset/1/masks/1_2.jpg', 'dataset/1/masks/1_0.jpg']
dataset/2/image/2.jpg
['dataset/2/masks/2_0.jpg', 'dataset/2/masks/2_1.jpg']

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

转自https://blog.csdn.net/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是训练模式,部分网络结构下两者有差别。

这里使用ResNet50预训练模型,对Caltech101数据集进行图像分类。只有CPU,运行较慢,但是在训练集固定的情况下,较慢的过程只需要运行一次。该预训练模型的中文文档介绍在http://keras-cn.readthedocs.io/en/latest/other/application/#resnet50

我使用的版本:

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 os.path.exists(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 = conv_utils.normalize_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 = cv2.resize(img,(Width,Height))     
                img = img.reshape(-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.create_dataset('X_train', data = X_train)  
        f.create_dataset('y_train', data = 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.create_dataset('X_test', data = X_test)  
        f.create_dataset('y_test', data = 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 = np_utils.to_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 os.path.exists(file_name):  
    f = h5py.File(file_name,'r')  
    resnet50_train_output = f['resnet50_train_output'][:]  
    f.close()  
else:  
    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.create_dataset('resnet50_train_output', data = resnet50_train_output)  
    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)  
model.compile(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 = np_utils.to_categorical(y_test, num_classes)  
      
file_name = os.path.join(pic_dir_mine,'resnet50_test_output'+'.h5')  
if os.path.exists(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.create_dataset('resnet50_test_output', data = resnet50_test_output)  
    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  
from keras.models import Model  
from keras.layers import Flatten, Dense, Input   
from keras.optimizers import Adam  
from keras.applications.resnet50 import ResNet50  
from keras import backend as K  
  
def get_name_list(filepath):                #获取各个类别的名字  
    pathDir =  os.listdir(filepath)  
    out = []  
    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 os.path.exists(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 = conv_utils.normalize_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 = cv2.resize(img,(Width,Height))     
                img = img.reshape(-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.create_dataset('X_train', data = X_train)  
        f.create_dataset('y_train', data = 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.create_dataset('X_test', data = X_test)  
        f.create_dataset('y_test', data = y_test)  
        f.close()  
        return (X_test, y_test)     
    else:  
        return  
  
def main():  
    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 = np_utils.to_categorical(y_train, num_classes)  
  
    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 os.path.exists(file_name):  
        f = h5py.File(file_name,'r')  
        resnet50_train_output = f['resnet50_train_output'][:]  
        f.close()  
    else:  
        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.create_dataset('resnet50_train_output', data = resnet50_train_output)  
        f.close()  
  
    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)  
    model.compile(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 = np_utils.to_categorical(y_test, num_classes)  
          
    file_name = os.path.join(pic_dir_mine,'resnet50_test_output'+'.h5')  
    if os.path.exists(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.create_dataset('resnet50_test_output', data = resnet50_test_output)  
        f.close()  
    print('\nTesting ------------')     #对测试集进行评估  
    class_name_list = get_name_list(pic_dir_data)    #获取top-N的每类的准确率  
    pred = model.predict(resnet50_test_output, batch_size=32)  
    f = h5py.File(os.path.join(pic_dir_mine,'pred_'+cm2_str+'.h5'),'w')            
    f.create_dataset('pred', data = pred)  
    f.close()  
      
    N = 1  
    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]))  
      
    print('----------------------------------------------------')  
    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]))  
        
if __name__ == '__main__':  
    main()

运行结果:

Using TensorFlow backend.
/home/ccuux3/pic_cnn/pic_out/Caltech101_color_data_train_0.0_0.7_224X224.h5

Training ------------
Epoch 1/10
6353/6353 [==============================] - 5s - loss: 1.1269 - acc: 0.7494      
Epoch 2/10
6353/6353 [==============================] - 4s - loss: 0.1603 - acc: 0.9536     
Epoch 3/10
6353/6353 [==============================] - 4s - loss: 0.0580 - acc: 0.9855     
Epoch 4/10
6353/6353 [==============================] - 4s - loss: 0.0312 - acc: 0.9931     
Epoch 5/10
6353/6353 [==============================] - 4s - loss: 0.0182 - acc: 0.9956     
Epoch 6/10
6353/6353 [==============================] - 4s - loss: 0.0111 - acc: 0.9976     
Epoch 7/10
6353/6353 [==============================] - 4s - loss: 0.0090 - acc: 0.9981     
Epoch 8/10
6353/6353 [==============================] - 4s - loss: 0.0082 - acc: 0.9987     
Epoch 9/10
6353/6353 [==============================] - 4s - loss: 0.0069 - acc: 0.9994     
Epoch 10/10
6353/6353 [==============================] - 4s - loss: 0.0087 - acc: 0.9987     
/home/ccuux3/pic_cnn/pic_out/Caltech101_color_data_test_0.0_0.7_224X224.h5

Testing ------------
('top-1 all acc:', '2597/2792', 0.9301575931232091)
(0, u'62.mayfly', 'acc: 10/12')
(1, u'66.Motorbikes', 'acc: 240/240')
(2, u'68.octopus', 'acc: 7/11')
(3, u'94.umbrella', 'acc: 21/23')
(4, u'90.strawberry', 'acc: 10/11')
(5, u'86.stapler', 'acc: 13/14')
(6, u'83.sea_horse', 'acc: 15/18')
(7, u'72.pigeon', 'acc: 13/14')
(8, u'89.stop_sign', 'acc: 19/20')
(9, u'4.BACKGROUND_Google', 'acc: 125/141')
(10, u'22.cougar_face', 'acc: 18/21')
(11, u'81.scissors', 'acc: 9/12')
(12, u'100.wrench', 'acc: 8/12')
(13, u'57.Leopards', 'acc: 60/60')
(14, u'46.hawksbill', 'acc: 29/30')
(15, u'30.dolphin', 'acc: 19/20')
(16, u'9.bonsai', 'acc: 39/39')
(17, u'35.euphonium', 'acc: 18/20')
(18, u'44.gramophone', 'acc: 16/16')
(19, u'74.platypus', 'acc: 7/11')
(20, u'14.camera', 'acc: 15/15')
(21, u'55.lamp', 'acc: 15/19')
(22, u'38.Faces_easy', 'acc: 129/131')
(23, u'54.ketch', 'acc: 28/35')
(24, u'33.elephant', 'acc: 18/20')
(25, u'3.ant', 'acc: 8/13')
(26, u'49.helicopter', 'acc: 26/27')
(27, u'36.ewer', 'acc: 26/26')
(28, u'78.rooster', 'acc: 14/15')
(29, u'70.pagoda', 'acc: 15/15')
(30, u'58.llama', 'acc: 20/24')
(31, u'5.barrel', 'acc: 15/15')
(32, u'101.yin_yang', 'acc: 18/18')
(33, u'18.cellphone', 'acc: 18/18')
(34, u'59.lobster', 'acc: 7/13')
(35, u'17.ceiling_fan', 'acc: 14/15')
(36, u'16.car_side', 'acc: 37/37')
(37, u'50.ibis', 'acc: 24/24')
(38, u'76.revolver', 'acc: 23/25')
(39, u'84.snoopy', 'acc: 7/11')
(40, u'87.starfish', 'acc: 26/26')
(41, u'12.buddha', 'acc: 24/26')
(42, u'52.joshua_tree', 'acc: 20/20')
(43, u'43.gerenuk', 'acc: 10/11')
(44, u'65.minaret', 'acc: 23/23')
(45, u'91.sunflower', 'acc: 26/26')
(46, u'56.laptop', 'acc: 24/25')
(47, u'77.rhino', 'acc: 17/18')
(48, u'1.airplanes', 'acc: 239/240')
(49, u'88.stegosaurus', 'acc: 16/18')
(50, u'23.crab', 'acc: 17/22')
(51, u'8.binocular', 'acc: 8/10')
(52, u'31.dragonfly', 'acc: 18/21')
(53, u'6.bass', 'acc: 15/17')
(54, u'95.watch', 'acc: 72/72')
(55, u'0.accordion', 'acc: 17/17')
(56, u'98.wild_cat', 'acc: 9/11')
(57, u'67.nautilus', 'acc: 16/17')
(58, u'40.flamingo', 'acc: 20/21')
(59, u'92.tick', 'acc: 12/15')
(60, u'47.headphone', 'acc: 12/13')
(61, u'24.crayfish', 'acc: 15/21')
(62, u'97.wheelchair', 'acc: 17/18')
(63, u'27.cup', 'acc: 15/18')
(64, u'25.crocodile', 'acc: 14/15')
(65, u'2.anchor', 'acc: 7/13')
(66, u'19.chair', 'acc: 17/19')
(67, u'39.ferry', 'acc: 21/21')
(68, u'60.lotus', 'acc: 16/20')
(69, u'13.butterfly', 'acc: 26/28')
(70, u'34.emu', 'acc: 14/16')
(71, u'64.metronome', 'acc: 10/10')
(72, u'82.scorpion', 'acc: 24/26')
(73, u'7.beaver', 'acc: 12/14')
(74, u'48.hedgehog', 'acc: 16/17')
(75, u'37.Faces', 'acc: 131/131')
(76, u'45.grand_piano', 'acc: 30/30')
(77, u'79.saxophone', 'acc: 11/12')
(78, u'26.crocodile_head', 'acc: 9/16')
(79, u'80.schooner', 'acc: 15/19')
(80, u'93.trilobite', 'acc: 26/26')
(81, u'28.dalmatian', 'acc: 21/21')
(82, u'10.brain', 'acc: 28/30')
(83, u'61.mandolin', 'acc: 10/13')
(84, u'11.brontosaurus', 'acc: 11/13')
(85, u'63.menorah', 'acc: 25/27')
(86, u'85.soccer_ball', 'acc: 20/20')
(87, u'51.inline_skate', 'acc: 9/10')
(88, u'71.panda', 'acc: 11/12')
(89, u'53.kangaroo', 'acc: 24/26')
(90, u'99.windsor_chair', 'acc: 16/17')
(91, u'42.garfield', 'acc: 11/11')
(92, u'29.dollar_bill', 'acc: 16/16')
(93, u'20.chandelier', 'acc: 30/33')
(94, u'96.water_lilly', 'acc: 6/12')
(95, u'41.flamingo_head', 'acc: 13/14')
(96, u'73.pizza', 'acc: 13/16')
(97, u'21.cougar_body', 'acc: 15/15')
(98, u'75.pyramid', 'acc: 16/18')
(99, u'69.okapi', 'acc: 12/12')
(100, u'15.cannon', 'acc: 11/13')
(101, u'32.electric_guitar', 'acc: 19/23')
----------------------------------------------------
('top-5 all acc:', '2759/2792', 0.9881805157593123)
(0, u'62.mayfly', 'acc: 12/12')
(1, u'66.Motorbikes', 'acc: 240/240')
(2, u'68.octopus', 'acc: 11/11')
(3, u'94.umbrella', 'acc: 23/23')
(4, u'90.strawberry', 'acc: 11/11')
(5, u'86.stapler', 'acc: 14/14')
(6, u'83.sea_horse', 'acc: 16/18')
(7, u'72.pigeon', 'acc: 14/14')
(8, u'89.stop_sign', 'acc: 20/20')
(9, u'4.BACKGROUND_Google', 'acc: 141/141')
(10, u'22.cougar_face', 'acc: 19/21')
(11, u'81.scissors', 'acc: 11/12')
(12, u'100.wrench', 'acc: 10/12')
(13, u'57.Leopards', 'acc: 60/60')
(14, u'46.hawksbill', 'acc: 30/30')
(15, u'30.dolphin', 'acc: 20/20')
(16, u'9.bonsai', 'acc: 39/39')
(17, u'35.euphonium', 'acc: 20/20')
(18, u'44.gramophone', 'acc: 16/16')
(19, u'74.platypus', 'acc: 9/11')
(20, u'14.camera', 'acc: 15/15')
(21, u'55.lamp', 'acc: 18/19')
(22, u'38.Faces_easy', 'acc: 131/131')
(23, u'54.ketch', 'acc: 34/35')
(24, u'33.elephant', 'acc: 20/20')
(25, u'3.ant', 'acc: 10/13')
(26, u'49.helicopter', 'acc: 27/27')
(27, u'36.ewer', 'acc: 26/26')
(28, u'78.rooster', 'acc: 15/15')
(29, u'70.pagoda', 'acc: 15/15')
(30, u'58.llama', 'acc: 24/24')
(31, u'5.barrel', 'acc: 15/15')
(32, u'101.yin_yang', 'acc: 18/18')
(33, u'18.cellphone', 'acc: 18/18')
(34, u'59.lobster', 'acc: 13/13')
(35, u'17.ceiling_fan', 'acc: 14/15')
(36, u'16.car_side', 'acc: 37/37')
(37, u'50.ibis', 'acc: 24/24')
(38, u'76.revolver', 'acc: 25/25')
(39, u'84.snoopy', 'acc: 10/11')
(40, u'87.starfish', 'acc: 26/26')
(41, u'12.buddha', 'acc: 25/26')
(42, u'52.joshua_tree', 'acc: 20/20')
(43, u'43.gerenuk', 'acc: 11/11')
(44, u'65.minaret', 'acc: 23/23')
(45, u'91.sunflower', 'acc: 26/26')
(46, u'56.laptop', 'acc: 25/25')
(47, u'77.rhino', 'acc: 18/18')
(48, u'1.airplanes', 'acc: 240/240')
(49, u'88.stegosaurus', 'acc: 18/18')
(50, u'23.crab', 'acc: 22/22')
(51, u'8.binocular', 'acc: 10/10')
(52, u'31.dragonfly', 'acc: 20/21')
(53, u'6.bass', 'acc: 16/17')
(54, u'95.watch', 'acc: 72/72')
(55, u'0.accordion', 'acc: 17/17')
(56, u'98.wild_cat', 'acc: 11/11')
(57, u'67.nautilus', 'acc: 17/17')
(58, u'40.flamingo', 'acc: 21/21')
(59, u'92.tick', 'acc: 13/15')
(60, u'47.headphone', 'acc: 12/13')
(61, u'24.crayfish', 'acc: 21/21')
(62, u'97.wheelchair', 'acc: 18/18')
(63, u'27.cup', 'acc: 16/18')
(64, u'25.crocodile', 'acc: 15/15')
(65, u'2.anchor', 'acc: 12/13')
(66, u'19.chair', 'acc: 19/19')
(67, u'39.ferry', 'acc: 21/21')
(68, u'60.lotus', 'acc: 19/20')
(69, u'13.butterfly', 'acc: 27/28')
(70, u'34.emu', 'acc: 16/16')
(71, u'64.metronome', 'acc: 10/10')
(72, u'82.scorpion', 'acc: 26/26')
(73, u'7.beaver', 'acc: 14/14')
(74, u'48.hedgehog', 'acc: 17/17')
(75, u'37.Faces', 'acc: 131/131')
(76, u'45.grand_piano', 'acc: 30/30')
(77, u'79.saxophone', 'acc: 12/12')
(78, u'26.crocodile_head', 'acc: 14/16')
(79, u'80.schooner', 'acc: 19/19')
(80, u'93.trilobite', 'acc: 26/26')
(81, u'28.dalmatian', 'acc: 21/21')
(82, u'10.brain', 'acc: 30/30')
(83, u'61.mandolin', 'acc: 13/13')
(84, u'11.brontosaurus', 'acc: 13/13')
(85, u'63.menorah', 'acc: 25/27')
(86, u'85.soccer_ball', 'acc: 20/20')
(87, u'51.inline_skate', 'acc: 10/10')
(88, u'71.panda', 'acc: 12/12')
(89, u'53.kangaroo', 'acc: 26/26')
(90, u'99.windsor_chair', 'acc: 17/17')
(91, u'42.garfield', 'acc: 11/11')
(92, u'29.dollar_bill', 'acc: 16/16')
(93, u'20.chandelier', 'acc: 32/33')
(94, u'96.water_lilly', 'acc: 12/12')
(95, u'41.flamingo_head', 'acc: 14/14')
(96, u'73.pizza', 'acc: 16/16')
(97, u'21.cougar_body', 'acc: 15/15')
(98, u'75.pyramid', 'acc: 18/18')
(99, u'69.okapi', 'acc: 12/12')
(100, u'15.cannon', 'acc: 12/13')
(101, u'32.electric_guitar', 'acc: 23/23')