当前位置:   article > 正文

深度学习3 使用keras进行迁移学习(重新修订)_train_data.npy

train_data.npy

修改说明:为了能使迁移学习所训练出的模型能适应后续的知识蒸馏,因此对迁移的代码做了细节上的修订。后续红色标明字样,皆为修改后的内容

采用模型分离的方式构造迁移学习,可以降低反向传播时卷积运算的工作量。

1、卷积基的提取

首先选定迁移的目标并提取其卷积基  可按照不同的需求提取迁移特征。keras除此外还有  DenseNet121、MobileNet、Xception等网络可以用于迁移

注意:1、要按照个人需求和电脑配置调整 shape,batch_size, 和models数组内的模型名称

           2、要从tensorflow.kreas中引入application库,这样子才能支持更多的模型库(如EfficientNet系列)

            3、新增os环境设置,避免价值tensorflow时输出太多不必要的信息

  1. import os
  2. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # or any {'0', '1', '2'}
  3. from keras.preprocessing.image import ImageDataGenerator
  4. from keras.utils import np_utils
  5. #from tensorflow.python.keras.utils import np_utils #上面语句报错可以改成这个
  6. from tensorflow.keras import applications,Model
  7. import numpy as np
  8. import os,gc
  9. batch_size=32#ResNet50,VGG16,InceptionV3 EfficientNetB7 NASNetLarge
  10. shape=(226, 226)
  11. # DenseNet169 DenseNet201 #DenseNet121 ResNet152V2 ,"InceptionV3","MobileNetV3Small","ResNet50V2","VGG19"
  12. models=["EfficientNetB0"]#
  13. for modelname in models:
  14. mstr="applications.%s(include_top=False,input_shape=(114,114,3), weights='imagenet')"%modelname
  15. base = eval(mstr)
  16. print(modelname)
  17. print(modelname)
  18. model= Model(input=base.input, output=base.layers[-1].output)
可用于迁移的对象

2、数据集的划分

数据集的划分可以查看python工具方法 4 依据随机种子将图片文件划分为训练集、测试集、验证集_a486259的博客-CSDN博客,代码复制后即可运行

文件夹:flower   通过该代码可得到:flower-训练,flower-验证,flower-测试三个文件夹

3、特征的提取与保存

所提取的特征保存在features文件夹中,命名方式为:
modelname_data_训练、modelname_data_验证、modelname_data_测试

modelname_labels_训练、modelname_labels_验证、modelname_labels_测试

  1. #代码复制过来不想调整缩进,所以使用了if True来控制
  2. if True:
  3. datagen = ImageDataGenerator()#(rescale=1.0 / 255)
  4. root_path='./features/'
  5. if not os.path.exists(root_path):
  6. os.makedirs(root_path)
  7. dirList=['训练','验证','测试']
  8. data_path='flower//'
  9. for path in dirList:
  10. generator = datagen.flow_from_directory(data_path+'-'+path,
  11. target_size=shape,
  12. batch_size=batch_size,
  13. class_mode='categorical',
  14. shuffle=False)
  15. print(generator.class_indices)#输出数据的labels
  16. labels= np_utils.to_categorical(generator.classes)
  17. np.save(open(root_path+'label.npy', 'wb'), generator.class_indices)
  18. features= model.predict_generator(generator, len(generator.classes)/generator.batch_size)
  19. print('result.shape: ',features.shape)
  20. #import sys;sys.exit()
  21. print(len(generator.classes))
  22. print(path,'集-卷积池化数据固化成功!')
  23. np.save(open('%s%s_data_%s.npy'%(root_path,modelname,path), 'wb'), features)
  24. np.save(open('%s%s_labels_%s.npy'%(root_path,modelname,path), 'wb'), labels)
  25. np.save(open('%s%s_fileName_%s.npy'%(root_path,modelname,path), 'wb'), generator.filenames)
  26. gc.collect()

4、读取特征

  1. import numpy as np
  2. root_path='./features/VGG16_'
  3. train_data = np.load(root_path+'data_训练.npy')
  4. train_data=train_data.reshape(train_data.shape[0],-1)
  5. train_label = np.load(root_path+'labels_训练.npy')
  6. shuffle=True
  7. if shuffle:
  8. import random
  9. randnum = random.randint(0,100)
  10. random.seed(randnum)
  11. random.shuffle(train_data)
  12. random.seed(randnum)
  13. random.shuffle(train_label)
  14. validation_data = np.load(root_path+'data_验证.npy')
  15. validation_data=validation_data.reshape(validation_data.shape[0],-1)
  16. validation_label =np.load(root_path+'labels_验证.npy')
  17. test_data = np.load(root_path+'data_测试.npy')
  18. test_data=test_data.reshape(test_data.shape[0],-1)
  19. test_label =np.load(root_path+'labels_测试.npy')
  20. #数据的扁平化
  21. inputShape=np.array(train_data.shape[1:]).prod()
  22. train_data=train_data.reshape(-1,inputShape)
  23. test_data=test_data.reshape(-1,inputShape)
  24. validation_data=validation_data.reshape(-1,inputShape)

5、重新训练分类器

在这里修改了两行代码,移除了最后一个Dense中的激活函数,并为每一个dense设置了name,通过这种操作,可以已另一种方式实现模型拼接。需要进行更高级的知识蒸馏(实现kl loss,softmax升温)的朋友,请不要使用后续的模型拼接代码。

output = Dense(class_types,name='dense_out')(x)
output = Activation(tf.nn.softmax,name='Activation_out')(output)

  1. import tensorflow as tf
  2. from keras.models import Model
  3. from keras.layers import Dense,Input,Dropout,Activation
  4. inputs = Input(shape=(inputShape,))
  5. x = Dense(100, activation='relu',name='dense1')(inputs)
  6. x = Dense(50, activation='relu',name='dense2')(x)
  7. x = Dropout(0.2)(x)
  8. output = Dense(class_types,name='dense_out')(x)
  9. output = Activation(tf.nn.softmax,name='Activation_out')(output)
  10. model = Model(inputs=inputs, outputs=output)
  11. model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])
  12. from keras.callbacks import History,ModelCheckpoint,EarlyStopping
  13. #最佳模型保存
  14. ModelCheckpoint=ModelCheckpoint('best_model.h5', monitor='acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
  15. #提前终止
  16. EarlyStopping=EarlyStopping(monitor='val_loss', patience=2, verbose=2, mode='auto')
  17. #历史数据记录
  18. loss_history = History()
  19. #模型训练
  20. model.fit(train_data,train_label,epochs=100,batch_size=32,
  21. callbacks=[ModelCheckpoint,EarlyStopping,loss_history]
  22. validation_data=(validation_data, validation_label),
  23. verbose=2)
  24. #模型评估
  25. loss,acc=model.evaluate(test_data, test_label )
  26. print('loss:',loss,'acc:',acc)
  27. #历史数据绘图
  28. import pandas as pd
  29. d=pd.DataFrame(data=loss_history.history)
  30. d.to_csv('history.csv')

6、全部代码

01.feature_save.py   复制代码保存为01.feature_save.py,然后执行,完成迁移特征的提取与保存

  1. import os
  2. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # or any {'0', '1', '2'}
  3. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  4. from tensorflow.python.keras.utils.np_utils import to_categorical
  5. from tensorflow.keras import applications,Model
  6. import numpy as np
  7. import os,gc
  8. batch_size=32#ResNet50,VGG16,InceptionV3 EfficientNetB7 NASNetLarge
  9. shape=(56, 56)
  10. # DenseNet169 DenseNet201 #DenseNet121 ResNet152V2 ,"InceptionV3","MobileNetV3Small","ResNet50V2","VGG19"
  11. models=["EfficientNetB0"]#
  12. for modelname in models:
  13. mstr="applications.%s(include_top=False,input_shape=(114,114,3), weights='imagenet')"%modelname
  14. base = eval(mstr)
  15. print(modelname)
  16. print(modelname)
  17. model= Model(inputs=base.input, outputs=base.layers[-1].output)
  18. datagen = ImageDataGenerator()#(rescale=1.0 / 255)
  19. root_path='./features/'
  20. if not os.path.exists(root_path):
  21. os.makedirs(root_path)
  22. dirList=['训练','验证','测试']
  23. data_path = r"./flower"
  24. for path in dirList:
  25. generator = datagen.flow_from_directory(data_path+'-'+path,
  26. target_size=shape,
  27. batch_size=batch_size,
  28. class_mode='categorical',
  29. shuffle=False)
  30. print(generator.class_indices)#输出数据的labels
  31. labels= to_categorical(generator.classes)
  32. np.save(open(root_path+'label.npy', 'wb'), generator.class_indices)
  33. features= model.predict_generator(generator, len(generator.classes)/generator.batch_size)
  34. print('result.shape: ',features.shape)
  35. #import sys;sys.exit()
  36. print(len(generator.classes))
  37. print(path,'集-卷积池化数据固化成功!')
  38. np.save(open('%s%s_data_%s.npy'%(root_path,modelname,path), 'wb'), features)
  39. np.save(open('%s%s_labels_%s.npy'%(root_path,modelname,path), 'wb'), labels)
  40. np.save(open('%s%s_fileName_%s.npy'%(root_path,modelname,path), 'wb'), generator.filenames)
  41. gc.collect()

02.new_cls.py  复制代码保存为02.new_cls.py,然后执行,完成分类器训练

  1. #------------------------------特征数据读取---------------------------------------
  2. import numpy as np
  3. class_types=2
  4. root_path='./features/VGG16_'
  5. train_data = np.load(root_path+'data_训练.npy')
  6. train_label = np.load(root_path+'labels_训练.npy')
  7. shuffle=True
  8. if shuffle:
  9. import random
  10. randnum = random.randint(0,100)
  11. random.seed(randnum)
  12. random.shuffle(train_data)
  13. random.seed(randnum)
  14. random.shuffle(train_label)
  15. validation_data = np.load(root_path+'data_验证.npy')
  16. validation_label =np.load(root_path+'labels_验证.npy')
  17. test_data = np.load(root_path+'data_测试.npy')
  18. test_label =np.load(root_path+'labels_测试.npy')
  19. #-----------------------------------重新训练全连接分类器--------------------------
  20. from keras.models import Model
  21. from keras.layers import Dense,Input,Dropout,GlobalAveragePooling2D
  22. inputs = Input(shape=test_data[0].shape)
  23. x = GlobalAveragePooling2D()(inputs)#GlobalAveragePooling2D 为了减少对数据的形变操作,和降低模型参数量
  24. x = Dense(100, activation='relu')(x)
  25. x = Dense(50, activation='relu')(x)
  26. x = Dropout(0.2)(x)
  27. output = Dense(class_types, activation='softmax')(x)
  28. model = Model(inputs=inputs, outputs=output)
  29. model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])
  30. from keras.callbacks import History,ModelCheckpoint,EarlyStopping
  31. #最佳模型保存
  32. ModelCheckpoint=ModelCheckpoint('gap_best_model.h5', monitor='acc', verbose=0, save_best_only=True, save_weights_only=False, mode='auto', period=1)
  33. #提前终止
  34. EarlyStopping=EarlyStopping(monitor='val_loss', patience=15, verbose=2, mode='auto')
  35. #历史数据记录
  36. loss_history = History()
  37. #模型训练
  38. model.fit(train_data,train_label,epochs=100,batch_size=32,
  39. callbacks=[ModelCheckpoint,EarlyStopping,loss_history],
  40. validation_data=(validation_data, validation_label),
  41. verbose=2)
  42. #模型评估
  43. loss,acc=model.evaluate(test_data, test_label)
  44. print('test loss:',loss,'acc:',acc)
  45. loss,acc=model.evaluate(train_data, train_label)
  46. print('train loss:',loss,'acc:',acc)
  47. loss,acc=model.evaluate(validation_data, validation_label)
  48. print('valid loss:',loss,'acc:',acc)
  49. #历史数据绘图
  50. import pandas as pd
  51. d=pd.DataFrame(data=loss_history.history)
  52. d.to_csv(root_path+'history.csv')

7、模型拼接

复制代码既可用       深度学习 11 keras迁移学习模型拼接_a486259的博客-CSDN博客

8、迁移模型知识蒸馏

迁移后的模型体量太大,复制该代码既可

深度学习12 基于keras的知识蒸馏_a486259的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/532149
推荐阅读
相关标签
  

闽ICP备14008679号