当前位置:   article > 正文

采用DensNet121模型进行迁移学习——服装二分类任务_densenet121迁移学习

densenet121迁移学习

这是一个品牌分类任务,需要设计一个神经网络,识别出其正确率。采用DensNet121进行迁移学习

  1. from sklearn import metrics
  2. import numpy as np
  3. import tensorflow as tf
  4. from tensorflow import keras
  5. from tensorflow.keras import Model, layers
  6. from tensorflow.keras import layers, optimizers, datasets, Sequential
  7. import os
  8. from tensorflow.python.keras import regularizers
  9. # 数据读取函数,返回训练集、验证集、测试集
  10. def get_data(height, width, batchsz):
  11. # 获取训练集
  12. filepath1 = '/content/drive/MyDrive/Colab Notebooks/Fashion_Dataset/train'
  13. train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  14. filepath1, # 指定数据路径
  15. label_mode='categorical', # 导入的目标数据,进行onehot编码
  16. image_size=(height, width), # 对图像resize
  17. batch_size=batchsz, # 每次迭代的batchsize
  18. )
  19. # 获取验证集数据
  20. filepath2 = '/content/drive/MyDrive/Colab Notebooks/Fashion_Dataset/val'
  21. val_ds = tf.keras.preprocessing.image_dataset_from_directory(
  22. filepath2,
  23. label_mode='categorical',
  24. image_size=(height, width),
  25. batch_size=batchsz,
  26. )
  27. # 获取验证集数据
  28. filepath3 = '/content/drive/MyDrive/Colab Notebooks/Fashion_Dataset/test'
  29. test_ds = tf.keras.preprocessing.image_dataset_from_directory(
  30. filepath3,
  31. label_mode='categorical',
  32. image_size=(height, width),
  33. batch_size=batchsz,
  34. )
  35. return (train_ds, val_ds, test_ds)
  36. # 获取数据
  37. train_ds, val_ds, test_ds = get_data(224, 224, 64)
  38. # 查看分类名称
  39. class_names = train_ds.class_names
  40. print('分类名:', class_names)
  41. # 查看数据信息
  42. sample = next(iter(train_ds))
  43. print('x_batch.shape:', sample[0].shape, 'y_batch.shape:', sample[1].shape)
  44. # 构建归一化函数
  45. def processing(x, y):
  46. # 图像中的每个像素值映射到[-1,1]之间 归一化
  47. x = 2 * tf.cast(x, dtype=tf.float32) / 255.0 - 1
  48. y = tf.cast(y, dtype=tf.int32)
  49. # 返回处理后的结果
  50. return (x, y)
  51. #对数据进行洗牌
  52. train_ds = train_ds.map(processing).shuffle(10000)
  53. val_ds = val_ds.map(processing) # 验证集和测试集不需要打乱顺序
  54. test_ds = test_ds.map(processing)
  55. # 查看数据信息
  56. sample = next(iter(train_ds))
  57. print('x_batch.shape:', sample[0].shape, 'y_batch.shape:', sample[1].shape)
  58. #载入DensNet模型并进行网络微调
  59. def get_new_model():
  60. pre_model = tf.keras.applications.DenseNet121(
  61. # 不包括全连接层,导入预训练权重,自定义输入图片大小
  62. include_top=False, weights='imagenet', input_shape=[224, 224, 3]
  63. )
  64. # 冻住特征提取层
  65. for layer in pre_model.layers:
  66. # 正反向传播过程中权重参数不更新
  67. layer.trainable = False
  68. # 进行一次前向传播,看图像有何改变
  69. imgs, labels = next(iter(train_ds))
  70. # 获取训练集的某一个batch的图像及标签
  71. res = pre_model(imgs)
  72. # 微调网络
  73. # 解冻所有网络层
  74. pre_model.trainable = True
  75. print('numbers of layers:', len(pre_model.layers))
  76. # 查看一共有多少层:780
  77. # 指定冻结前500层
  78. find_tune_at = 500
  79. # 前500层在正方向传播过程中参数不能变,剩下的层权重参数可以调整
  80. for layer in pre_model.layers[:find_tune_at]: # 包括第500层
  81. layer.trainable = False
  82. # 构造输出层
  83. # 对特征提取层的输出进行全局平均池化
  84. x = layers.GlobalAveragePooling2D()(pre_model.output)
  85. x = layers.Flatten(name='flatten')(x)
  86. x = layers.Dense(2048, activation='relu', kernel_regularizer=regularizers.l2(0.0001))(x) #对数据进行正则化
  87. x = layers.BatchNormalization()(x)
  88. x = layers.Dense(1024, activation='relu', kernel_regularizer=regularizers.l2(0.0001))(x)
  89. x = layers.BatchNormalization(name='bn_fc_01')(x)
  90. #输出层分2类
  91. x = layers.Dense(2, activation='softmax')(x)
  92. # 构建模型
  93. model = Model(pre_model.input, x)
  94. #网络配置,调小学习率避免过拟合
  95. opt = optimizers.Adam(learning_rate=0.001)
  96. #编译
  97. model.compile(optimizer=opt, # 学习率
  98. loss='categorical_crossentropy', # 对onehot后的y,计算交叉熵损失
  99. metrics=['accuracy']) # 评价指标
  100. return model
  101. model = get_new_model()
  102. model.summary()
  103. from tensorflow.keras.callbacks import ModelCheckpoint
  104. checkpoint_path = '/content/drive/MyDrive/model_checkpoints' # 每次保存的都会覆盖旧的
  105. # 每次保存为一个新的文件
  106. checkpoint = ModelCheckpoint(filepath=checkpoint_path,
  107. save_freq='epoch', # 每个epoch结束就保存一次
  108. save_weights_only=True,
  109. verbose=1)
  110. # 训练,在上一次训练的基础上继续训练10次
  111. history_fine = model.fit(train_ds, # 训练集
  112. validation_data=val_ds, # 验证集
  113. epochs=25,
  114. callbacks=[checkpoint]) # 迭代次数修改epoch
  115. import matplotlib.pyplot as plt
  116. train_acc = history_fine.history['accuracy']
  117. test_acc = history_fine.history['val_accuracy']
  118. # 损失
  119. train_loss = history_fine.history['loss']
  120. test_loss = history_fine.history['val_loss']
  121. # 绘图
  122. # 准确率曲线
  123. plt.figure(figsize=(10, 5))
  124. plt.subplot(1, 2, 1)
  125. plt.plot(train_acc, label='train_acc')
  126. plt.plot(test_acc, label='test_acc')
  127. plt.title('accuracy')
  128. plt.legend() #显示图例label
  129. # 损失曲线
  130. plt.subplot(1, 2, 2)
  131. plt.plot(train_loss, label='train_loss')
  132. plt.plot(test_loss, label='test_loss')
  133. plt.title('loss')
  134. plt.legend()
  135. plt.show()
  136. test_loss, test_acc =model .evaluate(test_ds)
  137. print("Test loss: {:.3f}\nTest accuracy: {:.2f}%".format(test_loss, 100 * test_acc))

利用K折交叉熵

  1. from PIL import Image
  2. # 从文件夹读取图片和标签到numpy数组中
  3. # 标签信息在文件名中,burberry类型的衣服表示该图片的标签为0
  4. def read_data(data_dir):
  5. datas = []
  6. labels = []
  7. for fname in os.listdir(data_dir):
  8. if fname[:8] =='burberry':
  9. label = 0
  10. else:
  11. label = 1
  12. fpath = os.path.join(data_dir, fname)
  13. i=0
  14. for ffname in os.listdir(fpath):
  15. ffpath = os.path.join(fpath, ffname)
  16. image = Image.open(ffpath)
  17. image = image.resize((224,224),Image.LANCZOS)
  18. data = np.array(image) / 255.0
  19. label = label
  20. datas.append(data)
  21. labels.append(label)
  22. datas = np.array(datas)
  23. labels = np.array(labels)
  24. #print("shape of datas: {}\tshape of labels: {}".format(datas.shape,labels.shape))
  25. return datas, labels
  26. 将训练集和验证集合并为一个训练集
  27. def get_data(path="/content/drive/MyDrive/Colab Notebooks/Fashion_Dataset"):
  28. #将path修改为dataset路径
  29. train_x, train_y = read_data(os.path.join(path,'train'))
  30. val_x, val_y = read_data(os.path.join(path,'val'))
  31. test_x, test_y = read_data(os.path.join(path,'test'))
  32. #合并
  33. #train_x = np.vstack((train_x,val_x))
  34. #train_y = np.hstack((train_y,val_y))
  35. train_x = np.concatenate([train_x,val_x],axis=0)
  36. train_y = np.concatenate([train_y,val_y],axis=0)
  37. #训练集打乱
  38. train_x,train_y=shuffle_datas(train_x,train_y)
  39. print("shape of datas: {}\tshape of labels: {}".format(train_x.shape,train_y.shape))
  40. print("shape of datas: {}\tshape of labels: {}".format(test_x.shape,test_y.shape))
  41. return train_x,train_y,test_x,test_y
  42. # 对数据进行洗牌
  43. def shuffle_datas(x,y):
  44. index = [i for i in range(len(x))]
  45. np.random.shuffle(index)
  46. x = x[index]
  47. y = y[index]
  48. return x,y
  49. #获取数据
  50. train_x,train_y,test_x,test_y = get_data()
  51. K折交叉验证实现(k取5组)
  52. from tensorflow.keras.utils import to_categorical
  53. k=5
  54. num_epochs=25
  55. #算出滑动步长 x_data的shape为(70000,28,28) 划分5组 每个步长为14000
  56. slid_step=int(train_x.shape[0]/k)
  57. #数据类型转换
  58. train_x.astype(dtype='float32')
  59. train_y.astype(dtype="int32")
  60. #historys用来记录5组auc
  61. historys=[]
  62. #五组实验
  63. for i in range(k):
  64. x_test, y_test = train_x[i * slid_step:(i + 1) * slid_step],train_y[i * slid_step:(i + 1) * slid_step]
  65. x_train, y_train = train_x[i * slid_step:], train_y[i * slid_step:]
  66. #数据形状修改为相同
  67. y_train = to_categorical(y_train, 2)
  68. y_test = to_categorical(y_test, 2)
  69. #读取模型
  70. model = get_new_model()
  71. history =model.fit(x_train, y_train,epochs=num_epochs,
  72. validation_data=(x_test,y_test),
  73. batch_size=64)
  74. historys.append(history.history)
  75. 平均准确率
  76. acc_mean=[]
  77. for i in range(5):
  78. acc_mean=list(range(1,6)),list(historys[i].values())[1]
  79. print(acc_mean)
  80. print("平均值acc:",np.sum(list(historys[i].values())[1])/25)

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

闽ICP备14008679号

        
cppcmd=keepalive&