InfogainLoss layer
Question: I wish to use a loss layer of type
[`InfogainLoss`](http://caffe.berkeleyvision.org/doxygen/classcaffe_1_1InfogainLossLayer.html#details)
in my model. But I am having difficulties defining it properly.

  1. Is there any tutorial/example on the usage of `INFOGAIN_LOSS` layer?

  2. Should the input to this layer, the class probabilities, be the output of a `SOFTMAX` layer, or is it enough to input the "top" of a fully connected layer?

`INFOGAIN_LOSS` requires three inputs: class probabilities, labels and the
matrix `H`. The matrix `H` can be provided either as a layer parameters
`infogain_loss_param { source: "fiename" }`.  
Suppose I have a python script that computes `H` as a `numpy.array` of shape
`(L,L)` with `dtype='f4'` (where `L` is the number of labels in my model).

  3. How can I convert my `numpy.array` into a `binproto` file that can be provided as a `infogain_loss_param { source }` to the model?

  4. Suppose I want `H` to be provided as the third input (bottom) to the loss layer (rather than as a model parameter). How can I do this?  
Do I define a new data layer which "top" is `H`? If so, wouldn't the data of
this layer be incremented every training iteration like the training data is
incremented? How can I define multiple unrelated input "data" layers, and how
does caffe know to read from the training/testing "data" layer batch after
batch, while from the `H` "data" layer it knows to read only once for all the
training process?


Answer: I still do not have a full answer to my question. This answer only covers my
third and fourth parts:  
_3\. How can I convert an numpy.array into a binproto file_ :

In python

    
    
    H = np.eye( L, dtype = 'f4' ) 
    import caffe
    blob = caffe.io.array_to_blobproto( H.reshape( (1,1,L,L) ) )
    with open( 'infogainH.binaryproto', 'wb' ) as f :
        f.write( blob.SerializeToString() )
    

Now you can add to the model prototext the `INFOGAIN_LOSS` layer with `H` as a
parameter:

    
    
    layer {
      bottom: "topOfPrevLayer"
      bottom: "label"
      top: "infoGainLoss"
      name: "infoGainLoss"
      type: "InfogainLoss"
      infogain_loss_param {
        source: "infogainH.binaryproto"
      }
    }
    

* * *

_4\. How to load`H` as part of a DATA layer_

Quoting [Evan Shelhamer's post](https://github.com/BVLC/caffe/issues/1640):

> There's no way at present to make data layers load input at different rates.
> Every forward pass all data layers will advance. However, the constant H
> input could be done by making an input lmdb / leveldb / hdf5 file that is
> only H since the data layer will loop and keep loading the same H. This
> obviously wastes disk IO.

* * *

As for the first two parts of my question:  
_1\. Is there any tutorial/example on the usage of**InfogainLoss** layer?_:  
A nice example can be found
[here](http://stackoverflow.com/questions/30486033/tackling-class-imbalance-
scaling-contribution-to-loss-and-sgd?lq=1): using **InfogainLoss** to tackle
class imbalance.

_2\. Should the input to this layer, the class probabilities, be the output of
a**Softmax** layer?_  
According to [Yair's answer](http://stackoverflow.com/a/30037614/1714410) the
answer is _YES_ it should be the output of **Softmax** layer (or any other
layer that makes sure the input values are in range [0..1]).

* * *

Recently, I noticed that using `"InfogainLoss"` on top of `"Softmax"` layer
can lead to numerical instability. Thus I suggest combining these two layers
into a single one (much like `"SoftmaxWithLoss"` layer). The mathematics of
this combined layer are given
[here](http://stackoverflow.com/a/34917052/1714410). An implementation of this
"combined" infogainLoss + Softmax can be found in [this pull
request](https://github.com/BVLC/caffe/pull/3855).

