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

本文介绍了如何利用Keras的预训练模型ResNet50进行图像分类,特别是针对Caltech101数据集。讨论了Keras中include_top参数的作用,以及学习阶段标志K.learning_phase()的正确使用。还列出了所使用的软件环境,并提供了从文件夹加载图像数据的方法,以及训练和测试过程的概要。最后,展示了获取测试集top-5准确率的代码片段和运行结果。
摘要由CSDN通过智能技术生成

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]
            resnet
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值