caffe 多标签输入训练数据标签一定要打乱顺序吗,打乱顺序的目的是啥

深度学习(7)
我的第二个程序时运行caffe自带的mnist手写数据。具体过程如下:
一、获取数据
可以从我的网盘中下载:
链接:/s/1dEVYUHj 密码:joyq
包含4个文件。
2个是训练集的:train-images.idx3-ubyte(训练集照片)和train-labels.idx1-ubyte(训练集照片对应的label).
2个是测试集的:t10k-images.idx3-ubyte(测试集照片)和t10k-labels.idx1-ubyte(测试集照片对应的label).
在数据放置在examples/mnist/文件夹下新建mnist_data文件夹,并将以上4个文件复制过去。
二、将数据转为leveldbd文件
此处我们换用一下方法,但是换汤不换药。
在caffe-master根目录下新建bat文件。convert_mnist_train.bat文件。并写入一下代码:
Build\x64\Debug\convert_mnist_data.exe --backend=lmdb examples\mnist\mnist_data\train-images.idx3-ubyte examples\mnist\mnist_data\train-labels.idx1-ubyte examples\mnist\mnist_data\mnist_train_lmdb
再新建文件convert_mnist_test.bat.写入如下代码:
此处采用的均是相对路径。此处,将文件转换为lmdb文件。
PS:convert_mnist_data.exe的使用格式:
convert_mnist_data.exe [FLAGS] Input_Image_File Input_Label_File OutPut_db_File
[FLAGS]:图片参数组
-gray:是否以灰度图的方式打开图片,默认为false。程序调用opencv库中的imread()函数来打开图片。
-shuffle:是否随机打乱图片顺序,默认为false。
-backend:需要转换成的文件格式,可设置为leveldb或者lmdb.
-reseize_width/resize_height:改变图片的大小。要求程序在运行中,要保证所有图片的大小一致。程序调用opencv库中的resize()函数对图片进行放缩。默认为false,即不变化。
Input_Image_File :输入图片的位置
Input_Label_File :图片文件列表清单,也就是输入图片的类标label。
OutPut_db_File:最终生成的db文件的存放位置。
三、运行程序
首先在examples/mnist/文件夹下面找到lenet_solver.prototxt文件。修改solver_mode=CPU.
将刚刚生成的两个文件夹剪切到examples/mnist/下。或者不动,修改lenet_train_test.prototxt的source。
在caffe-master根目录下新建.bat文件。写入代码如下:
.\Build\x64\Debug\caffe.exe train --solver=examples/mnist/lenet_solver.prototxt
pause即可运行。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2420次
排名:千里之外
原创:13篇拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(38e122f811cf662e-ua98).
重新安装浏览器,或使用别的浏览器1828人阅读
caffe-深度学习(21)
终于到了介绍如何使用Siamese网络跑自己的数据了,在网上、论坛上、群里关于用Siamese网络的资料很多,但是实战的资料很少,难道是因为太容易了吗?反正博主查阅了各种地方,几乎没有找到Siamese网络实战的东东,即使有零星关于实战的东西,那也是基于Ubuntu系统,殊不知Ubuntu系统跑caffe可要比Windows简单的多了,所以,就本博主的调研情况来看,这篇博客绝对称的上是Windows平台使用Siamese网络跑自己的数据的第一篇详细资料!这一篇介绍如何利用Windows caffe Siamese网络跑自己的数据,下一篇打算介绍如何调整和搭建网络结构。。。。
开始train。(补充一句,这个博客是博主刚开始学习写的,有很多不足的地方,评论区有一高人指出了几个不足之处,望大家在训练的时候注意那几个地方)
1、准备数据
我们知道Siamese网络是要输入一个图像对,这个图像对是一对image pair,所以首先要把图像数据放到文件夹中,然后建立一个索引文件,索引文件的每一行是两个图像名,代表一个图像对。样式如下:
2、转换数据
转换数据需要转换数据的可执行文件,这个可执行文件哪里得到呢?哎,说到这里都是眼泪了,搞了好长时间,终于找到了相应的代码,不过这个代码有一个大坑,不知道当时写这个代码的人是没有注意,还是故意挖坑呢:
#include &algorithm&
#include &fstream&
#include &string&
#include &cstdio&
#include &utility&
#include &vector&
#include "boost/scoped_ptr.hpp"
#include "gflags/gflags.h"
#include "glog/logging.h"
#include "leveldb/db.h"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"
#include "caffe/util/rng.hpp"
#include "caffe/util/math_functions.hpp"
#include "opencv2/opencv.hpp"
#include "google/protobuf/text_format.h"
#include "stdint.h"
#include &cstdio&
#include &iostream&
#include &cmath&
using namespace
using std::
using boost::scoped_
using namespace
using namespace std;
DEFINE_bool(gray, false, "when this option is on, treat images as grayscale ones");
DEFINE_bool(shuffle, false, "randomly shuffle the order of images and their labels");
DEFINE_string(backend, "leveldb", "the backend {lmdb, leveldb} for storing the result");
DEFINE_int32(resize_width, 0, "Width images are resized to");
DEFINE_int32(resize_height, 0, "Height images are resized to");
DEFINE_bool(check_size, false,
"When this option is on, check that all the datum have the same size");
DEFINE_bool(encoded, false,
"When this option is on, the encoded image will be save in datum");
DEFINE_string(encode_type, "",
"Optional: What type should we encode the image as ('png','jpg',...).");
DEFINE_int32(channel, 3, "channel numbers of the image");
static bool ReadImageToMemory(const string &FileName, const int Height, const int Width, char *Pixels)
cv::Mat OriginImage = cv::imread(FileName);
CHECK(OriginImage.data) && "Failed to read the image.\n";
cv::Mat ResizeI
cv::resize(OriginImage, ResizeImage, cv::Size(Width, Height));
CHECK(ResizeImage.rows == Height) && "The heighs of Image is no equal to the input height.\n";
CHECK(ResizeImage.cols == Width) && "The width of Image is no equal to the input width.\n";
CHECK(ResizeImage.channels() == 3) && "The channel of Image is no equal to three.\n";
for (int HeightIndex = 0; HeightIndex & H ++HeightIndex)
const uchar* ptr = ResizeImage.ptr&uchar&(HeightIndex);
int img_index = 0;
for (int WidthIndex = 0; WidthIndex & W ++WidthIndex)
for (int ChannelIndex = 0; ChannelIndex & ResizeImage.channels(); ++ChannelIndex)
int datum_index = (ChannelIndex * Height + HeightIndex) * Width + WidthI
*(Pixels + datum_index) = static_cast&char&(ptr[img_index++]);
return true;
int main(int argc, char** argv)
#ifndef GFLAGS_GFLAGS_H_
namespace gflags =
gflags::SetUsageMessage("Convert a set of color images to the leveldb\n"
"format used as input for Caffe.\n"
"Usage:\n"
convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME\n");
caffe::GlobalInit(&argc, &argv);
if (argc & 4)
gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/convert_imageset");
std::ifstream infile(argv[2]);
std::vector&std::pair&std::string, std::string& &
std::string
std::string
while (infile && filename && pairname)
lines.push_back(std::make_pair(filename, pairname));
if (FLAGS_shuffle)
LOG(INFO) && "Shuffling data";
shuffle(lines.begin(), lines.end());
LOG(INFO) && "A total of " && lines.size() && " images.";
int resize_height = std::max&int&(0, FLAGS_resize_height);
int resize_width = std::max&int&(0, FLAGS_resize_width);
int channel = std::max&int&(1, FLAGS_channel);
leveldb::DB*
leveldb::O
options.create_if_missing = true;
options.error_if_exists = true;
leveldb::Status status = leveldb::DB::Open(
options, argv[3], &db);
CHECK(status.ok()) && "Failed to open leveldb " && argv[3]
&& ". Is it already existing?";
std::string root_folder(argv[1]);
char* Pixels = new char[2 * resize_height * resize_width * channel];
const int kMaxKeyLength = 10;
char key[kMaxKeyLength];
std::string
datum.set_channels(2 * channel);
datum.set_height(resize_height);
datum.set_width(resize_width);
for (int LineIndex = 0; LineIndex & lines.size(); LineIndex++)
char* FirstImagePixel = P
ReadImageToMemory(root_folder + lines[LineIndex].first, resize_height, resize_width, FirstImagePixel);
char *SecondImagePixel = Pixels + resize_width * resize_height *
ReadImageToMemory(root_folder + lines[LineIndex].second, resize_height, resize_width, SecondImagePixel);
datum.set_data(Pixels, 2 * resize_height * resize_width * channel);
if (LineIndex&9123000)
datum.set_label(1);
datum.set_label(0);
datum.SerializeToString(&value);
int key_value = (int)(LineIndex);
_snprintf(key, kMaxKeyLength, "%08d", key_value);
string keystr(key);
cout && "label: " && datum.label() && ' ' && "key index: " && keystr &&
db-&Put(leveldb::WriteOptions(), std::string(key), value);
delete[] P
这个cpp文件里有一个大坑,下面再做介绍。在caffe-windows-master\build_cpu_only\同样的方法,把convert_imageset文件复制一下,然后把复制文件夹里的release删除,把剩下的三个文件重命名,然后把复制的这个工程用VS打开,把原来的cpp移除,把上面的代码作为cpp文件导进去,这个步骤的实现方法我就不截图了,前面的博客里都有详细的截图说明,不懂的去看前面的博客吧。
生成之后,在bin目录下会有convert_imagese_siamese.exe可执行文件,这个文件就是用来数据转换的文件,在data文件夹下新建一个文件夹用来存放数据和可执行文件,写一个数据转换脚本文件:
分别转换训练集和验证集。
3、开始训练
有了数据集,就要训练了不是,写一个训练的脚本文件:
Siamese网络还是用的caffe自带的那个Siamese网络协议和超参文件,这两个文件中需要修改的地方在这里我不做介绍了,不懂的同学去看之前的博客吧。
这个时候就出现大坑了。
cv::resize错误,咋回事?起初我还以为是我的opencv有问题,所以在工程里我配置了一下opencv结果,还是不行,老方法,我就知道这个问题去问别人,别人也解答不了,也没人去解答,靠人不如靠自己啊!去一行行分析源码吧。。。。。。不看不知道,一看吓一跳啊,数据转换代码里有一个大坑。
int resize_height = std::max&int&(0, FLAGS_resize_height);
int resize_width = std::max&int&(0, FLAGS_resize_width);
DEFINE_int32(resize_width, 0, "Width images are resized to");
DEFINE_int32(resize_height, 0, "Height images are resized to");
修改方法:把定义中的0改成你要设置的图像大小即可。
再编译一次,把数据重新转换,可以训练了。
4、一个疑问*(已经解决)*
开始训练以后,我的会caffe会报一个错误,第一个卷积层的卷积核参数共享提示维度不匹配,一个是20*1*5*5,共享层是20*5*5*5,没办法只能把这个参数共享关了,不知道具体原因是什么,参数共享的这两个卷积层明明是一样的 ,如果有知道原因的同学还想请教一下,在此先谢过了。
把第一个参数共享关闭了之后,成功。
后来查看了Glog日志,发现问题在于Slice层数据分解的问题,至于Slice层的讲解在这个博客里介绍的比较详细
解决方法,就是在slice_point: 1去除,使得数据平均分配,就没有维度不匹配的问题了。
写在后面的话:
Siamese网络是两个lenet网络的合并,用ContrastiveLoss损失函数做图像对的训练,但是我觉得Siamese更多的是一种思想,所有挖掘双分支或者更多分支关系的网络都可以称为Siamese网络,而不仅仅局限于lenet。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:25753次
排名:千里之外
原创:22篇
评论:68条在深度学习的实际应用中,我们经常用到的原始数据是图片文件,如jpg,jpeg,png,tif等格式的,而且有可能图片的大小还不一致。而在caffe中经常使用的数据类型是lmdb或leveldb,因此就产生了这样的一个问题:如何从原始图片文件转换成caffe中能够运行的db(leveldb/lmdb)文件?
在caffe中,作者为我们提供了这样一个文件:convert_imageset.cpp,存放在根目录下的tools文件夹下。编译之后,生成对应的可执行文件放在 buile/tools/ 下面,这个文件的作用就是用于将图片文件转换成caffe框架中能直接使用的db文件。
该文件的使用格式:
convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME
需要带四个参数:
FLAGS: 图片参数组,后面详细介绍
ROOTFOLDER/: 图片存放的绝对路径,从linux系统根目录开始
LISTFILE: 图片文件列表清单,一般为一个txt文件,一行一张图片
DB_NAME: 最终生成的db文件存放目录
如果图片已经下载到本地电脑上了,那么我们首先需要创建一个图片列表清单,保存为txt
本文以caffe程序中自带的图片为例,进行讲解,图片目录是 &example/images/, 两张图片,一张为cat.jpg, 另一张为fish_bike.jpg,表示两个类别。
我们创建一个sh脚本文件,调用linux命令来生成图片清单:
# sudo vi examples/images/create_filelist.sh
编辑这个文件,输入下面的代码并保存
# /usr/bin/env sh
DATA=examples/images
echo &Create train.txt...&
rm -rf $DATA/train.txt
find $DATA -name *cat.jpg | cut -d '/' -f3 | sed &s/$/ 1/&&&$DATA/train.txt
find $DATA -name *bike.jpg | cut -d '/' -f3 | sed &s/$/ 2/&&&$DATA/tmp.txt
cat $DATA/tmp.txt&&$DATA/train.txt
rm -rf $DATA/tmp.txt
echo &Done..&
这个脚本文件中,用到了rm,find, cut, sed,cat等linux命令。
rm: 删除文件
find: 寻找文件
cut: 截取路径
sed: 在每行的最后面加上标注。本例中将找到的*cat.jpg文件加入标注为1,找到的*bike.jpg文件加入标注为2
cat: 将两个类别合并在一个文件里。
最终生成如下的一个train.txt文件:
fish-bike.jpg 2
当然,图片很少的时候,手动编写这个列表清单文件就行了。但图片很多的情况,就需要用脚本文件来自动生成了。在以后的实际应用中,还需要生成相应的val.txt和test.txt文件,方法是一样的。
生成的这个train.txt文件,就可以作为第三个参数,直接使用了。
接下来,我们来了解一下FLAGS这个参数组,有些什么内容:
-gray: 是否以灰度图的方式打开图片。程序调用opencv库中的imread()函数来打开图片,默认为false
-shuffle: 是否随机打乱图片顺序。默认为false
-backend:需要转换成的db文件格式,可选为leveldb或lmdb,默认为lmdb
-resize_width/resize_height: 改变图片的大小。在运行中,要求所有图片的尺寸一致,因此需要改变图片大小。 程序调用opencv库的resize()函数来对图片放大缩小,默认为0,不改变
-check_size: 检查所有的数据是否有相同的尺寸。默认为false,不检查
-encoded: 是否将原图片编码放入最终的数据中,默认为false
-encode_type: 与前一个参数对应,将图片编码为哪一个格式:‘png','jpg'......
好了,知道这些参数后,我们就可以调用命令来生成最终的lmdb格式数据了
由于参数比较多,因此我们可以编写一个sh脚本来执行命令:
首先,创建sh脚本文件:
# sudo vi examples/images/create_lmdb.sh
编辑,输入下面的代码并保存
#!/usr/bin/en sh
DATA=examples/images
rm -rf $DATA/img_train_lmdb
build/tools/convert_imageset --shuffle \
--resize_height=256 --resize_width=256 \
/home/xxx/caffe/examples/images/ $DATA/train.txt
$DATA/img_train_lmdb
设置参数-shuffle,打乱图片顺序。设置参数-resize_height和-resize_width将所有图片尺寸都变为256*256.
/home/xxx/caffe/examples/images/ 为图片保存的绝对路径。
最后,运行这个脚本文件
# sudo sh examples/images/create_lmdb.sh
就会在examples/images/ 目录下生成一个名为 img_train_lmdb的文件夹,里面的文件就是我们需要的db文件了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1032次
排名:千里之外2010年 总版技术专家分年内排行榜第二
2009年 总版技术专家分年内排行榜第三
2010年 总版技术专家分年内排行榜第二
2009年 总版技术专家分年内排行榜第三
2010年 总版技术专家分年内排行榜第二
2009年 总版技术专家分年内排行榜第三
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 caffe 多标签 的文章

 

随机推荐