Luchador is a library for Deep Learning built on top of Tensorflow or Theano. You can build complex network using configuration file like Caffe, but with simpler YAML format.
In luchador, network components can be instantiated with python-primitive-type arguments (such as number, string, list, and dict), thus, just by giving the class name you want to instantiate (as typename) and its arguments (as args), the network can be built.
The following configuration file defines sequential network composed of convolution and non-linear activation followed by inner product.
typename: Sequential
args:
name: classifier
input_config:
typename: Input
name: input_image
shape: [32, 84, 84, 1]
layer_configs:
- typename: Conv2D
args:
n_filters: 32
filter_width: 8
filter_height: 8
strides: 4
padding: valid
- typename: ReLU
- typename: Flatten
- typename: Dense
args:
n_nodes: 10You can construct the model with luchador.nn.make_model function as following.
import numpy as np
import luchador
import luchador.nn as nn
model_config = nn.get_model_config('model.yml')
model = nn.make_model(model_config)This will create the following network. (To visualize network, you need to run luchador with Tensorflow backend. See Setting Backend for this.)
For executing computation, luchador provides Session interface which works in a similar way as Tensorflow sesison.
session = nn.Session()
session.initialize()
input_shape = [32, 84, 84, 1]
input_data = np.random.rand(*input_shape)
output_data = session.run(
inputs={
model.input: input_data,
},
outputs=model.output,
)But fixing parameters is often inconvenient. You can put placeholder with {placeholder_name} in model YAML file and give value at runtime, by giving value to get_model_config.
In the following example, network input shape (input_shape) is set at runtime. At runtime, the code checks the current backend to define image channel order accordingly. (NHWC for Thensorflow CPU, NCHW for the others.)
typename: Sequential
args:
name: classifier
input_config:
typename: Input
args:
name: input_image
shape: {input_shape}
layer_configs:
- typename: Conv2D
args:
n_filters: 32
filter_width: 8
filter_height: 8
strides: 4
padding: valid
- typename: ReLU
- typename: Flatten
- typename: Dense
args:
n_nodes: 10be = luchador.get_nn_backend()
fmt = luchador.get_nn_conv_format()
if be == 'tensorflow' and fmt == 'NHWC':
input_shape = [32, 84, 84, 1]
else:
input_shape = [32, 1, 84, 84]
model_config = nn.get_model_config('model.yml', input_shape=input_shape)
model = nn.make_model(model_config)In the sense of computation node, Sequential model represents one-to-one mapping. To build more complex graph, one needs to create many-to-many mappings. In luchador you can use Graph and Container models and feed compound input object to build such network.
Luchador has Input class which represents single network input object. Under the hood, it wrapps Tensorflow's placeholder or Theano's equivalent (TensorVariable) class. When constructing complex network, one needs multiple of such objects. For example, Optimizers require variables representing predicted values and correct values as its input. When defining network input input_config you can use either, single Input definition, list of definitions, or dictionary of definitions.
The following example defines the dictionary of Inputs, with keys data and label.
input_config:
data:
typename: Input
args:
name: input_image
shape: {image_shape}
label:
typename: Input
args:
name: label
shape: {label_size}
dtype: int64The following defines the list version of the previous example.
input_config:
- typename: Input
args:
name: input_image
shape: {image_shape}
- typename: Input
args:
name: label
shape: {label_size}
dtype: int64Luchador uses retrieval mechanism similar to Tensorflow's get_variable but extends it to Input and Tensor (output) for flexible model construction. When constructing complex network, it is often required to retrieve Input, Output and Variable defined somewhere else. To retrieve existing instance, you can use the name of the instance.
typename: Input
reuse: True
name: input_imageretrieves Input instance named input_image. reuse attribute is requried to Input type.
typename: Tensor
name: dense/outputretrieves Tensor instance which is output from layer named dense.
typename: Variable
name: conv/filterretrieves Variable instance which is filter parameter of Conv2D layer named conv.
typename: Model
name: foo
fetch: inputretrieves the input attribute of Model named foo.
typename: Model
name: foo
fetch: outputretrieves the output attribute of Model named foo.
typename: Model
name: foo
fetch: parameterretrieves the list of trainable parameters of Model named foo.
In Sequential model, the input to the model is passed through each layers, thus you do not need to specify the input to each layer. In contrast, in Graph model, each node (corresponds to layer in Sequential) has its own input. In the following example, Adam optimizer is constructed and the output from the Model named error is fed as loss and the parameters of Model named classifier is fed as wrt.
typename: Graph
args:
name: optimization
node_configs:
- typename: Adam
args:
name: Adam
learning_rate: 0.01
input:
loss:
typename: Model
name: error
fetch: output
wrt:
typename: Model
name: classifier
fetch: parameterContainer model combines multiple models in dictionary manner. In the following example, a Container model which contains three models (classifier, error and optimization) is defined. (The contents of each model is omitted here, using YAML's alias feature.)
typename: Container
args:
model_configs:
- << : *classifier
name: classifier
- << : *error
name: error
- << : *optimization
name: optimizationTo define input/output of Graph and Container model, one needs to add input_config manually.
You can add network component by subclassing the base class. For simplicity, here we forcus on Theano backend.
To add new layer, you need to subclass from luchador.nn.BaseLayer, then implement build method. build is called with the input Variable. Let's add Parametric ReLU Layer as an example.
from luchador.nn import BaseLayer
class PReLU(BaseLayer):
def __init__(self, alpha):
super(PReLU, self).__init__(alpha=alpha)
def build(self, input_tensor):
alpha = self.args['alpha']
x = input_tensor.get() # Unwrap the variable
output_tensor = T.switch(x < 0, alpha * x, x)
return Tensor(output_tensor, shape=input_tensor.shape)Then you can retrieve this with luchador.nn.get_layer function.
$ python
>>> import example.custom_layer
2016-09-27 15:36:53,129: INFO: Using theano backend
>>> from luchador.nn import get_layer
>>> get_layer('PReLU')
<class 'example.custom_layer.PReLU'>You can run examples in example directory, such as MNIST classification, (Variational) AutoEncoder, GAN and DCGAN as follow. Use --help for how to run.
python example/classification/classify_mnist.py
python example/autoencoder/train_vae.py
python example/gan/train_dcgan.pyThe following is the network built using DCGAN example.

Luchador has luchador.nn.summary.SummaryWriter class which wraps Tensorflow's SummaryWriter class so that not only Tensorflow backend but also Thenao backend can produce summary data which then can be visualized with tensorboard. However, when using Theano backend and if Tensorflow is installed with GPU enabled, Tensorflow detects that other library is using GPU and fail the program. Therefore it is strongly advised to setup a new python environment when you use Theano and Tensorflow (SummaryWriter) at the same time.
- Luchador uses Thensorflow or Theano as neural network backend, so you need to install them. Refer to the installation instruction for each project.
The following dependencies are automatically installed during the installation.
h5pyfor saving neural network parametersruamel.yamlfor parsing YAML files.
- Download the source code
git clone https://github.com/mthrok/luchador && cd luchador - Install
pip install .
pip install --upgrade --no-deps git+git://github.com/mthrok/luchador.git
At the time of importing luchador.nn module, luchador checks environmental variable LUCHADOR_NN_BACKEND to detcide which backend it should use. Set value either tensorflow or theano to switch backend.
LUCHADOR_NN_BACKEND=theano luchadorWhen running Tensorflow backend, you can additionally configure default dtype and convolution data format with LUCHADOR_NN_DTYPE and LUCHADOR_NN_CONV_FORMAT. These values are only effective in Tensorflow backend. To configure Theano, make .theanorc file in home directory and follow the instruction found at Theano documentation..
LUCHADOR_NN_BACKEND=tensorflow LUCHADOR_NN_CONV_FORMAT=NHWC LUCHADOR_NN_DTYPE=float32 luchador Or programtically, you can set backend before importing nn module.
import luchador
luchador.set_nn_backend('tensorflow')
luchador.set_nn_conv_format('NHWC')
luchador.set_nn_dtype('float32')
import luchador.nn # tensorflow backend is loadedSee project list for the list of plans.
Although automated integration test and unit test is set up via CircleCI, currently only small usage pattern is tested. If you find a bug, please open an issue.
