caffe hdf5数据进行多标签数据训练与测试

利用Caffe进行多标签影像数据训练时,主要有两种方法:

1. 对caffe源码进行修改,修改convert_imageset.cpp文件支持多标签,具体步骤可以参考https://www.jianshu.com/p/fdf7c599ab9d

2. 利用HDF5数据和Slice层进行多标签数据训练,本文主要介绍本方法。

  • 制造hdf5数据

        首先将图像数据和标签保存到TXT文件中,本文为图像路径 label_1 label_2形式如下

114841417@N06/coarse_tilt_aligned_face.492.12059747423_6b3535aa6a_o.jpg 3 0
8187011@N06/coarse_tilt_aligned_face.992.10353206665_5173637857_o.jpg 4 1
48647239@N03/coarse_tilt_aligned_face.1515.11838493313_5b7240b1c9_o.jpg 3 1
100003415@N08/coarse_tilt_aligned_face.2176.9523981569_ea255870f1_o.jpg 4 0
7464014@N04/coarse_tilt_aligned_face.965.10107710156_9cb48097c5_o.jpg 4 0
31183835@N08/coarse_tilt_aligned_face.2096.8754898174_5d34522d9a_o.jpg 4 1
63164355@N03/coarse_tilt_aligned_face.1082.8826664078_de8f6c6a9e_o.jpg 3 1
111700049@N08/coarse_tilt_aligned_face.1548.11833465006_b9235b0c89_o.jpg 5 0
63164355@N03/coarse_tilt_aligned_face.1111.11014305184_25bc533930_o.jpg 5 0
7398884@N04/coarse_tilt_aligned_face.1641.8727032370_97ab4ee179_o.jpg 3 0
10280355@N07/coarse_tilt_aligned_face.1880.9496762548_754e1337d6_o.jpg 6 1
33627988@N04/coarse_tilt_aligned_face.1949.8809482906_7021c9794c_o.jpg 7 1
64504106@N06/coarse_tilt_aligned_face.911.11846581226_fc9f42d681_o.jpg 0 0
112599447@N03/coarse_tilt_aligned_face.1201.11576030294_cf8d7137a6_o.jpg 5 1

对数据和标签进行编辑,生成hdf5数据:


 
 
  1. #影像文件夹所在目录
  2. img_root = './image'
  3. #训练数据txt路径
  4. train_path = './train.txt'
  5. #输出路径
  6. train_out = './hdf5_train'
  7. #将txt中的数据存入
  8. with open(train_path) as f:
  9. lines = f.readlines()
  10. file_list = [] #存入影像路径
  11. #建立标签和数据数组
  12. #若要生成hdf5数据,必须先把影像和标签变为数组
  13. #本文标签数目为2,影像数据:channel = 3,width = 256,height = 256故生成如下形式数据
  14. labels = np.zeros((len(lines), 2)).astype(np.int)
  15. datas = np.zeros((len(lines), 3, 256, 256)).astype(np.float32)
  16. #读取数据
  17. count = 0
  18. for line in lines:
  19. file_list.append(line.split()[ 0])
  20. labels[count][ 0] = line.split()[ 1]
  21. labels[count][ 1] = line.split()[ 2]
  22. count += 1
  23. f.close()
  24. #caffe利用hfd5数据时,在输入层没有transform_param 参数,所以需要先对影像数据进行预处理
  25. for i, file in enumerate(file_list):
  26. path = os.path.join(img_root,file)
  27. image = cv.imread(path) #获取影像
  28. image = cv.resize(image,( 256, 256)) #重采样为256*256大小的图像
  29. img = np.array(image)
  30. img = img.transpose( 2, 0, 1) #讲图像从宽 高 通道 形式转化为通道 宽 高 caffe读取图像形式
  31. datas[i, :, :, :] = img.astype(np.float32) #hdf5要求数据为float或double形式
  32. #获取影像均值
  33. mean = datas.mean(axis= 0)
  34. mean = mean.mean( 1).mean( 1)
  35. #将影像减去均值
  36. for i in range(len(datas)):
  37. datas[i][ 0] = datas[i][ 0] - mean[ 0]
  38. datas[i][ 1] = datas[i][ 1] - mean[ 1]
  39. datas[i][ 2] = datas[i][ 2] - mean[ 2]
  40. #保存hdf5文件
  41. with h5py.File(train_out, 'w') as fout:
  42. #'data'必须和train_val.prototxt文件里数据层中top:后边的名称一致,在修改prototxt文件时会进一步说明
  43. fout.create_dataset( 'data',data = datas)
  44. fout.create_dataset( 'label', data=labels)
  45. fout.close()

注意:1. caffe中获取hyd5文件时,需要把所有数据读入内存中,所以当数据量很大时,需要将其分成多份保存,每份最好不大于2GB

            2.在train_val.prototxt文件中,hdf5_data_param的source应该为保存hdf5数据路径的txt文件,不能直接读取hdf5数据

             3.HDF5Data layer没有transform_param参数,所以需要在生成hdf5数据之前对影像数据进行相应的预处理

  • 修改train_val.prototxt文件

 
 
  1. name: "CaffeNet"
  2. layers {
  3. name: "data"
  4. type: HDF5_DATA
  5. top: "data" #在生成hdf5文件时,数据和标签名称一定要和top之后的名称一致
  6. top: "label"
  7. hdf5_data_param {
  8. source: "/train_list.txt"
  9. batch_size: 64
  10. }
  11. include: { phase: TRAIN }
  12. }
  13. layers {
  14. name: "data"
  15. type: HDF5_DATA
  16. top: "data"
  17. top: "label"
  18. hdf5_data_param {
  19. source: "/test_list.txt"
  20. batch_size: 64
  21. }
  22. include: { phase: TEST }
  23. }
  24. #添加slices层,对标签进行划分
  25. layers {
  26. name: "slices"
  27. type: SLICE
  28. bottom: "label"
  29. top: "label_1" #有几个标签,就建立几个top
  30. top: "label_2"
  31. slice_param{
  32. axis: 1 #axis表示轴,用来确定数据是按照num还是channel来划分,此处表示利用channel来划分
  33. slice_point: 1 #slice_point数目等于label数目减1,本文为2个标签,所以划分一次即可
  34. #slice_point: 2 有三个标签,则增加slice_point层即可
  35. }
  36. }
  37. #卷积池化等层没做修改,在此处省略
  38. #修改fc8 accuracy和loss层
  39. layers {
  40. name: "fc8_age"
  41. type: INNER_PRODUCT
  42. bottom: "fc7"
  43. top: "fc8_age"
  44. inner_product_param {
  45. num_output: 8 #对应第一个标签输出
  46. }
  47. }
  48. layers {
  49. name: "accuracy1"
  50. type: ACCURACY
  51. bottom: "fc8_age"
  52. bottom: "label_1" #标签1 slices层划分的
  53. top: "accuracy1"
  54. include: { phase: TEST }
  55. }
  56. layers {
  57. name: "loss_age"
  58. type: SOFTMAX_LOSS
  59. bottom: "fc8_age"
  60. bottom: "label_1" #label_1
  61. top: "loss_age"
  62. }
  63. layers {
  64. name: "fc8_gender"
  65. type: INNER_PRODUCT
  66. bottom: "fc7"
  67. top: "fc8_gender"
  68. inner_product_param {
  69. num_output: 2 #label_2的输出
  70. }
  71. }
  72. layers {
  73. name: "accuracy2"
  74. type: ACCURACY
  75. bottom: "fc8_gender"
  76. bottom: "label_2" #对应于label_2
  77. top: "accuracy2"
  78. include: { phase: TEST }
  79. }
  80. layers {
  81. name: "loss_gender"
  82. type: SOFTMAX_LOSS
  83. bottom: "fc8_gender"
  84. bottom: "label_2" #对应于label_2
  85. top: "loss_gender"
  86. }
  • 修改deploy.prototxt

 
 
  1. #只修改fc8和prob层即可
  2. layers {
  3. name: "fc8_age"
  4. type: INNER_PRODUCT
  5. bottom: "fc7"
  6. top: "fc8_age"
  7. inner_product_param {
  8. num_output: 8
  9. }
  10. }
  11. layers {
  12. name: "prob1"
  13. type: SOFTMAX
  14. bottom: "fc8_age"
  15. top: "prob1"
  16. }
  17. layers {
  18. name: "fc8_gender"
  19. type: INNER_PRODUCT
  20. bottom: "fc7"
  21. top: "fc8_gender"
  22. inner_product_param {
  23. num_output: 2
  24. }
  25. }
  26. layers {
  27. name: "prob2"
  28. type: SOFTMAX
  29. bottom: "fc8_gender"
  30. top: "prob2"
  31. }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值