Skip to content

Instantly share code, notes, and snippets.

@erfannoury
Created June 9, 2016 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erfannoury/6f42b6098e4cbbabd1f114766c212506 to your computer and use it in GitHub Desktop.
Save erfannoury/6f42b6098e4cbbabd1f114766c212506 to your computer and use it in GitHub Desktop.
def create_param(spec, shape, name=None):
"""
Helper method to create Theano shared variables for layer parameters
and to initialize them.
Parameters
----------
spec : numpy array, Theano expression, or callable
Either of the following:
* a numpy array with the initial parameter values
* a Theano expression or shared variable representing the parameters
* a function or callable that takes the desired shape of
the parameter array as its single argument and returns
a numpy array.
shape : iterable of int
a tuple or other iterable of integers representing the desired
shape of the parameter array.
name : string, optional
If a new variable is created, the name to give to the parameter
variable. This is ignored if `spec` is already a Theano expression
or shared variable.
Returns
-------
Theano shared variable or Theano expression
A Theano shared variable or expression representing layer parameters.
If a numpy array was provided, a shared variable is initialized to
contain this array. If a shared variable or expression was provided,
it is simply returned. If a callable was provided, it is called, and
its output is used to initialize a shared variable.
Notes
-----
This function is called by :meth:`Layer.add_param()` in the constructor
of most :class:`Layer` subclasses. This enables those layers to
support initialization with numpy arrays, existing Theano shared variables
or expressions, and callables for generating initial parameter values.
"""
shape = tuple(shape) # convert to tuple if needed
if any(d <= 0 for d in shape):
raise ValueError((
"Cannot create param with a non-positive shape dimension. "
"Tried to create param with shape=%r, name=%r") % (shape, name))
if hasattr(spec, '__call__'):
spec = spec(shape)
was_callable = True
if isinstance(spec, theano.Variable):
# We cannot check the shape here, Theano expressions (even shared
# variables) do not have a fixed compile-time shape. We can check the
# dimensionality though.
# Note that we cannot assign a name here. We could assign to the
# `name` attribute of the variable, but the user may have already
# named the variable and we don't want to override this.
if spec.ndim != len(shape):
if was_callable:
raise RuntimeError("cannot initialize parameters: the "
"provided callable did not return a "
" variable with correct dimensions. "
"Should be %d instead of %d" % \
(len(shape), spec.ndim))
else:
raise RuntimeError("parameter variable has %d dimensions, "
"should be %d" % (spec.ndim, len(shape)))
return spec
elif isinstance(spec, np.ndarray):
if spec.shape != shape:
if was_callable:
raise RuntimeError("cannot initialize parameters: the "
"provided callable did not return a value "
"with the correct shape")
else:
raise RuntimeError("parameter array has shape %s, should be "
"%s" % (spec.shape, shape))
if was_callable:
return theano.shared(floatX(spec))
return theano.shared(floatX(spec), name=name)
else:
raise RuntimeError("cannot initialize parameters: 'spec' is not "
"a numpy array, a Theano expression, or a "
"callable")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment