Mathematica Neural Networks based on MXNet
. And there is lots of model in MXNet(MXNet Model Zoo).
For example,I follow a tutorial An introduction to the MXNet API — part 4, It uses Inception v3(net using MXNet).
I can use this code to load this pretrained model
<< NeuralNetworks`;
net = ImportMXNetModel["F:\\model\\Inception-BN-symbol.json",
"F:\\model\\Inception-BN-0126.params"];
labels = Import["http://data.dmlc.ml/models/imagenet/synset.txt", "List"];
incepNet = NetChain[{ElementwiseLayer[#*255 &], net},
"Input" -> NetEncoder[{"Image", {224, 224}, ColorSpace -> "RGB"}],
"Output" -> NetDecoder[{"Class", labels}]]
TakeLargestBy[incepNet[Import["https://i.stack.imgur.com/893F0.jpg"],
"Probabilities"], Identity, 5]//Dataset
Dynamic@Column[{#, incepNet[#]} &@CurrentImage[]]
FileByteCount[Export["Inception v3.wlnet", incepNet]]/2^20.
(*44.0188 MB*)
I want to share this model to others, but it's too big (about 44 MB) because there are lots of parameters in this pretrained model.
If I only want to share this model structure to others,I think deNetInitialize
is necessary.
You can see UninitializedEvaluationNet
only need very little memory.
In order to share nets like UninitializedEvaluationNet
, can we define a deNetInitialize
function?
Answer
The weights in the neural network are stored in the form of RawArray
. This can be seen by comparing their full form
NetInitialize@ConvolutionLayer[1, {2}, "Input" -> {1, 3}] // InputForm
(* ConvolutionLayer[<|"Type" -> "Convolution",
"Arrays" -> <|"Weights" -> RawArray["Real32", {{{0.4258739650249481, -0.9216004014015198}}}],
"Biases" -> RawArray["Real32", {0.}]|>, "Parameters" -> <|"OutputChannels" -> 1, "KernelSize" -> {2}, "Stride" -> {1},
"PaddingSize" -> {0}, "Dilation" -> {1}, "Dimensionality" -> 1, "InputChannels" -> 1, "$GroupNumber" -> 1, "$InputSize" -> {3},
"$OutputSize" -> {2}|>, "Inputs" -> <|"Input" -> TensorT[{1, 3}, RealT]|>, "Outputs" -> <|"Output" -> TensorT[{1, 2}, RealT]|>|>,
<|"Version" -> "11.1.1"|>] *)
ConvolutionLayer[1, {2}, "Input" -> {1, 3}] // InputForm
(* ConvolutionLayer[<|"Type" -> "Convolution", "Arrays" -> <|"Weights" -> TensorT[{1, 1, 2}, RealT],
"Biases" -> Nullable[TensorT[{1}, RealT]]|>, "Parameters" -> <|"OutputChannels" -> 1, "KernelSize" -> {2}, "Stride" -> {1},
"PaddingSize" -> {0}, "Dilation" -> {1}, "Dimensionality" -> 1, "InputChannels" -> 1, "$GroupNumber" -> 1, "$InputSize" -> {3},
"$OutputSize" -> {2}|>, "Inputs" -> <|"Input" -> TensorT[{1, 3}, RealT]|>, "Outputs" -> <|"Output" -> TensorT[{1, 2}, RealT]|>|>,
<|"Version" -> "11.1.1"|>] *)
To remove the weights, we only need to replace the RawArray
with the corresponding place holders. Here is a solution using string manipulation
netUnInitialize[net_] :=
Activate@Replace[
ToExpression[
StringReplace[
ToString[InputForm[net]], {"NetChain" -> "Inactive[NetChain]",
"NetGraph" -> "Inactive[NetGraph]",
"RawArray" -> "Inactive[RawArray]"}]],
Inactive[RawArray][x_, y_] :>
NeuralNetworks`TensorT[Dimensions[y],
NeuralNetworks`RealT], ∞]
FileByteCount[Export["~/Downloads/incept.wlnet",netUnInitialize[incepNet]]]
(* 40877 *)
Comments
Post a Comment