Wolfram Research

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/27f82875-41b1-4465-ad7b-27574138bf5e"]
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/570cb0f5-963a-4739-bf28-556532c40f42"]
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/f744f77b-cfdc-47be-a2d9-067c11a2b9db"]
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/92468851-80b9-433b-9fb2-7fd01fcdb9bc"]

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 64 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/b9d42569-313d-42d1-9c99-3079b1121667"]
In[19]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/6df8f742-941b-4296-9d67-076052e20d7e"]

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