1.前言
上一篇博客介绍了一个Caffe自带的例子,使用Python接口实现多标签数据的输入,通过SigmoidCrossEntropy Loss函数实现Caffe多标签分类。实现多标签分类的关键是实现多标签图像数据的录入,这篇博客介绍如何为自己的数据集定制一个基于Python的多标签图像数据输入的data层。
2.数据集
本文选用多标签数据集Corel5k用于实验,平均每幅图像含有3.5个标注词。
3.为数据集定制用于输入的data层
由上一篇博客可以看出,实现多标签图像数据输入的两个文件是pascal_multilabel_datalayers.py(实现数据输入)、tools.py(实现图像数据的处理)。因此,我们需要为目标数据集定制两个类似的文件用于多标签图像数据的输入。
3.1Corel5k_multilabel_datalayers.py(用于多标签图像数据的输入)
多标签图像数据的输入需要两个txt文件(train.txt与val.txt),文件中存储了图像的文件名与标签,标签由1和0组成(含有这个标签则为1,不含有这个标签则为0)。使用Python读取的时候可以使用空格为分隔符,依次读取出图像的文件名与标签。
import scipy.misc
import caffe
import numpy as np
import os.path as osp
from random import shuffle
from PIL import Image
from tools import SimpleTransformer
class Corel5kMultilabelDataLayerSync(caffe.Layer):
def setup(self, bottom, top):
#定义data层的输入名称(data和label)
self.top_names = ['data', 'label']
#读取Python data层的变量名
params = eval(self.param_str)
#判断params是否合法
check_params(params)
# 获取每次训练需要读取的batch_size
self.batch_size = params['batch_size']
# 用于读取每个批次的图像数据信息
self.batch_loader = BatchLoader(params, None)
#reshape输入的图像数据
top[0].reshape(self.batch_size, 3, params['im_shape'][0], params['im_shape'][1])
#reshape标签信息
top[1].reshape(self.batch_size, 260)
#输出params信息
print_info("Corel5kMultilabelDataLayerSync", params)
# 前向函数
def forward(self, bottom, top):
# 读取图像数据与标签
for itt in range(self.batch_size):
#读取并保存每张图片的图像内容信息和标签信息
im, multilabel = self.batch_loader.load_next_image()
# 上面定义了top[0]存取的是label、top[1]是标签
top[0].data[itt, ...] = im
top[1].data[itt, ...] = multilabel
# data层不需要Reshape,因为输入是固定的
def reshape(self, bottom, top):
pass
# 定义反向传播函数(data层不需要反向传播)
def backward(self, top, propagate_down, bottom):
pass
class BatchLoader(object):
def __init__(self, params, result):
self.result = result
# 获取batch_size大小
self.batch_size = params['batch_size']
# 获取root文件夹,里面有train.tx与val.txt
self.Corel5k_root = params['Corel5k_root']
# 输入图像的大小
self.im_shape = params['im_shape']
# 判断是训练阶段还是测试阶段
# self.isshuffle定义是否打乱图像的顺序
# self.iscenter 定义是否在中心裁剪图像数据
# self.isflip 定义图像是否翻转
if params['split'] == 'train':
self.isshuffle = True
self.iscenter = False
self.isflip = True
else:
self.isshuffle = False
self.iscenter = True
self.isflip = False
#图片的存储地址
self.floder = r'E:\MATLAB_space\DataSet_Image\Corel5k'
#保存着数据信息的txt文件的位置
list_file = params['split'] + '