一.数据模型与准备
(1) 进入caffe根目录,创建临时文件夹,用于存放所需要的临时文件
cd caffe
mkdir examples/_temp
(2) 根据examples/images文件夹中的图片,创建包含图像列表的txt文件,并添加标签
这里建议参考本人之前的一篇帖子,方便快捷
https://blog.csdn.net/swiftfake/article/details/79799880
我们首先生成temp.txt(带标签)文件
接下来我们要创建一个sh脚本文件,手动创建并命名为create_temp.sh
# /usr/bin/env sh
DATA=/home/hca/caffe/examples/images #DATA为训练集的路径
echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA -name cat*.jpg | cut -d '/' -f | sed "s/$/ 1/">>$DATA/temp.txt
find $DATA -name fish*.jpg | cut -d '/' -f | sed "s/$/ 2/">>$DATA/tmp.txt
cat $DATA/tmp.txt>>$DATA/temp.txt
rm -rf $DATA/tmp.txt
echo "Done.."
接下来生成file_list.txt(不带标签)文件
接下来我们要创建一个sh脚本文件,手动创建并命名为create_file_list.sh
# /usr/bin/env sh
DATA=/home/hca/caffe/examples/images #DATA为训练集的路径
echo "Create train.txt..."
rm -rf $DATA/train.txt
find $DATA -name cat*.jpg | cut -d '/' -f | sed "s/$/ /">>$DATA/file_list.txt
find $DATA -name fish*.jpg | cut -d '/' -f | sed "s/$/ /">>$DATA/tmp.txt
cat $DATA/tmp.txt>>$DATA/file_list.txt
rm -rf $DATA/tmp.txt
echo "Done.."
然后执行刚刚创建好的两个sh文件,
cd caffe
sh /XXX/create_temp.sh #/XXX/为存放create_temp.sh的路径
sh /XXX/create_file_list.sh #/xxx/为存放create_file_list.sh的路径
然后将生成的file_list.txt和temp.txt文件存放到_temp文件夹中。
(3)我们需要准备好已经训练好的网络模型和网络定义prototxt文件,然后将训练好的模型.caffemodel存放到/examples/imagenet文件夹下,将网络定义prototxt文件存放到_temp
文件夹中。(本人会尽快上传一个到百度云,方便新手练习)
二.提取特征并存储
(1) 安装CAFFE的python依赖库,并使用以下两个辅助文件把lmdb转换为mat。在caffe 根目录下创建feat_helper_pb2.py 和lmdb2mat.py,直接copy 下面的python程序即可。
cd caffe
sudo gedit feat_helper_pb2.py
sudo gedit lmdb2mat.py
需要添加的内容如下
feat_helper_pb2.py:
# Generated by the protocol buffer compiler. DO NOT EDIT!
from google.protobuf import descriptor
from google.protobuf import message
from google.protobuf import reflection
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
DESCRIPTOR = descriptor.FileDescriptor(
name='datum.proto',
package='feat_extract',
serialized_pb='\n\x0b\x64\x61tum.proto\x12\x0c\x66\x65\x61t_extract\"i\n\x05\x44\x61tum\x12\x10\n\x08\x63hannels\x18\x01 \x01(\x05\x12\x0e\n\x06height\x18\x02 \x01(\x05\x12\r\n\x05width\x18\x03 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x12\r\n\x05label\x18\x05 \x01(\x05\x12\x12\n\nfloat_data\x18\x06 \x03(\x02')
_DATUM = descriptor.Descriptor(
name='Datum',
full_name='feat_extract.Datum',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
descriptor.FieldDescriptor(
name='channels', full_name='feat_extract.Datum.channels', index=0,
number=1, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
descriptor.FieldDescriptor(
name='height', full_name='feat_extract.Datum.height', index=1,
number=2, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
descriptor.FieldDescriptor(
name='width', full_name='feat_extract.Datum.width', index=2,
number=3, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
descriptor.FieldDescriptor(
name='data', full_name='feat_extract.Datum.data', index=3,
number=4, type=12, cpp_type=9, label=1,
has_default_value=False, default_value="",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
descriptor.FieldDescriptor(
name='label', full_name='feat_extract.Datum.label', index=4,
number=5, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
descriptor.FieldDescriptor(
name='float_data', full_name='feat_extract.Datum.float_data', index=5,
number=6, type=2, cpp_type=6, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
serialized_start=29,
serialized_end=134,
)
DESCRIPTOR.message_types_by_name['Datum'] = _DATUM
class Datum(message.Message):
__metaclass__ = reflection.GeneratedProtocolMessageType
DESCRIPTOR = _DATUM
# @@protoc_insertion_point(class_scope:feat_extract.Datum)
# @@protoc_insertion_point(module_scope)
lmdb2mat.py:
import lmdb
import feat_helper_pb2
import numpy as np
import scipy.io as sio
import time
def main(argv):
lmdb_name = sys.argv[1]
print "%s" % sys.argv[1]
batch_num = int(sys.argv[2]);
batch_size = int(sys.argv[3]);
window_num = batch_num*batch_size;
start = time.time()
if 'db' not in locals().keys():
db = lmdb.open(lmdb_name)
txn= db.begin()
cursor = txn.cursor()
cursor.iternext()
datum = feat_helper_pb2.Datum()
keys = []
values = []
for key, value in enumerate( cursor.iternext_nodup()):
keys.append(key)
values.append(cursor.value())
ft = np.zeros((window_num, int(sys.argv[4])))
for im_idx in range(window_num):
datum.ParseFromString(values[im_idx])
ft[im_idx, :] = datum.float_data
print 'time 1: %f' %(time.time() - start)
sio.savemat(sys.argv[5], {'feats':ft})
print 'time 2: %f' %(time.time() - start)
print 'done!'
if __name__ == '__main__':
import sys
main(sys.argv)
(2) 在caffe 根目录下创建脚本文件extract_feature_example1.sh, 并执行,将在examples/_temp文件夹下得到lmdb文件(features_conv1)和.mat文件(features_conv1.mat)
cd caffe
sudo gedit extract_feature_example.sh
需要添加的内容如下:
#!/usr/bin/env sh
# args for EXTRACT_FEATURE
TOOL=./build/tools
MODEL=./examples/imagenet/caffe_reference_imagenet_model #下载得到的caffe model
PROTOTXT=./examples/_temp/imagenet_val.prototxt # 网络定义
LAYER=conv1 # 提取层的名字,如提取fc7等
LEVELDB=./examples/_temp/features_conv1 # 保存的leveldb路径
BATCHSIZE=10
# args for LEVELDB to MAT
DIM=290400 # 需要手工计算feature长度
OUT=./examples/_temp/features_conv1.mat #.mat文件保存路径
BATCHNUM=1 # 有多少个batch, 本例只有两张图, 所以只有一个batch
$TOOL/extract_features.bin $MODEL $PROTOTXT $LAYER $LEVELDB $BATCHSIZE lmdb
python lmdb2mat.py $LEVELDB $BATCHNUM $BATCHSIZE $DIM $OUT
执行该文件
cd caffe
sh extract_feature_example.sh
执行完之后,会在_temp文件夹下生成features_conv1文件夹和features_conv1.mat文件
参考:
https://blog.csdn.net/jiandanjinxin/article/details/50410290
http://caffe.berkeleyvision.org/gathered/examples/feature_extraction.html
http://caffe.berkeleyvision.org/tutorial/interfaces.html