Caffe
C++ programming
machine learning
neural networks
multi-input models

Modifying the Caffe C prediction code for multiple inputs

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Caffe prediction examples are usually written for a network with one input blob, often called data. If your trained model expects multiple input blobs, the prediction code has to change in two places: the network definition must expose all required inputs, and the C++ inference path must load each blob with the correct shape and ordering.

Verify the Network Really Has Multiple Inputs

Before changing C++ code, confirm that the model architecture actually expects more than one input. In Caffe, that usually means your deploy prototxt contains multiple Input definitions or a graph where several input blobs feed downstream layers.

A minimal deploy file can look like this:

protobuf
1input: "image"
2input_shape { dim: 1 dim: 3 dim: 224 dim: 224 }
3
4input: "metadata"
5input_shape { dim: 1 dim: 10 dim: 1 dim: 1 }

If the deploy file only defines one input, adding loops in C++ will not help. The network itself must be trained and exported with multiple inputs.

Inspect the Input Blobs in C++

When a caffe::Net<float> is loaded, you can query all input blobs instead of assuming there is exactly one.

cpp
1#include <caffe/caffe.hpp>
2#include <iostream>
3
4int main() {
5    caffe::Caffe::set_mode(caffe::Caffe::CPU);
6    caffe::Net<float> net("deploy.prototxt", caffe::TEST);
7    net.CopyTrainedLayersFrom("weights.caffemodel");
8
9    const auto& input_blobs = net.input_blobs();
10    std::cout << "Input blob count: " << input_blobs.size() << std::endl;
11
12    for (int i = 0; i < input_blobs.size(); ++i) {
13        std::cout << i << ": " << input_blobs[i]->shape_string() << std::endl;
14    }
15}

This is the first sanity check. If you expect two inputs and the program reports one, the model definition is still wrong.

Fill Each Blob Explicitly

The typical single-input example wraps only input_blobs[0]. For a multi-input model, assign each input blob separately and copy data into the correct memory region.

cpp
1#include <caffe/caffe.hpp>
2#include <vector>
3
4void copyVectorToBlob(const std::vector<float>& values, caffe::Blob<float>* blob) {
5    CHECK_EQ(values.size(), blob->count());
6    float* dst = blob->mutable_cpu_data();
7    std::copy(values.begin(), values.end(), dst);
8}
9
10int main() {
11    caffe::Caffe::set_mode(caffe::Caffe::CPU);
12    caffe::Net<float> net("deploy.prototxt", caffe::TEST);
13    net.CopyTrainedLayersFrom("weights.caffemodel");
14
15    auto* image_blob = net.input_blobs()[0];
16    auto* metadata_blob = net.input_blobs()[1];
17
18    std::vector<float> image(image_blob->count(), 0.5f);
19    std::vector<float> metadata(metadata_blob->count(), 1.0f);
20
21    copyVectorToBlob(image, image_blob);
22    copyVectorToBlob(metadata, metadata_blob);
23
24    net.Forward();
25}

This example uses placeholder data, but the structure is correct: each blob is addressed independently, sized correctly, and populated before Forward().

Keep Preprocessing Separate Per Input

Multiple inputs often represent different data modalities. One input may be an RGB image, another a feature vector, and another a mask. They should not share the same preprocessing code unless the shapes and semantics are identical.

For example:

  • image input may need resize, channel reordering, and mean subtraction
  • metadata input may need normalization using training-set statistics
  • sequence input may need padding or truncation

If you hide all of that behind one generic helper, inference bugs become harder to spot. Use one preparation function per input type.

cpp
1std::vector<float> normalizeMetadata(const std::vector<float>& raw) {
2    std::vector<float> result = raw;
3    for (float& value : result) {
4        value /= 100.0f;
5    }
6    return result;
7}

That keeps model assumptions visible in code.

Validate Input Order and Shape Carefully

A multi-input inference bug is often not a crash. It is a silent prediction error caused by loading the right data into the wrong blob. To avoid that, validate both blob names and shapes.

If the network uses named blobs, inspect them during initialization and map your application inputs explicitly. Do not rely only on index position unless the model interface is tightly controlled.

It is also worth running one known test case from training or validation through the C++ program and comparing the prediction with a trusted reference pipeline.

Common Pitfalls

  • Modifying the C++ loop while forgetting to export a deploy model that actually has multiple inputs.
  • Assuming all inputs share the same preprocessing steps.
  • Filling blobs by index without checking whether the order matches the deploy definition.
  • Ignoring shape mismatches until Forward() fails or predictions become nonsensical.
  • Testing only with random input, which hides data-ordering mistakes.

Summary

  • Multi-input inference in Caffe starts with a deploy model that defines multiple input blobs.
  • Inspect net.input_blobs() instead of assuming a single data input.
  • Copy data into each blob explicitly and keep preprocessing logic separate per input type.
  • Validate blob order, names, and shapes before trusting predictions.
  • Compare against a known-good reference example to catch silent mapping errors.

Course illustration
Course illustration

All Rights Reserved.