ModulesΒΆ
Since expressions are just objects, you can put them inside lists, dicts, etc., and you can also pass them to and return them from functions. By taking advantage of this, you can define very complex networks without very much clutter.
For example, Layer
class simplifies definitions of feedforward
neural networks. It takes an input size and output size and returns a
function. This function, in turn, creates a fully-connected layer
\(y = f(Wx+b)\), including properly-initialized parameters \(W\)
and \(b\). The same example above using Layer
would be:
h = Layer(2, nh)(i)
o = Layer(nh, 1)(h)
e = distance2(o, c)
The parameters of the two layers are there, but hidden from our view.
The reason for the two-step usage is to control parameter sharing. If
you create two Layer
objects, you get two different layers with
different parameters. But if you call it once and use the result twice,
you get two layers with shared parameters.
A possible definition of Layer
would be:
class MyLayer(object):
def __init__(self, ni, no):
self.W = parameter(numpy.random.uniform(-1., 1., (no, ni)))
self.b = parameter(numpy.zeros((no,)))
def __call__(self, i):
return tanh(dot(self.W, i) + self.b)
The real Layer
has some extra bells and whistles.
- it can take a sequence of input sizes instead of a single input size
- a negative input size gives you an input that takes an integer
i
and selects thei
th row of weights - the
bias
option lets you specify the initial bias;None
means no bias - the
f
option lets you set the activation function (default istanh
)