summaryrefslogtreecommitdiff
path: root/matlab
diff options
context:
space:
mode:
authorSergio Guadarrama <sguada@gmail.com>2014-03-31 14:39:16 -0700
committerSergio Guadarrama <sguada@gmail.com>2014-03-31 14:39:16 -0700
commitc8249e7f880297976ff3faade106620b4e968206 (patch)
treeb89af3f70af1c255750b4739b7ed3f79316da19f /matlab
parent0edff71a0117ae93cb0708f2d1eefa76debc542d (diff)
downloadcaffe-c8249e7f880297976ff3faade106620b4e968206.tar.gz
caffe-c8249e7f880297976ff3faade106620b4e968206.tar.bz2
caffe-c8249e7f880297976ff3faade106620b4e968206.zip
Changed Copyright to BVLC
Diffstat (limited to 'matlab')
-rw-r--r--matlab/caffe/matcaffe.cpp69
-rw-r--r--matlab/caffe/matcaffe_demo.m4
2 files changed, 66 insertions, 7 deletions
diff --git a/matlab/caffe/matcaffe.cpp b/matlab/caffe/matcaffe.cpp
index c3482eda..7c4b338d 100644
--- a/matlab/caffe/matcaffe.cpp
+++ b/matlab/caffe/matcaffe.cpp
@@ -1,4 +1,3 @@
-<<<<<<< HEAD
// Copyright 2014 BVLC and contributors.
//
// matcaffe.cpp provides a wrapper of the caffe::Net class as well as some
@@ -94,11 +93,63 @@ static mxArray* do_forward(const mxArray* const bottom) {
return mx_out;
}
+static mxArray* do_backward(const mxArray* const top_diff) {
+ vector<Blob<float>*>& output_blobs = net_->output_blobs();
+ vector<Blob<float>*>& input_blobs = net_->input_blobs();
+ CHECK_EQ(static_cast<unsigned int>(mxGetDimensions(top_diff)[0]),
+ output_blobs.size());
+ // First, copy the output diff
+ for (unsigned int i = 0; i < output_blobs.size(); ++i) {
+ const mxArray* const elem = mxGetCell(top_diff, i);
+ const float* const data_ptr =
+ reinterpret_cast<const float* const>(mxGetPr(elem));
+ switch (Caffe::mode()) {
+ case Caffe::CPU:
+ memcpy(output_blobs[i]->mutable_cpu_diff(), data_ptr,
+ sizeof(float) * output_blobs[i]->count());
+ break;
+ case Caffe::GPU:
+ cudaMemcpy(output_blobs[i]->mutable_gpu_diff(), data_ptr,
+ sizeof(float) * output_blobs[i]->count(), cudaMemcpyHostToDevice);
+ break;
+ default:
+ LOG(FATAL) << "Unknown Caffe mode.";
+ } // switch (Caffe::mode())
+ }
+ //LOG(INFO) << "Start";
+ net_->Backward();
+ //LOG(INFO) << "End";
+ mxArray* mx_out = mxCreateCellMatrix(input_blobs.size(), 1);
+ for (unsigned int i = 0; i < input_blobs.size(); ++i) {
+ // internally data is stored as (width, height, channels, num)
+ // where width is the fastest dimension
+ mwSize dims[4] = {input_blobs[i]->width(), input_blobs[i]->height(),
+ input_blobs[i]->channels(), input_blobs[i]->num()};
+ mxArray* mx_blob = mxCreateNumericArray(4, dims, mxSINGLE_CLASS, mxREAL);
+ mxSetCell(mx_out, i, mx_blob);
+ float* data_ptr = reinterpret_cast<float*>(mxGetPr(mx_blob));
+ switch (Caffe::mode()) {
+ case Caffe::CPU:
+ memcpy(data_ptr, input_blobs[i]->cpu_diff(),
+ sizeof(float) * input_blobs[i]->count());
+ break;
+ case Caffe::GPU:
+ cudaMemcpy(data_ptr, input_blobs[i]->gpu_diff(),
+ sizeof(float) * input_blobs[i]->count(), cudaMemcpyDeviceToHost);
+ break;
+ default:
+ LOG(FATAL) << "Unknown Caffe mode.";
+ } // switch (Caffe::mode())
+ }
+
+ return mx_out;
+}
+
static mxArray* do_get_weights() {
const vector<shared_ptr<Layer<float> > >& layers = net_->layers();
const vector<string>& layer_names = net_->layer_names();
- // Step 1: count the number of layers
+ // Step 1: count the number of layers with weights
int num_layers = 0;
{
string prev_layer_name = "";
@@ -237,10 +288,10 @@ static void end(MEX_ARGS){
if (net_) {
net_.reset();
init_key = -2;
- LOG(INFO) << "Network deleted, now it needs to init before used again";
+ LOG(INFO) << "Network reset, now it needs to init before used again";
}
-
}
+
static void forward(MEX_ARGS) {
if (nrhs != 1) {
LOG(ERROR) << "Only given " << nrhs << " arguments";
@@ -250,6 +301,15 @@ static void forward(MEX_ARGS) {
plhs[0] = do_forward(prhs[0]);
}
+static void backward(MEX_ARGS) {
+ if (nrhs != 1) {
+ LOG(ERROR) << "Only given " << nrhs << " arguments";
+ mexErrMsgTxt("Wrong number of arguments");
+ }
+
+ plhs[0] = do_backward(prhs[0]);
+}
+
static void is_initialized(MEX_ARGS) {
if (!net_) {
plhs[0] = mxCreateDoubleScalar(0);
@@ -269,6 +329,7 @@ struct handler_registry {
static handler_registry handlers[] = {
// Public API functions
{ "forward", forward },
+ { "backward", backward },
{ "init", init },
{ "is_initialized", is_initialized },
{ "set_mode_cpu", set_mode_cpu },
diff --git a/matlab/caffe/matcaffe_demo.m b/matlab/caffe/matcaffe_demo.m
index 1faeb4be..7d4e81b9 100644
--- a/matlab/caffe/matcaffe_demo.m
+++ b/matlab/caffe/matcaffe_demo.m
@@ -29,8 +29,6 @@ function [scores, layers] = matcaffe_demo(im, use_gpu)
% Data coming in from matlab needs to be in the order
% [width, height, channels, images]
% where width is the fastest dimension.
-% Data coming out from matcaffe is
-% [height, width, channels, images]
% Here is the rough matlab for putting image data into the correct
% format:
% % convert from uint8 to single
@@ -95,7 +93,7 @@ toc;
scores = scores{1};
size(scores)
scores = squeeze(scores);
-scores = mean(squeeze,2);
+scores = mean(scores,2);
% you can also get network weights by calling
if nargout == 2