Skip to content

[Discussion] Roadmap and TensorLayer API Changes for Version 2.0 #770

@DEKHTIARJonathan

Description

@DEKHTIARJonathan

Dear friends,

I will try to write and summarize a few thoughts regarding the upcoming changes in TensorLayer, namely for version 2.0 🎉🎉🎉.

Main features that will be released.

I may forget some, if so I will update my post.

  • Logging contrib Hyperdash module
  • Graph Architecture saving
  • Distributed training with Horovod
  • Network API and features inspired by Keras and PyTorch.
  • Database for data and model life-cycle management

TensorLayer 1.x recurring issues.

TensorLayer has always been a quite fuzzy and messy (and it's really improving 👍). The results have been an incredible number of bugs in the different Layers. Implementing one single feature oftenly assume that you partly rewrite the code for absolutely each Layer (I did it already 2 times, and I'm doing it for the 3rd time with the Network API). This is extremely dangerous with a high risk of introducing an incredible number of bugs (I remind you that we had to release a very large number of release candidate to fix all the bugs 1.8.6rc0, 1.8.6rc1, 1.8.6rc2, 1.8.6rc3, 1.8.6rc4, 1.8.6rc5 1.8.6rc6).

Every so often we find new bugs, just by reading at the code:

Additionally, the current Layer API is slightly counter intuitive:

  • why layer.all_params returns the params of a network and not a layer
  • same layer.all_layers is quite ironic right ?
  • with the Graph API newly introduced, when you save a Layer, you actually save the whole network.
  • layer.count_params() send you the number of params in the graph, not inside the layer
  • etc.

Proposition: Breaking the breaking the backward compatibility with the Network API

As TensorFlow did when releasing TF 1.0 or Django (with Django 2.0) in a non deep learning context. Very big libraries oftenly decide to let the good old times behind them and clean the code base. I believe that it is not a problem to break backward compibility if it is for the better and done very rarely.

What are the changes, I believe would highly improve TL maintainability and clarity for TL 2.0:

  • a huge cleanup in the features of the Layer API, absolutely every features which is a Network feature should move to the newly created Network API.
  • keep Layer features at the Layer level.
  • add feature Layer-related in a Layer API (e.g. how many params in this Layer ?)

A few words on the Network API

I believe the network API should NOT be mandatory in TL. It should bring additional, non essential features.

The following should be possible

import tensorflow as tf
import tensorlayer as tl

tf.logging.set_verbosity(tf.logging.DEBUG)
tl.logging.set_verbosity(tl.logging.DEBUG)

x = tf.placeholder(tf.float32, shape=[None, 30])

net = tl.layers.InputLayer(x, name='input')
net = tl.layers.DenseLayer(net, n_units=10, name='dense1')

However, the following functionalities should be removed from Layer and move to Network API:

#  Graph API
net.load() 
net.save()

net.print_layers()
net.print_params(False)

print(net.all_drop)
print(net.all_params)
print(net.all_layers)
print(net.all_graphs)

The list above is not exhaustive. In the same time, new functionalities can be added:

layer.count_params()  # returns the number of params in this Layer
layer._local_vars  # returns a list of tf.Variable inside this Layer

The list above is not exhaustive

Presentation of the current Network API

It is not finialized, is subject to changes. I plan on releasing two Network Classes:

Sequential (similar idea than Keras)

For easy and sequential models, the Sequential Network API is here for rapid prototyping.

# Model Definition

model = tl.networks.Sequential(name="My_Sequential_1D_Network")  # Automatically adds the InputLayer, no need to do it

model.add(tl.layers.DenseLayer(n_units=10, act=tf.nn.relu, name="seq_layer_1"))

model.add(tl.layers.DenseLayer(n_units=20, act=None, name="seq_layer_2"))
model.add(tl.layers.PReluLayer(channel_shared=True, name="prelu_layer_2"))

model.add(tl.layers.DenseLayer(n_units=50, act=None, name="seq_layer_3"))
model.add(tl.layers.PRelu6Layer(channel_shared=False, name="prelu6_layer_3"))

model.add(tl.layers.DenseLayer(n_units=40, act=None, name="seq_layer_4"))
model.add(tl.layers.PTRelu6Layer(channel_shared=True, name="ptrelu6_layer_4"))

model.add(tl.layers.DenseLayer(n_units=40, act=tf.nn.relu, name="seq_layer_5"))
model.add(tl.layers.DropoutLayer(keep=0.5, is_fix=True, name="dropout_layer_5"))

# TF Graph Creation

plh = tf.placeholder(tf.float16, (100, 32))

train_model_output = model.compile(plh, reuse=False, is_train=True)  # returns a TF Tensor
test_model_output = model.compile(plh, reuse=True, is_train=False)   # returns a TF Tensor

# PyTorch-Like Layer Access

layer_1 = model["seq_layer_1"]

Custom Model API

CustomModel/CustomNetwork/Model/Network: I haven't really decide on the name yet.
This Class haven't been created yet, it is subject to change.

# Model Definition

class MyCustomNetwork(CustomNetwork):    

    def define_network(self):  # abstract function that needs to be overwritten
    
        net_in = tl.layers.InputLayer(name="input_layer")

        net = tl.layers.DenseLayer(n_units=10, act=tf.nn.relu, name="seq_layer_1")

        net1 = tl.layers.DenseLayer(n_units=20, act=None, name="seq_layer_2")(net)
        net1 = tl.layers.PReluLayer(channel_shared=True, name="prelu_layer_2")(net)

        net2 = tl.layers.DenseLayer(n_units=50, act=None, name="seq_layer_3")(net)
        net2 = tl.layers.PRelu6Layer(channel_shared=False, name="prelu6_layer_3")(net)

        net3 = tl.layers.DenseLayer(n_units=40, act=None, name="seq_layer_4")(net)
        net3 = tl.layers.PTRelu6Layer(channel_shared=True, name="ptrelu6_layer_4")(net)

        net4 = tl.layers.DenseLayer(n_units=40, act=tf.nn.relu, name="seq_layer_5")(net)
        net4 = tl.layers.DropoutLayer(keep=0.5, is_fix=True, name="dropout_layer_5")(net)
        
        net_stack = tl.layers.StackLayer(axis=1, name='stack')([net1, net2, net3, net4])
        
        return net_stack
        
model = MyCustomNetwork(name="My_Custom_Network")

# TF Graph Creation

plh = tf.placeholder(tf.float16, (100, 32))

train_model_output = model.compile(plh, reuse=False, is_train=True)  # returns a TF Tensor
test_model_output = model.compile(plh, reuse=True, is_train=False)   # returns a TF Tensor

# PyTorch-Like Layer Access

layer_1 = model["seq_layer_1"]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions