Caffe训练自己的数据

注意:一下所有配置,均为林多的电脑配置路径。如果,要在自己的电脑上run,请仔细改为自己电脑上相应的路径。
1、准备训练数据

首先为训练数据和测试数据,新建两个文件夹,名称任意,存放数据:
trian(存放训练数据)
val(存放测试数据)
在tiran和val中,放入统一尺寸的图片,如320x320。保证这些图像的名称,不包含奇怪的字符。最好是数字或字母组成的名称。

2、新建train.txt和val.txt两个文本。

在train.txt中,输入train文件下的图片名+分类。
trian.txt内容如(更正:标签建议从0开始):
1.jpg 0
2.jpg 0
3.jpg 1

注意:1.jpg和1(类别)之间,只能有1个空格。
成千,上万的文件名,如何一下子输入到.txt中?
命令“dir/s/on/b>d:/train.txt”,可以将当前所在文件夹内的文件名(含路径,输入到tran.txt中),之后,只要利用记事本里的“查找—替换”功能,将路径名替换为空,将.jpg替换成(.jpg 1)。如存在多个分类,建立多个文件夹,将不同分类放入,重复上面步骤,最后将多个.txt内容整合到一个.txt中即可。

最后,将train.txt和val.txt放在与train和val文件夹同级的目录下。如D:/my文件夹内
注:在linux或windows下,跑caffe,其实差别不是很大,训练数据几乎是一样的,只是windows下多用leveldb格式,而linux下为默认的lmdb格式。至于配置文件,无非是指定路径的差别。

3、利用caffe自带例子中的imagenet来训练我们的数据。

windows下,将caffe安装目录下的examples\imagenet中的 create_imagenet.sh、make_ imagenet.sh、train_caffenet.sh。和models\bvlc_reference_caffenet中的solver.prototxt和train_val.prototxt。一共5个文件,拷入到D:/my文件夹中.
在windows下,安装Git,即可运行sh,十分方便。

4、生成leveldb和图像均值

修改create_imagenet.sh,内容如下:

#!/usr/bin/env sh
# Create the imagenet lmdb inputs
# N.B. set the path to the imagenet train + val data dirs
set -e
#对应自己的路径
DATA=D:/my
TOOLS=D:/caffe-master/Build/x64/Release
#对应自己的路径
TRAIN_DATA_ROOT=D:/my/train/
VAL_DATA_ROOT=D:/my/val/

# Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
#改为true,让caffe为我们resize图片
RESIZE=true
if $RESIZE; then
  RESIZE_HEIGHT=256
  RESIZE_WIDTH=256
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi

if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet training data is stored."
  exit 1
fi

if [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet validation data is stored."
  exit 1
fi

echo "Creating train leveldb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    #指定数据格式
	--backend=leveldb \
    --shuffle \
    $TRAIN_DATA_ROOT \
    #对应自己的路径
    $DATA/train.txt \
    $DATA/imagenet_train_leveldb 

echo "Creating val leveldb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    #指定数据格式
	--backend=leveldb \
    --shuffle \
    $VAL_DATA_ROOT \
    #对应自己的路径
    $DATA/val.txt \
    $DATA/imagenet_val_leveldb 

echo "Done."

[图片]
运行后,生成imagenet_train_leveldb和imagenet_val_leveldb两个文件夹。
生成图像均值
修改make_imagenet_mean.sh,内容如下:

#!/usr/bin/env sh
# Compute the mean image from the imagenet training lmdb
# N.B. this is available in data/ilsvrc12
#对应自己的路径
DATA=D:/my
TOOLS=D:/caffe-master/Build/x64/Release
#对应自己的路径
$TOOLS/compute_image_mean.exe $DATA/imagenet_train_leveldb $DATA/imagenet_mean.binaryproto --backend=leveldb

echo "Done."

运行后,会生成imagenet_mean.binaryproto文件。

到此,数据阶段的所有内容,都已经准备好

5、配置,训练阶段需要的内容。
solver.prototxt内容:

#指定路径
net: "D:/my/train_val.prototxt"
test_iter: 1000
test_interval: 1000
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 100000
display: 20
max_iter: 450000
momentum: 0.9
weight_decay: 0.0005
snapshot: 10000
#指定路径
snapshot_prefix: "D:/my/result"
#指定CPU训练
solver_mode: CPU

train_val.prototxt文件内容:

name: "CaffeNet"
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 227
    #指定路径
    mean_file: "D:/my/imagenet_mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }
  data_param {
  #指定路径
    source: "D:/my/imagenet_train_leveldb"
    batch_size: 256
    #指定格式
	backend: LEVELDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 227
    #指定路径
    mean_file: "D:/my/imagenet_mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: false
#  }
  data_param {
  #指定路径
    source: "D:/my/imagene_val_leveldb"
    batch_size: 50
    #指定格式
    backend: LEVELDB
  }
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "norm1"
  top: "conv2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 2
    kernel_size: 5
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv3"
  type: "Convolution"
  bottom: "norm2"
  top: "conv3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}
layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}
layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "fc6"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6"
  top: "fc6"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: “类别数”#注意,此处对应训练数据的标签数(如100个类别:100)
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "fc8"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "fc8"
  bottom: "label"
  top: "loss"
}

将train_caffenet.sh,改为train_caffenet.bat,内容如下:

#!/usr/bin/env sh
set -e
#指定路径
D:/caffe-master/Build/x64/Release/caffe.exe train --solver=D:/my/solver.prototxt

到此,运行train_caffenet.bat,训练网络即可。。当然,你可以不把train_caffenet.sh改为.bat文件,只需要修改里面的路径后,在Git中,运行即可。

5、linux下

PS:博主某天重新看了下这段,有些乱。于是这段的仅供参考(-_-)
首选保证,你以及配置好caffe了。
在windows下,你也可以在linux下这么做。。将数据重新生成lmdb格式。。。就是在上面的步骤中,去掉 --backend=leveldb \,再将 $DATA/imagenet_train_leveldb 改为 $DATA/imagenet_train_lmdb (val的也要改)
这样会生成imagenet_train_lmdb和imagenet_val_lmdb两个文件夹。将生成的imagenet_train_lmdb和imagenet_val_lmdb两个文件夹中的内容,上传到linux服务器中。
首先,在~/caffe/examples/imagenet(以我安装caffe路径为例)文件夹下,利用mkdir命令新建两个文件夹
ilsvrc12_val_lmdb和ilsvrc12_train_lmdb。。将imagenet_train_leveldb和imagenet_val_leveldb中的内容,在SecureCRT中利用rz命令上传文件(将train文件夹中的图片,传入imagenet_train_leveldb。将val中的图片,传入imagenet_val_leveldb)

make_imagenet_mean.sh (无需修改)
create_imagenet.sh(无需修改)
train_caffenet.sh内容(无需修改)
solver.prototxt内容(无需修改默认)
train_val.prototxt内容:(无需修改,默认)

之后,切换到~/caffe目录下
按照windows下的流程,运行 make_imagenet_mean.sh,然后train_caffen.sh。
如果,出现如法运行的情况,请切换到caffe安装根目录(~/caffe),在该目录下运行sh。

实际训练效果非常慢,大约1小时才回蹦出下一条提示。估计是Net的结构配置的不对,毕竟用了自己的数据,Net结构肯定要修改。但训练效果还是很好的。
下面是在linux服务器上跑的结果。
这里写图片描述
跑了大概两天,loss从最开始的7.65707,迭代到1280次时,降到0.000921745。训练出来的模型完全可以利用caffe+opencv做分类了~
这里写图片描述

这里提供了图片数据、标签分类文本、还是网络配置数据。在运行前,要生成自己的leveldb嗷~
Windows下caffe训练实例

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值