caffe/matalb/python中数据的存储方式
下面的代码摘自:classification_demo.m
% Usage:
% im = imread('../../examples/images/cat.jpg');
% scores = classification_demo(im, 1);
% [score, class] = max(scores);
% Five things to be aware of:
% caffe uses row-major order
% matlab uses column-major order
% caffe uses BGR color channel order
% matlab uses RGB color channel order
% images need to have the data mean subtracted
% Data coming in from matlab needs to be in the order
% [width, height, channels, images]
% where width is the fastest dimension.
% Here is the rough matlab for putting image data into the correct
% format in W x H x C with BGR channels:
% % permute channels from RGB to BGR
% im_data = im(:, :, [3, 2, 1]);
% % flip width and height to make width the fastest dimension
% im_data = permute(im_data, [2, 1, 3]);
% % convert from uint8 to single
% im_data = single(im_data);
% % reshape to a fixed size (e.g., 227x227).
% im_data = imresize(im_data, [IMAGE_DIM IMAGE_DIM], 'bilinear');
% % subtract mean_data (already in W x H x C with BGR channels)
% im_data = im_data - mean_data;
1.python中数组是按行为主存储的。
2.matlab中数组是按列为主存储的
3.caffe使用c++,也是按行存储的。
1.python 中的图像的三通道是RGB
2.matlab中图像的通道是RGB
3.caffe使用opencv库,图像的通道为BGR
caffe C++中的blobs
caffe是基于blobs存储和交换数据。blobs是一个四维数组:
图像数量N * 通道数K * 图像高度H * 图像宽度W
在一个4位的blobs,坐标为(n,k,h,w)的物理位置为:
((n*K+k)*H+h)*W+w
caffe的matlab接口中,blobs的存储方式为:
width * height * channels * num
三通道的形式为BGR.
上述blobs不同的原因是,matlab和c的存储方式的差异。matlab中存储是按照: 列 * 行 * 页 * 卷 …的形式进行存储的。而c语言数组的存储方式可以理解为:…卷 * 页 * 行 * 列,其中这两种存储方式中,…卷、页相当于索引,行和列维实际存储值。
通过地址的形式访问,越后面的维度存储越是连续的,具体参考:
《一个例子弄明白C语言动态多维数组的创建,存储,引用及降维操作》
caffe提供了读取图像的接口:
im_data = caffe.io.load_image('./examples/images/cat.jpg');
im_data = imresize(im_data, [width, height]); % resize using Matlab's imresize
img_data是:width * height * C 的三维数组,并且提供的接口读取的图像的通道顺序为:BGR。
使用matlab自带的读取图像的接口:
此时需要对图像进行额外的处理操作才能供caffe使用。
im_data = imread('./examples/images/cat.jpg'); % read image
im_data = im_data(:, :, [3, 2, 1]); % 从 RGB 转换为 BGR
im_data = permute(im_data, [2, 1, 3]); % 改变 width 与 height 位置
im_data = single(im_data); % 转换为单精度
单通道图像和单标签转化为hdf5格式
在这个例子中,我们关心的是图像是如何转换为hdf5供caffe使用的,但是这个例子中只涉及到单通道和单标签图像。
核心代码如下:
% train-images.idx3-ubyte / train-labels.idx1-ubyte
% images: 784*60000,784为28*28大小的图像,60000是训练样本的数量
% labels: 60000*1 的列矢量。
images = loadMNISTImages('train-images.idx3-ubyte');
labels = loadMNISTLabels('train-labels.idx1-ubyte');
% reshape images to 4-D: [rows,col,channel,numbers]
% trainData: 28 * 28 * 1 * 60000 [height,width,channels,numbers]
trainData=reshape(images,[28 28 1 size(images,2)]);
% permute to [cols,rows,channel,numbers]
% trainData: 28 * 28 * 1 * 60000 [width,height,channels,numbers],因为高和宽大小相同
trainData=permute(trainData,[2 1 3 4]);
% permute lables to [labels, number of labels ]
% trainLabel: 1 * 60000
trainLabels=permute(labels,[2,1]);
h5create('train.hdf5','/data',size(trainData),'Datatype','double');
h5create('train.hdf5','/label',size(trainLabels),'Datatype','double');
h5write('train.hdf5','/data',trainData);
h5write('train.hdf5','/label',trainLabels);
上面两次用到了permute函数,是因为matlab以列为主,c语言以行为主。
特征向量 和单标签转换为 hdf5 格式
问题:输入数字的大小为,label是单标签。
% 创建HDF5文件,包含data和label两个变量,数据类型是caffe支持的float型数据
h5create('train.h5','/data',[1 1 512 1000],'Datatype','single');
h5create('train.h5','/label',[1 1 1 1000],'Datatype','single');
%reshape: width x height x channels x num,注意MATLAB读数据是列优先,是和C++里面相反的。所以写数据的时候也要倒着写。
train_data = reshape(train_data,[1 1 512 1000]);
train_label = reshape(train_label,[1 1 1 1000]);
h5write('train.h5' ,'/data' , single(train_data));
h5write('train.h5' ,'/label', single(train_label));
上面的情况来至于网络,
下面的情况根据上面的原则应该如此,还需要进行验证。
多通道图像(彩色)和单标签转化为hdf5格式
只需要将## 单通道图像和单标签转化为hdf5格式中:
% permute channels from RGB to BGR
% trainData = trainData(:,:,[3,2,1],:);
多通道图像和多标签转换为hdf5格式
此时2个label 应该为,n个标签,修改matlab中的第3维,或者是下面表示形式的第1维。
train_label = reshape(train_label,[1 1 2 1000]);
% 或
train_label = reshape(train_label,[2 1000]);
验证
参考文献:
- http://blog.sina.com.cn/s/blog_62c832270101bdrp.html [一个例子弄明白C语言动态多维数组的创建,存储,引用及降维操作;]