-
Notifications
You must be signed in to change notification settings - Fork 9
/
sample.py
149 lines (127 loc) · 5.55 KB
/
sample.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import numpy as np
import skimage
caffe_root = 'PATH_TO_CAFFE'
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe
class NetWrap(caffe.Net):
"""
NetWrap extends Net for image class prediction
by scaling, center cropping, or oversampling.
Parameters
----------
image_dims : dimensions to scale input for cropping/sampling.
Default is to scale to net input size for whole-image crop.
mean_file: path to the binaryproto file
input_scale: not implemented
raw_scale: typically 255
channel_swap: should be BGR (2, 1, 0)
"""
def __init__(self, model_file, pretrained_file, image_dims=None,
mean_file=None, input_scale=None, raw_scale=None,
channel_swap=None):
caffe.Net.__init__(self, model_file, pretrained_file, caffe.TEST)
# configure pre-processing
in_ = self.inputs[0]
if mean_file is not None:
blob = caffe.proto.caffe_pb2.BlobProto()
data = open( mean_file , 'rb' ).read()
blob.ParseFromString(data)
# Transform from K x H x W to H x W x K
self.mean_array = np.array(caffe.io.blobproto_to_array(blob))[0].transpose((1, 2, 0))
if input_scale is not None:
self.input_scale = input_scale
if raw_scale is not None:
self.raw_scale = raw_scale
if channel_swap is not None:
self.channel_swap = channel_swap
self.crop_dims = np.array(self.blobs[in_].data.shape[2:])
if not image_dims:
image_dims = self.crop_dims
self.image_dims = image_dims
def predict(self, inputs, oversample=True):
"""
Predict classification probabilities of inputs.
Parameters
----------
inputs : iterable of (H x W x K) input ndarrays.
oversample : boolean
average predictions across center, corners, and mirrors
when True (default). Center-only prediction when False.
Returns
-------
predictions: (N x C) ndarray of class probabilities for N images and C
classes.
"""
# Scale to standardize input dimensions.
input_ = np.zeros((len(inputs),
self.image_dims[0],
self.image_dims[1],
inputs[0].shape[2]),
dtype=np.float32)
for ix, in_ in enumerate(inputs):
#input_[ix] = caffe.io.resize_image(in_, self.image_dims)
input_[ix] = (skimage.transform.resize(in_, self.image_dims) * self.raw_scale)\
[:, :, self.channel_swap] - self.mean_array
if oversample:
# Generate center, corner, and mirrored crops.
input_ = caffe.io.oversample(input_, self.crop_dims)
else:
# Take center crop.
center = np.array(self.image_dims) / 2.0
crop = np.tile(center, (1, 2))[0] + np.concatenate([
-self.crop_dims / 2.0,
self.crop_dims / 2.0
])
input_ = input_[:, crop[0]:crop[2], crop[1]:crop[3], :]
# Classify
caffe_in = np.zeros(np.array(input_.shape)[[0, 3, 1, 2]],
dtype=np.float32)
for ix, in_ in enumerate(input_):
caffe_in[ix] = in_.transpose((2, 0, 1))
# caffe_in[ix] = self.transformer.preprocess(self.inputs[0], in_)
out = self.forward_all(**{self.inputs[0]: caffe_in})
predictions = self.blobs["prob"].data
# For oversampling, average predictions across crops.
if oversample:
predictions = predictions.reshape((len(predictions) / 10, 10, -1))
predictions = predictions.mean(1)
return predictions
def feature_extraction(self, inputs, layer):
# Scale to standardize input dimensions.
input_ = np.zeros((len(inputs),
self.image_dims[0],
self.image_dims[1],
inputs[0].shape[2]),
dtype=np.float32)
for ix, in_ in enumerate(inputs):
#input_[ix] = caffe.io.resize_image(in_, self.image_dims)
input_[ix] = (skimage.transform.resize(in_, self.image_dims) * self.raw_scale)\
[:, :, self.channel_swap] - self.mean_array
# Take center crop.
center = np.array(self.image_dims) / 2.0
crop = np.tile(center, (1, 2))[0] + np.concatenate([
-self.crop_dims / 2.0,
self.crop_dims / 2.0
])
input_ = input_[:, crop[0]:crop[2], crop[1]:crop[3], :]
# Classify
caffe_in = np.zeros(np.array(input_.shape)[[0, 3, 1, 2]],
dtype=np.float32)
for ix, in_ in enumerate(input_):
caffe_in[ix] = in_.transpose((2, 0, 1))
# caffe_in[ix] = self.transformer.preprocess(self.inputs[0], in_)
out = self.forward_all(**{self.inputs[0]: caffe_in})
return self.blobs[layer].data
MODEL_PREFIX = "PATH_TO_MODEL_FOLDER"
WEIGHT_FILE = MODEL_PREFIX + "siamese_vgg_food_train_iter_100000.caffemodel"
DEPLOY_FILE = MODEL_PREFIX + "deploy.prototxt"
MEAN_FILE = MODEL_PREFIX + "food_mean.binaryproto"
net_feature = NetWrap(model_file=DEPLOY_FILE,
pretrained_file=WEIGHT_FILE,
image_dims=(256, 256),
mean_file=MEAN_FILE,
raw_scale=255,
channel_swap=(2, 1, 0))
# Sample for feature extraction
# feature = net_feature.feature_extraction([image_data], "feature")[0].copy()