EfficientNet Trained on ImageNet

Identify the main object in an image

Released in 2019, this family of models is obtained by uniformly scaling up width, depth and resolution of a baseline convolutional net using a novel method. EfficientNets demonstrate a significant performance gain both in accuracy and inference time compared to the existing classification models trained on ImageNet. In particular, EfficientNet-B7 surpasses GPipe accuracy (Huang et al., 2018), using ~8.4x fewer parameters and running ~6.1x faster on inference. Furthermore, the models are successfully used in transfer learning on datasets such as CIFAR-100, Flowers, Birdsnap, Stanford Cars and others, still outperforming the existing state-of-the-art nets.

Number of models: 6

Training Set Information

Performance

Examples

Resource retrieval

Get the pre-trained net:

In[1]:=
NetModel["EfficientNet Trained on ImageNet"]
Out[1]=

NetModel parameters

This model consists of a family of individual nets, each identified by a specific parameter combination. Inspect the available parameters:

In[2]:=
NetModel["EfficientNet Trained on ImageNet", "ParametersInformation"]
Out[2]=

Pick a non-default net by specifying the parameters:

In[3]:=
NetModel[{"EfficientNet Trained on ImageNet", "Architecture" -> "B5"}]
Out[3]=

Pick a non-default uninitialized net:

In[4]:=
NetModel[{"EfficientNet Trained on ImageNet", "Architecture" -> "B5"}, "UninitializedEvaluationNet"]
Out[4]=

Basic usage

Classify an image:

In[5]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/021af06e-4c1e-42e9-b694-d29dcd947319"]
Out[5]=

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

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

Get a list of available properties of the predicted Entity:

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

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

In[8]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/677689c0-8469-4e34-b67e-715f8d51ee2c"]
Out[8]=

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

In[9]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/7bd1c7df-47c8-499f-83b5-6cd72bad35df"]
Out[9]=

Obtain the list of names of all available classes:

In[10]:=
EntityValue[
 NetExtract[NetModel["EfficientNet Trained on ImageNet"], "Output"][[
  "Labels"]], "Name"]
Out[10]=

Feature extraction

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

In[11]:=
extractor = Take[NetModel["EfficientNet Trained on ImageNet"], {1, -3}]
Out[11]=

Get a set of images:

In[12]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/eb3a80ec-5c1e-4560-b555-4f41d8d90643"]

Visualize the features of a set of images:

In[13]:=
FeatureSpacePlot[imgs, FeatureExtractor -> extractor, LabelingSize -> 200, ImageSize -> Full, AspectRatio -> 1/2]
Out[13]=

Visualize convolutional weights

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

In[14]:=
NetModel["EfficientNet Trained on ImageNet"]
Out[14]=
In[15]:=
weights = NetExtract[
   NetModel["EfficientNet Trained on ImageNet"], {"stem_conv", "Weights"}];

Show the dimensions of the weights:

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

Visualize the weights as a list of 32 images of size 3x3:

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

Transfer learning

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

In[18]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/5e44ac16-b75c-4422-a458-336007634336"]
In[19]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/27ba9f1d-5773-4240-adb8-7af28e8ec14e"]

Remove the linear layer from the pre-trained net:

In[20]:=
tempNet = Take[NetModel["EfficientNet Trained on ImageNet"], {1, -3}]
Out[20]=

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

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

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

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

Perfect accuracy is obtained on the test set:

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

Net information

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

In[24]:=
Information[
 NetModel["EfficientNet Trained on ImageNet"], "ArraysElementCounts"]
Out[24]=

Obtain the total number of parameters:

In[25]:=
Information[
 NetModel["EfficientNet Trained on ImageNet"], \
"ArraysTotalElementCount"]
Out[25]=

Obtain the layer type counts:

In[26]:=
Information[
 NetModel["EfficientNet Trained on ImageNet"], "LayerTypeCounts"]
Out[26]=

Export to MXNet

Export the net into a format that can be opened in MXNet:

In[27]:=
jsonPath = Export[FileNameJoin[{$TemporaryDirectory, "net.json"}], NetModel["EfficientNet Trained on ImageNet"], "MXNet"]
Out[27]=

Export also creates a net.params file containing parameters:

In[28]:=
paramPath = FileNameJoin[{DirectoryName[jsonPath], "net.params"}]
Out[28]=

Get the size of the parameter file:

In[29]:=
FileByteCount[paramPath]
Out[29]=

Requirements

Wolfram Language 12.1 (March 2020) or above

Resource History

Reference