Skip to content

A small Python utility module that provides TensorFlow decorators

License

Notifications You must be signed in to change notification settings

lemonzi/tensorify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tensorify

Prototyping with TensorFlow can often be very tideous because it provides a limited number of possible operations on data. Pre-processing steps can be implemented in pure Python, but if an intermediate parsing is required (or if you want to take more advantage of TensorFlow's multi-threading capabilities) the solution is to either write it yourself in C++ or use the tf.py_func wrapper. Using the wrapper, however, requires passing a lot of arguments to it that make software maintenance harder -- especially if you are re-using parsing functions or classes for other pursposes.

This Python package provides tensorflow_op, a Python decorator that converts regular functions into TensorFlow ops, and tensorify, which is a convenience wrapper that applies the decorator to all the functions in the given module, either in-place or in a copy.

In short, it lets you do this:

@tensorflow_op(tf.int32)
def add(a_numpy_array, another_numpy_array, extra_one=False):
    extra = 1 if extra_one else 0
    return a_numpy_array + another_numpy_array + extra

result = add(a_tf_tensor, another_tf_tensor, extra_one=True)

With the advantage of using any class or library you want inside the function. This makes wrapping existing numerical libraries for use with Tensorflow extremely easy.

WARNING: All functions wrapped with tensorify will be executed in the same machine as the main script, so this is not a very efficient solution. This is intended for prototyping and for pre-processing or parsing code only. Do not implement heavy deep learning layers with this!

Installation

The tensorify package is not yet on the PyPI archive; you can install it with:

pip install git+https://github.com/lemonzi/tensorify

And then import it as usual.

Usage

tensorflow_op

A decorator that takes a function and turns it into a TensorFlow op.

A call to the decorated function will create a node with input tensors set to the function arguments, and the supplied key-word arguments will be passed to the function directly using a partial invocation.

The decorator takes as optional arguments a list with output types, a name for the op, and whether the function is stateful (False by default).

If no name is supplied, the CamelCased name of the function will be used. The name can also be modified at call time using the with_name() method:

@tensorflow_op(tf.int32)
def add(x, y, extra_one=False):
    return x + y + (1 if extra_one else 0)

input_one = tf.constant([1])
input_two = tf.constant([2])
answer.with_name("AddPlusOne")(input_one, input_two, extra_one=True)
answer.with_name("AddAndThatsIt")(input_one, input_two)

Similarly, the op can be made stateful using stateful(). In this example, we need to supply is_method so that the self argument doesn't get sent to the TensorFlow engine and stays in the closure instead. Actually, when stateful is not provided as argument and is_method is true the op is stateful by default; this is only an example.

class Accumulator:
    def __init__(self):
        self.state = 0
    @tensorify.tensorflow_op(tf.int64, is_method=True)
    def accumulate(self, x):
        self.state = self.state + x
        return self.state

x = tf.constant([1])
y = tf.constant([2])
my_accumulator = Accumulator()
after_accumulating_x = my_accumulator.stateful()(x)
after_accumulating_y = my_accumulator.stateful()(y)

Notice that, in this example, all ops that come form the same accumulator will accumulate to the same buffer, so the accumulator acts as a global counter. This is not very efficient, though; it would be better to use a tf.Variable for state storage and have the operation be stateless.

The same applies for the outputs:

@tensorflow_op()
def replicate(value, how_many_times):
    return [value] * how_many_times

x = tf.constant([1])
three_x = replicate.with_outputs([tf.int32] * 3)(x, 3)

tensorify

Converts all functions in a module into TensorFlow ops.

Example usage:

In fancy_module.py:

def add(x, y):
    return x + y

In app.py:

import tensorflow as tf
from tensorify import tensorify

import fancy_module
tensorify(fancy_module, tf.int32)

x_tensor = tf.constant([1])
y_tensor = tf.constant([2])
result = fancy_module.add(x_tensor, y_tensor)

About

A small Python utility module that provides TensorFlow decorators

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages