# Bug when importing Neural Nets from .m files in a fresh kernel

Bug introduced in 11.0.0 and fixed in 11.0.1

Importing Neural Nets from .m files seems to destroy the neural net.

net = NetInitialize @ DotPlusLayer[3, "Input" -> 5];
Export["net.m", net]


Importing the .m file right after exporting it does not have any issues. However, when you start a fresh kernel and Import it:

Import["net.m"]


There is the following error:

TensorT::shdw: Symbol TensorT appears in multiple contexts {NeuralNetworks,Global}; definitions in context NeuralNetworks may shadow or be shadowed by other definitions.

... and a nonfunctional neural net as the output.

To note, TensorT is not a global variable (running ?TensorT in a new session gives a Information::notfound error).

Importing the file again or running a random NeuralNetworks code before Importing solve the problem.

• Did you report this to support? – Szabolcs Aug 23 '16 at 7:20
• @Szabolcs Not yet. – JungHwan Min Aug 24 '16 at 2:09

It appears that now the NeuralNetworks context is public. However, it is not actually populated until some neural net function is used. Observe:

I do wonder if all these symbols are actually meant to be in a public context ...

When you import net.m in a fresh kernel, the symbol NeuralNetworksTensorT has not yet been created. Thus when the kernel reads TensorT (without an explicitly specified context), it creates GlobalTensorT and not NeuralNetworksTensorT. At the same time, DotPlusLayer is also read from net.m. This triggers the loading of all the symbols in NeuralNetworks, but not before GlobalTensorT has been created. So we end up with TensorT in the wrong context in your expression, and a symbol shadowing situation.

This smells like a bug to me.

The simplest workaround is to trigger loading of the neural net stuff by evaluating something like DotPlusLayer (with no arguments) right after kernel startup.

Another, more complicated workaround is the following:

In[1]:= DotPlusLayer;


Now remove NeuralNetworks form the context path.

In[2]:= $ContextPath = DeleteCases[$ContextPath, "NeuralNetworks"]


net = NetInitialize@DotPlusLayer[3, "Input" -> 5];
ExportString[net, "Package"]

"(* Created with the Wolfram Language : www.wolfram.com *)
\
DotPlusLayer[<|\"Type\" -> \"DotPlus\",
\"Arrays\" -> <|\"Weights\" -> RawArray[\"Real32\", \
{{-0.5826271176338196,
0.7301018238067627, 0.6151853203773499, 0.7818413376808167,
-0.679416835308075}, {-0.03140471875667572, 0.6534066796302795, \

-0.16610436141490936, 0.004304547794163227, 0.8150935173034668},
{0.04995853826403618, -0.6442268490791321, 0.5564413070678711,
-0.22295577824115753, 0.6135303974151611}}],
\"Biases\" -> RawArray[\"Real32\", {0., 0., 0.}]|>,
\"Parameters\" -> <|\"Size\" -> 3, \"\$InputSize\" -> 5|>,
\"Inputs\" -> <|\"Input\" -> NeuralNetworksTensorT[1, {5}]|>,
\"Outputs\" -> <|\"Output\" -> NeuralNetworksTensorT[1, {3}]|>|>]
"


Notice that now the context is prepended to TensorT upon export.

To sum up, my suspicion is that the bug is that the NeuralNetworks context is made public. It shouldn't be in the context path at all. If it is in the context path on purpose (not as an oversight), then symbols such as TensorT should exist already on kernel startup (perhaps as a Stub`).

• Correct, this is a bug. It's a quirk in PacletManager that I can work around. Fixed, will be corrected in 11.0.1. – Taliesin Beynon Aug 24 '16 at 16:53