ShuffleNet-V2 Trained on ImageNet Competition Data

Identify the main object in an image

Released in 2018, this model features pointwise group convolutions and bottleneck-like structures. A "channel shuffle" operation is introduced to enable information flow between different groups of channels and improve accuracy.

Number of layers: 243 | Parameter count: 2,294,784 | Trained size: 10 MB |

Training Set Information

Performance

Examples

Resource retrieval

Get the pre-trained net:

In[1]:=
NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"]
Out[1]=

Basic usage

Classify an image:

In[2]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/7dc3f77c-71f5-4ae1-98ec-42949f0fbf29"]
Out[2]=

The prediction is an Entity object, which can be queried:

In[3]:=
pred["Definition"]
Out[3]=

Get a list of available properties of the predicted Entity:

In[4]:=
pred["Properties"]
Out[4]=

Obtain the probabilities of the 10 most likely entities predicted by the net:

In[5]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/85b440b9-3053-4b64-aad7-a30583e0a850"]
Out[5]=

An object outside the list of the ImageNet classes will be misidentified:

In[6]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/934f2220-f6b9-415f-b4b1-f2f0517113bd"]
Out[6]=

Obtain the list of names of all available classes:

In[7]:=
EntityValue[
 NetExtract[
   NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], "Output"][["Labels"]], "Name"]
Out[7]=

Feature extraction

Remove the last layers of the trained net so that the net produces a vector representation of an image:

In[8]:=
extractor = NetDrop[NetModel[
   "ShuffleNet-V2 Trained on ImageNet Competition Data"], -2]
Out[8]=

Get a set of images:

In[9]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/65840fbb-d1fc-48fb-9fd4-8378eb521329"]

Visualize the features of a set of images:

In[10]:=
FeatureSpacePlot[imgs, FeatureExtractor -> extractor, LabelingSize -> 100, ImageSize -> 600]
Out[10]=

Visualize convolutional weights

Extract the weights of the first convolutional layer in the trained net:

In[11]:=
weights = NetExtract[
   NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], {1,
     "Weights"}];

Show the dimensions of the weights:

In[12]:=
Dimensions[weights]
Out[12]=

Visualize the weights as a list of 24 images of size 3⨯3:

In[13]:=
ImageAdjust[Image[#, Interleaving -> False]] & /@ Normal[weights]
Out[13]=

Transfer learning

Use the pre-trained model to build a classifier for telling apart images of sunflowers and roses. Create a test set and a training set:

In[14]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/2d0f94d2-d11f-4ac7-8fb6-e4fd4160e2bd"]
In[15]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/6c30d67c-5413-4e71-90f0-b0f78a088fb1"]

Remove the last layers from the pre-trained net:

In[16]:=
tempNet = NetDrop[NetModel[
   "ShuffleNet-V2 Trained on ImageNet Competition Data"], -2]
Out[16]=

Create a new net composed of the pre-trained net followed by a linear layer and a softmax layer:

In[17]:=
newNet = NetChain[<|"pretrainedNet" -> tempNet, "linearNew" -> LinearLayer[], "softmax" -> SoftmaxLayer[]|>, "Output" -> NetDecoder[{"Class", {"sunflower", "rose"}}]]
Out[17]=

Train on the dataset, freezing all the weights except for those in the "linearNew" layer (use TargetDevice -> "GPU" for training on a GPU):

In[18]:=
trainedNet = NetTrain[newNet, trainSet, LearningRateMultipliers -> {"linearNew" -> 1, _ -> 0}]
Out[18]=

Accuracy obtained on the test set:

In[19]:=
ClassifierMeasurements[trainedNet, testSet, "Accuracy"]
Out[19]=

Net information

Inspect the number of parameters of all arrays in the net:

In[20]:=
Information[
 NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], "ArraysElementCounts"]
Out[20]=

Obtain the total number of parameters:

In[21]:=
Information[
 NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], "ArraysTotalElementCount"]
Out[21]=

Obtain the layer type counts:

In[22]:=
Information[
 NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], "LayerTypeCounts"]
Out[22]=

Display the summary graphic:

In[23]:=
Information[
 NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"], "SummaryGraphic"]
Out[23]=

Export to ONNX

Export the net to the ONNX format:

In[24]:=
onnxFile = Export[FileNameJoin[{$TemporaryDirectory, "net.onnx"}], NetModel["ShuffleNet-V2 Trained on ImageNet Competition Data"]]
Out[24]=

Get the size of the ONNX file:

In[25]:=
FileByteCount[onnxFile]
Out[25]=

The size is similar to the byte count of the resource object:

In[26]:=
ResourceObject[
  "ShuffleNet-V2 Trained on ImageNet Competition Data"]["ByteCount"]
Out[26]=

Check some metadata of the ONNX model:

In[27]:=
{OpsetVersion, IRVersion} = {Import[onnxFile, "OperatorSetVersion"], Import[onnxFile, "IRVersion"]}
Out[27]=

Import the model back into the Wolfram Language. However, the NetEncoder and NetDecoder will be absent because they are not supported by ONNX:

In[28]:=
Import[onnxFile]
Out[28]=

Requirements

Wolfram Language 12.3 (May 2021) or above

Resource History

Reference