set -e
if [ ! -n "$1" ] ;then
echo "\$1 is empty, default is 0"
gpu=0
else
echo "use $1-th gpu"
gpu=$1
fi
#base_model=caffenet
base_model=vgg_reduce
#base_model=googlenet
#base_model=res50
feature_name=fc7
#feature_name=pool5/7x7_s1
#feature_name=pool5
model_file=./models/market1501/$base_model/snapshot/${base_model}.full_iter_18000.caffemodel
python examples/market1501/testing/extract_feature.py \
examples/market1501/lists/test.lst \
examples/market1501/datamat/test.lst.fc7.mat \
examples/market1501/datamat/test.lst.score.mat \
--gpu $gpu \
--model_def ./models/market1501/$base_model/dev.proto \
--feature_name $feature_name \
--pretrained_model $model_file \
--mean_value 97.8286,99.0468,105.606
python examples/market1501/testing/extract_feature.py \
examples/market1501/lists/query.lst \
examples/market1501/datamat/query.lst.fc7.mat \
examples/market1501/datamat/query.lst.score.mat \
--gpu $gpu \
--model_def ./models/market1501/$base_model/dev.proto \
--feature_name $feature_name \
--pretrained_model $model_file \
--mean_value 97.8286,99.0468,105.606
extract_feature.py
内容如下:
import numpy as np
import os
import sys
import argparse
import glob
import time
import _init_paths
from units import SClassifier
import caffe
import scipy.io as sio
def load_txt(xfile):
img_files = []
labels = []
for line in open(xfile):
line = line.strip('\n').split(' ')
assert(len(line) == 2)
img_files.append(line[0])
labels.append(int(float(line[1])))
return img_files, labels
def main(argv):·
parser = argparse.ArgumentParser()
# Required arguments: input and output files.
#由于没有设置default,因此这些参数在命令行中是必须的,否则会报错
parser.add_argument(
"input_file",
help="Input image, directory"
)
parser.add_argument(
"feature_file",
help="Feature mat filename."
)
parser.add_argument(
"score_file",
help="Score Output mat filename."
)
# Optional arguments.
# 由于设置了default,因此这些参数在命令行中是可选的
parser.add_argument(
"--model_def",
default=os.path.join(
"./models/market1501/caffenet/feature.proto"),
help="Model definition file."
)
parser.add_argument(
"--pretrained_model",
default=os.path.join(
"./models/market1501/caffenet/caffenet_iter_17000.caffemodel"),
help="Trained model weights file."
)
parser.add_argument(
"--gpu",
type=int,
default=-1,
help="Switch for gpu computation."
)
parser.add_argument(
//action='store_true'的意思是说,如果脚本有传递--center_only的参数则将该值center_only取值为true
//由于脚本没有传递center_only,则其值为false
"--center_only",
action='store_true',
help="Switch for prediction from center crop alone instead of " +
"averaging predictions across crops (default)."
)
parser.add_argument(
"--images_dim",
default='256,256',
help="Canonical 'height,width' dimensions of input images."
)
parser.add_argument(
"--mean_value",
default=os.path.join(
'examples/market1501/market1501_mean.binaryproto'),
help="Data set image mean of [Channels x Height x Width] dimensions " +
"(numpy array). Set to '' for no mean subtraction."
)
parser.add_argument(
"--input_scale",
type=float,
help="Multiply input features by this scale to finish preprocessing."
)
parser.add_argument(
"--raw_scale",
type=float,
default=255.0,
help="Multiply raw input by this scale before preprocessing."
)
parser.add_argument(
"--channel_swap",
default='2,1,0',
help="Order to permute input channels. The default converts " +
"RGB -> BGR since BGR is the Caffe default by way of OpenCV."
)
parser.add_argument(
"--ext",
default='jpg',
help="Image file extension to take as input when a directory " +
"is given as the input file."
)
parser.add_argument(
"--feature_name",
default="fc7",
help="feature blob name."
)
parser.add_argument(
"--score_name",
default="prediction",
help="prediction score blob name."
)
args = parser.parse_args()
//image_dims = [256,256]
image_dims = [int(s) for s in args.images_dim.split(',')]
channel_swap=[2,1,0]
channel_swap = None
if args.channel_swap:
channel_swap = [int(s) for s in args.channel_swap.split(',')]
mean_value= [97.8,99.0,105.6]
mean_value = None
if args.mean_value:
mean_value = [float(s) for s in args.mean_value.split(',')]
mean_value = np.array(mean_value)
if args.gpu >= 0:
caffe.set_mode_gpu()
caffe.set_device(args.gpu)
print("GPU mode, device : {}".format(args.gpu))
else:
caffe.set_mode_cpu()
print("CPU mode")
//这句话的意思是根据训练好的模型,使用dev.proto前向一遍,得到分类的结果
//同时,前向网络也计算了fc7,这正是我们需要的特征
--model_def = ./models/market1501/caffenet/dev.proto
args.pretrained_model在命令行中存在
input_scale为空,无默认值
raw_scale=255
channel_swap=[2,1,0]
# Make classifier.
classifier = SClassifier(args.model_def, args.pretrained_model,
image_dims=image_dims, mean_value=mean_value,
input_scale=args.input_scale, raw_scale=args.raw_scale,
channel_swap=channel_swap)
# Load numpy, directory glob (*.jpg), or image file.
//将符号路径扩展成完整路径
args.input_file = os.path.expanduser(args.input_file)
//args.ext='jpg'
//args.input_file以lst结尾
if args.input_file.endswith(args.ext):
print("Loading file: %s" % args.input_file)
inputs = [caffe.io.load_image(args.input_file)]
labels = [-1]
//lst也不是文件夹
elif os.path.isdir(args.input_file):
print("Loading folder: %s" % args.input_file)
inputs =[caffe.io.load_image(im_f)
for im_f in glob.glob(args.input_file + '/*.' + args.ext)]
labels = [-1 for _ in xrange(len(inputs))]
else:
## Image List Files
print("Loading file: %s" % args.input_file)
//按列读取
img_files, labels = load_txt(args.input_file)
//对于lst中的每一个地址,就读取一次,放入到input中
inputs = [caffe.io.load_image(im_f)
for im_f in img_files]
print("Classifying %d inputs." % len(inputs))
# Classify.
ok = 0.0
save_feature = None
save_score = None
//由于脚本没有传递center_only,则其值为false
for idx, _input in enumerate(inputs):
start = time.time()
//_input是每一张图,后面的参数说明是否要对图像进行crop
//本例中是对图像进行了crop,四个角+一个中心,水平翻转之后再来一次,总计10张。否则我们仅仅需要中心的那张就可以
//返回的是一张N*C的numpy.ndarry,代表每张图片有可能对应的C个类别
_ = classifier.predict([_input], not args.center_only)
//提取fc7层的特征
feature = classifier.get_blob_data(args.feature_name)
//获取使用softmax后的结果
score = classifier.get_blob_data(args.score_name)
//都是一维的数据
assert (feature.shape[0] == 1 and score.shape[0] == 1)
feature_shape = feature.shape
score_shape = score.shape
//打印结果
if save_feature is None:
args.feature_name feature fc7 feature_shape(1,4096)
print('feature : {} : {}'.format(args.feature_name, feature_shape))
save_feature = np.zeros((len(inputs), feature.size),dtype=np.float32)
save_feature[idx, :] = feature.reshape(1, feature.size)
if save_score is None:
args.score_name score prediction (1,751)
print('score : {} : {}'.format(args.score_name, score_shape))
save_score = np.zeros((len(inputs), score.size),dtype=np.float32)
save_score[idx, :] = score.reshape(1, score.size)
//找到得分中最大的一项
mx_idx = np.argmax(score.view())
ok = ok + int(int(mx_idx) == int(labels[idx]))
print("{:5d} / {:5d} images predict done in {:.2f} s. [PRED: {:3d}] vs [OK: {:3d}] accuracy: {:.4f} = good: {:5d} bad: {:5d}".format( \
idx+1, len(inputs), time.time() - start, mx_idx, labels[idx], ok/(idx+1), int(ok), idx+1-int(ok)))
# Save
if (args.feature_file):
print("Saving feature into %s" % args.feature_file)
sio.savemat(args.feature_file, {'feature':save_feature})
else:
print("Without saving feature")
if (args.score_file):
print("Saving score into %s" % args.score_file)
sio.savemat(args.score_file, {'feature':save_score})
else:
print("Without saving score")
if __name__ == '__main__':
main(sys.argv)