3
$\begingroup$

I am following the documentation in the page https://reference.wolfram.com/language/ref/NetModel.html.

I am getting error when I try to execute the code given for attaching NetDecoder for a given model.

NetModel["LeNet", "Output" -> NetDecoder[{"Class", {"cat", "dog"}}]]

Output

NetReplacePart::invspdec: NetDecoder[{"Class", \[Ellipsis]}] taking a length-2 vector of real numbers, cannot be attached to port Output, which produces a length-10 vector of real numbers.

Can someone explain me what is wrong here?

$\endgroup$
5
$\begingroup$

The simplest way I can find to replace the output decoder is by copying over the net up to the last Ramp layer and then adding the rest back in manually:

net = NetModel["LeNet"];
net = NetFlatten @ NetChain[
   { NetTake[net, 9], (* the Ramp layer has index 9 *)
     LinearLayer[], SoftmaxLayer[]}, 
   "Output" -> NetDecoder[{"Class", {"cat", "dog"}}]
 ]
$\endgroup$
  • $\begingroup$ Yes, this is the way I'd normally do it as well. I wish NetReplace had a nice use-case here as well but it doesn't seem like it. $\endgroup$ – Carl Lange Oct 9 at 14:55
  • $\begingroup$ Thank you @Sjoerd Smit $\endgroup$ – Kr Sudharsan Oct 9 at 16:28
3
$\begingroup$

First and foremost, this example given by the documentation won't evaluate and (as far as I'm aware) never could have evaluated. You didn't do anything wrong here; it's a documentation bug. The following explains why it doesn't evaluate.

LeNet's "Output" port (before decoding) is a vector of reals of length 10 - in the case of LeNet, it outputs something approximating the probabilities that the input was a 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9.

LeNet has a NetDecoder by default, which we can look at with NetExtract[NetModel["LeNet"], "Output"].

enter image description here

This is also a "Class" NetDecoder, but unlike yours it has 10 labels. This means that the output from the network (remember, a length-10 vector of probabilities per class) can be mapped to this list of labels.

The NetDecoder that you've defined only has two labels ("cat" and "dog"), and so the decoder doesn't match up with the network output.

$\endgroup$
  • $\begingroup$ In all fairness to the OP, though, the line NetModel["LeNet", "Output" -> NetDecoder[{"Class", {"cat", "dog"}}]] is verbatim from the documentation of NetModel (3rd line in the Scope section). $\endgroup$ – Sjoerd Smit Oct 9 at 13:03
  • $\begingroup$ Totally agree, it's a bug in the documentation to have given an example that won't evaluate. $\endgroup$ – Carl Lange Oct 9 at 13:08
  • $\begingroup$ @CarlLange, could you please tell how to change the number of labels in network? That would be helpful $\endgroup$ – Kr Sudharsan Oct 9 at 13:11
  • $\begingroup$ @KrSudharsan Sorry, I missed this; Sjoerd's answer is exactly what I would have added. $\endgroup$ – Carl Lange Oct 9 at 15:32
1
$\begingroup$

Thanks for spotting the documentation error and the limitation of NetReplacePart.

Good news for the future: NetReplacePart will be improved in the next version.

In 12.1, it will be possible to write:

NetReplacePart[NetModel["LeNet"],
   {10 -> LinearLayer[], "Output" -> NetDecoder[{"Class", {"cat", "dog"}}]}
]

(replacing the layer(s) that need to be "reshaped", additionally to the output)

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.