forked from BVLC/caffe
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request BVLC#161 from kloudkl/simplify_feature_extraction
Feature extraction, feature binarization and image retrieval examples
- Loading branch information
Showing
9 changed files
with
562 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
layout: default | ||
title: Caffe | ||
--- | ||
|
||
Extracting Features Using Pre-trained Model | ||
=========================================== | ||
|
||
CAFFE represents Convolution Architecture For Feature Extraction. Extracting features using pre-trained model is one of the strongest requirements users ask for. | ||
|
||
Because of the record-breaking image classification accuracy and the flexible domain adaptability of [the network architecture proposed by Krizhevsky, Sutskever, and Hinton](http://books.nips.cc/papers/files/nips25/NIPS2012_0534.pdf), Caffe provides a pre-trained reference image model to save you from days of training. | ||
|
||
If you need detailed usage help information of the involved tools, please read the source code of them which provide everything you need to know about. | ||
|
||
Get the Reference Model | ||
----------------------- | ||
|
||
Assume you are in the root directory of Caffe. | ||
|
||
cd models | ||
./get_caffe_reference_imagenet_model.sh | ||
|
||
After the downloading is finished, you will have models/caffe_reference_imagenet_model. | ||
|
||
Preprocess the Data | ||
------------------- | ||
|
||
Generate a list of the files to process. | ||
|
||
examples/feature_extraction/generate_file_list.py /your/images/dir /your/images.txt | ||
|
||
The network definition of the reference model only accepts 256*256 pixel images stored in the leveldb format. First, resize your images if they do not match the required size. | ||
|
||
build/tools/resize_and_crop_images.py --num_clients=8 --image_lib=opencv --output_side_length=256 --input=/your/images.txt --input_folder=/your/images/dir --output_folder=/your/resized/images/dir_256_256 | ||
|
||
Set the num_clients to be the number of CPU cores on your machine. Run "nproc" or "cat /proc/cpuinfo | grep processor | wc -l" to get the number on Linux. | ||
|
||
build/tools/generate_file_list.py /your/resized/images/dir_256_256 /your/resized/images_256_256.txt | ||
build/tools/convert_imageset /your/resized/images/dir_256_256 /your/resized/images_256_256.txt /your/resized/images_256_256_leveldb 1 | ||
|
||
In practice, subtracting the mean image from a dataset significantly improves classification accuracies. Download the mean image of the ILSVRC dataset. | ||
|
||
data/ilsvrc12/get_ilsvrc_aux.sh | ||
|
||
You can directly use the imagenet_mean.binaryproto in the network definition proto. If you have a large number of images, you can also compute the mean of all the images. | ||
|
||
build/tools/compute_image_mean.bin /your/resized/images_256_256_leveldb /your/resized/images_256_256_mean.binaryproto | ||
|
||
Define the Feature Extraction Network Architecture | ||
-------------------------------------------------- | ||
|
||
If you do not want to change the reference model network architecture , simply copy examples/imagenet into examples/your_own_dir. Then point the source and meanfile field of the data layer in imagenet_val.prototxt to /your/resized/images_256_256_leveldb and /your/resized/images_256_256_mean.binaryproto respectively. | ||
|
||
Extract Features | ||
---------------- | ||
|
||
Now everything necessary is in place. | ||
|
||
build/tools/extract_features.bin models/caffe_reference_imagenet_model examples/feature_extraction/imagenet_val.prototxt fc7 examples/feature_extraction/features 10 | ||
|
||
The name of feature blob that you extract is fc7 which represents the highest level feature of the reference model. Any other blob is also applicable. The last parameter above is the number of data mini-batches. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/usr/bin/env python | ||
import os | ||
import sys | ||
|
||
def help(): | ||
print 'Usage: ./generate_file_list.py file_dir file_list.txt' | ||
exit(1) | ||
|
||
def main(): | ||
if len(sys.argv) < 3: | ||
help() | ||
file_dir = sys.argv[1] | ||
file_list_txt = sys.argv[2] | ||
if not os.path.exists(file_dir): | ||
print 'Error: file dir does not exist ', file_dir | ||
exit(1) | ||
file_dir = os.path.abspath(file_dir) + '/' | ||
with open(file_list_txt, 'w') as output: | ||
for root, dirs, files in os.walk(file_dir): | ||
for name in files: | ||
file_path = file_path.replace(os.path.join(root, name), '') | ||
output.write(file_path + '\n') | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2014 kloudkl@github | ||
|
||
#include <stdint.h> // for uint32_t & uint64_t | ||
|
||
#include "gtest/gtest.h" | ||
#include "caffe/blob.hpp" | ||
#include "caffe/common.hpp" | ||
#include "caffe/filler.hpp" | ||
#include "caffe/util/math_functions.hpp" | ||
|
||
#include "caffe/test/test_caffe_main.hpp" | ||
|
||
namespace caffe { | ||
|
||
template<typename Dtype> | ||
class MathFunctionsTest : public ::testing::Test { | ||
protected: | ||
MathFunctionsTest() | ||
: blob_bottom_(new Blob<Dtype>()), | ||
blob_top_(new Blob<Dtype>()) { | ||
} | ||
|
||
virtual void SetUp() { | ||
Caffe::set_random_seed(1701); | ||
this->blob_bottom_->Reshape(100, 70, 50, 30); | ||
this->blob_top_->Reshape(100, 70, 50, 30); | ||
// fill the values | ||
FillerParameter filler_param; | ||
GaussianFiller<Dtype> filler(filler_param); | ||
filler.Fill(this->blob_bottom_); | ||
filler.Fill(this->blob_top_); | ||
} | ||
|
||
virtual ~MathFunctionsTest() { | ||
delete blob_bottom_; | ||
delete blob_top_; | ||
} | ||
// http://en.wikipedia.org/wiki/Hamming_distance | ||
int ReferenceHammingDistance(const int n, const Dtype* x, const Dtype* y); | ||
|
||
Blob<Dtype>* const blob_bottom_; | ||
Blob<Dtype>* const blob_top_; | ||
}; | ||
|
||
#define REF_HAMMING_DIST(float_type, int_type) \ | ||
template<> \ | ||
int MathFunctionsTest<float_type>::ReferenceHammingDistance(const int n, \ | ||
const float_type* x, \ | ||
const float_type* y) { \ | ||
int dist = 0; \ | ||
int_type val; \ | ||
for (int i = 0; i < n; ++i) { \ | ||
val = static_cast<int_type>(x[i]) ^ static_cast<int_type>(y[i]); \ | ||
/* Count the number of set bits */ \ | ||
while (val) { \ | ||
++dist; \ | ||
val &= val - 1; \ | ||
} \ | ||
} \ | ||
return dist; \ | ||
} | ||
|
||
REF_HAMMING_DIST(float, uint32_t); | ||
REF_HAMMING_DIST(double, uint64_t); | ||
|
||
typedef ::testing::Types<float, double> Dtypes; | ||
TYPED_TEST_CASE(MathFunctionsTest, Dtypes); | ||
|
||
TYPED_TEST(MathFunctionsTest, TestHammingDistance) { | ||
int n = this->blob_bottom_->count(); | ||
const TypeParam* x = this->blob_bottom_->cpu_data(); | ||
const TypeParam* y = this->blob_top_->cpu_data(); | ||
CHECK_EQ(this->ReferenceHammingDistance(n, x, y), | ||
caffe_hamming_distance<TypeParam>(n, x, y)); | ||
} | ||
|
||
} // namespace caffe |
Oops, something went wrong.