深度学习|深度学习keras 多分类下的迁移学习

需要自己建路径,先大致看看路径,建好。
数据集在这:https://download.csdn.net/download/zqx951102/12675542

#深度学习009-用Keras迁移学习提升性能(多分类问题)来自:https://www.jianshu.com/p/d0723a267771 #使用迁移学习包括两个步骤:第一步是用VGG16网络提取bottleneck features,然后保存这些特征,第二步建立自己的分类器,然后用用保存的特征来训练分类器,优化weights。下面是第一步的代码,只注意一个地方:要修改为:class_mode='categorical' #第二步: 定义自己的分类器,专门适用于本项目的多分类问题,要将最后的Dense层修改为:model.add(Dense(class_num, activation='softmax')),并且loss使用'categorical_crossentropy'。 #然后使用保存的特征对该分类器进行训练,训练时有一个地方要注意:在二分类问题时,我们直接将labels定义为np.array([0]80+[1]80),但是多分类问题,需要用to_categorical进行转换,然后再放入到fit中。 #1,多分类的迁移学习问题需要注意几个地方:提取bottleneck features时要设置class_mode='categorical'。构建自己的分类器时要把输出层的Dense修改,然后把激活函数和损失函数修改为多分类对应的函数。在做labels时,要先用to_categorical转变为one-hot形式再输入到模型中进行fit.import numpy as np import os,random,shutil np.random.seed(7)# 为Keras模型准备数据集 #1,指定一些超参数:train_data_dir='D:/re/re/train' val_data_dir='D:/re/re/test' train_samples_num=400 # train set中全部照片数 val_samples_num=100 IMG_W,IMG_H,IMG_CH=384,256,3# 单张图片的大小 batch_size=50 # 这儿要保证400和100能除断 epochs=150# 用比较少的epochs数目做演示,节约训练时间 class_num=5 # 此处有5个类别save_folder='D:/多分类' # bottleneck特征保存位置# 此处的训练集和测试集并不是原始图片的train set和test set,而是用VGG16对图片提取的特征,这些特征组成新的train set和test set from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential from keras.layers import Dropout, Flatten, Dense from keras import applications def save_bottlebeck_features(): datagen = ImageDataGenerator(rescale=1. / 255) # 不需图片增强# build the VGG16 network model = applications.VGG16(include_top=False, weights='imagenet') # 使用imagenet的weights作为VGG16的初始weights,由于只是特征提取,故而只取前面的卷积层而不需要DenseLayer,故而include_top=Falsegenerator = datagen.flow_from_directory( # 产生train set train_data_dir, target_size=(IMG_W, IMG_H), batch_size=batch_size, class_mode='categorical', # 这个地方要修改,要不然出错 shuffle=False) # 必须为False,否则顺序打乱之后,和后面的label对应不上。 bottleneck_features_train = model.predict_generator( generator, train_samples_num // batch_size) np.save(os.path.join(save_folder,'bottleneck_features_train.npy'), bottleneck_features_train) print('bottleneck features of train set is saved.')generator = datagen.flow_from_directory( val_data_dir, target_size=(IMG_W, IMG_H), batch_size=batch_size, class_mode='categorical', shuffle=False) bottleneck_features_validation = model.predict_generator( generator, val_samples_num // batch_size) np.save(os.path.join(save_folder,'bottleneck_features_val.npy'),bottleneck_features_validation) print('bottleneck features of test set is saved.') save_bottlebeck_features()def my_model(): ''' 自定义一个模型,该模型仅仅相当于一个分类器,只包含有全连接层,对提取的特征进行分类即可 :return: ''' # 模型的结构 model = Sequential() model.add(Flatten(input_shape=train_data.shape[1:])) # 将所有data进行flatten model.add(Dense(256, activation='relu')) # 256个全连接单元 model.add(Dropout(0.5)) # dropout正则 model.add(Dense(class_num, activation='softmax')) # 与二分类不同之处:要用Dense(class_num)和softmax# 模型的配置 model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) # model的optimizer等return modelfrom keras.utils import to_categorical # 只需要训练分类器模型即可,不需要训练特征提取器 train_data = https://www.it610.com/article/np.load(os.path.join(save_folder,'bottleneck_features_train.npy')) # 加载训练图片集的所有图片的VGG16-notop特征 train_labels = np.array([0] * int((train_samples_num /class_num )) + [1] * int((train_samples_num /class_num ))+ [2]*int((train_samples_num /class_num ))+[3]*int((train_samples_num /class_num ))+[4]*int((train_samples_num /class_num ))) ##train_labels = np.array([0] * 80 + [1] * 80+ [2]*80+[3]*80+[4]*80)博客用的这个代码 我觉得这个还是用上面比较好80也不是固定数400/5下面那个20也是 100/55是类别数这个改了方便以后改数据集 # label是每个类别80张图片,共5个类别 # 设置标签,并规范成Keras默认格式 train_labels = to_categorical(train_labels, class_num)validation_data = https://www.it610.com/article/np.load(os.path.join(save_folder,'bottleneck_features_val.npy')) validation_labels = np.array([0] * int((val_samples_num/class_num ))+ [1] * int((val_samples_num/class_num ))+ [2]*int((val_samples_num/class_num ))+[3]*int((val_samples_num/class_num ))+[4]*int((val_samples_num/class_num ))) validation_labels = to_categorical(validation_labels, class_num)# 构建分类器模型 clf_model=my_model() history_ft = clf_model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size, validation_data=https://www.it610.com/article/(validation_data, validation_labels))# 画图,将训练时的acc和loss都绘制到图上 import matplotlib.pyplot as pltdef plot_training(history): plt.figure(12)plt.subplot(121) train_acc = history.history['acc'] val_acc = history.history['val_acc'] epochs = range(len(train_acc)) plt.plot(epochs, train_acc, 'b', label='train_acc') plt.plot(epochs, val_acc, 'r', label='test_acc') plt.title('Train and Test accuracy') plt.legend()plt.subplot(122) train_loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(train_loss)) plt.plot(epochs, train_loss, 'b', label='train_loss') plt.plot(epochs, val_loss, 'r', label='test_loss') plt.title('Train and Test loss') plt.legend()plt.show()plot_training(history_ft) clf_model.save_weights(os.path.join(save_folder,'top_FC_model'))#loss: 0.0646 - acc: 0.9875 - val_loss: 0.1708 - val_acc: 0.960050代结果 #loss: 0.0085 - acc: 0.9975 - val_loss: 0.5320 - val_acc: 0.9500150代结果

深度学习|深度学习keras 多分类下的迁移学习
文章图片

50代的结果
深度学习|深度学习keras 多分类下的迁移学习
文章图片

【深度学习|深度学习keras 多分类下的迁移学习】150代结果

    推荐阅读