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$

3 Answers 3

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$
2
  • $\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
    Commented Oct 9, 2019 at 14:55
  • $\begingroup$ Thank you @Sjoerd Smit $\endgroup$ Commented Oct 9, 2019 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$
4
  • $\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$ Commented Oct 9, 2019 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
    Commented Oct 9, 2019 at 13:08
  • $\begingroup$ @CarlLange, could you please tell how to change the number of labels in network? That would be helpful $\endgroup$ Commented Oct 9, 2019 at 13:11
  • $\begingroup$ @KrSudharsan Sorry, I missed this; Sjoerd's answer is exactly what I would have added. $\endgroup$
    – Carl Lange
    Commented Oct 9, 2019 at 15:32
2
$\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 and acknowledge you have read our privacy policy.

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