Wolfram Computation Meets Knowledge

CycleGAN Horse-to-Zebra Translation Trained on ImageNet Competition Data

Turn horses into zebras in a photo

Released in 2017, this model exploits a novel technique for image translation, in which two models translating from A to B and vice versa are trained jointly with adversarial training. In addition to the adversarial loss, cycle consistency is also enforced in the loss function: when the output of the first translator is fed into the second, the final result is encouraged to match the input of the first translator. This allows successful training for image translation tasks in which only unpaired training data can be collected. This model was trained to translate horses into zebras.

Number of layers: 94 | Parameter count: 2,855,811 | Trained size: 12 MB

Training Set Information

Examples

Resource retrieval

Retrieve the resource object:

In[1]:=
ResourceObject["CycleGAN Horse-to-Zebra Translation Trained on \
ImageNet Competition Data"]
Out[1]=

Get the pre-trained net:

In[2]:=
NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"]
Out[2]=

Basic usage

Run the net on a photo:

In[3]:=
CloudGet["https://www.wolframcloud.com/objects/3da1b7ab-ec94-49d3-a59f-388e6c54243f"] (* Evaluate this cell to copy the example input from a cloud object *)
Out[3]=

Adapt to any size

Automatic image resizing can be avoided by replacing the net encoders. First get the net:

In[4]:=
net = NetModel[
  "CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"]
Out[4]=

Get a photo:

In[5]:=
CloudGet["https://www.wolframcloud.com/objects/b9558c3e-dffa-49d8-98a3-f4f644a2b540"] (* Evaluate this cell to copy the example input from a cloud object *)

Create a new encoder with the desired dimensions:

In[6]:=
netEnc = NetEncoder[{"Image", ImageDimensions[img]}]
Out[6]=

Attach the new net encoder and run the network:

In[7]:=
resizedNet = 
 NetReplacePart[
  net, {"Input" -> netEnc, "Output" -> NetDecoder[{"Image"}]}]
Out[7]=
In[8]:=
resizedNet[img]
Out[8]=

Net information

Inspect the sizes of all arrays in the net:

In[9]:=
NetInformation[
 NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"], "ArraysSizes"]
Out[9]=

Obtain the total number of parameters:

In[10]:=
NetInformation[
 NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"], "ArraysTotalElementCount"]
Out[10]=

Obtain the layer type counts:

In[11]:=
NetInformation[
 NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"], "LayerTypeCounts"]
Out[11]=

Display the summary graphic:

In[12]:=
NetInformation[
 NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"], "SummaryGraphic"]
Out[12]=

Export to MXNet

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

In[13]:=
jsonPath = 
 Export[FileNameJoin[{$TemporaryDirectory, "net.json"}], 
  NetModel["CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"], "MXNet"]
Out[13]=

Export also creates a net.params file containing parameters:

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

Get the size of the parameter file:

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

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

In[16]:=
ResourceObject[
  "CycleGAN Horse-to-Zebra Translation Trained on ImageNet \
Competition Data"]["ByteCount"]
Out[16]=

Represent the MXNet net as a graph:

In[17]:=
Import[jsonPath, {"MXNet", "NodeGraphPlot"}]
Out[17]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Reference