Source code for deeppy.feedforward.layers

import cudarray as ca
from ..base import ParamMixin, PickleMixin
from ..parameter import Parameter


[docs]class Layer(PickleMixin): bprop_to_x = True def _setup(self, x_shape): """ Setup layer with parameters that are unknown at __init__(). """ pass
[docs] def fprop(self, x): """ Calculate layer output for given input (forward propagation). """ raise NotImplementedError()
[docs] def bprop(self, y_grad): """ Calculate input gradient. """ raise NotImplementedError()
[docs] def y_shape(self, x_shape): """ Calculate shape of this layer's output. x_shape[0] is the number of samples in the input. x_shape[1:] is the shape of the feature. """ raise NotImplementedError()
[docs]class FullyConnected(Layer, ParamMixin): def __init__(self, n_out, weights, bias=0.0): self.name = 'fullconn' self.n_out = n_out self.weights = Parameter.from_any(weights) self.bias = Parameter.from_any(bias) self._tmp_x = None def _setup(self, x_shape): self.weights._setup((x_shape[1], self.n_out)) if not self.weights.name: self.weights.name = self.name + '_w' self.bias._setup(self.n_out) if not self.bias.name: self.bias.name = self.name + '_b'
[docs] def fprop(self, x): self._tmp_x = x return ca.dot(x, self.weights.array) + self.bias.array
[docs] def bprop(self, y_grad): ca.dot(self._tmp_x.T, y_grad, out=self.weights.grad_array) ca.sum(y_grad, axis=0, out=self.bias.grad_array) if self.bprop_to_x: return ca.dot(y_grad, self.weights.array.T)
@property def _params(self): return self.weights, self.bias @_params.setter def _params(self, params): self.weights, self.bias = params
[docs] def y_shape(self, x_shape): return (x_shape[0], self.n_out)
[docs]class Activation(Layer): def __init__(self, method): self.name = 'act_' if method == 'sigmoid': self.name = self.name+'sigm' self.fun = ca.nnet.sigmoid self.fun_d = ca.nnet.sigmoid_d elif method == 'relu': self.name = self.name+method self.fun = ca.nnet.relu self.fun_d = ca.nnet.relu_d elif method == 'tanh': self.name = self.name+method self.fun = ca.tanh self.fun_d = ca.nnet.tanh_d else: raise ValueError('Invalid activation function.') self._tmp_x = None
[docs] def fprop(self, x): self._tmp_x = x return self.fun(x)
[docs] def bprop(self, y_grad): self.fun_d(self._tmp_x, self._tmp_x) return self._tmp_x * y_grad
[docs] def y_shape(self, x_shape): return x_shape
[docs]class PReLU(Layer, ParamMixin): def __init__(self, a=0.25): self.name = 'prelu' self.a = Parameter.from_any(a) self._tmp_x = None def _setup(self, x_shape): self.a._setup((1,)) self.a.name = self.name + '_a' @property def _params(self): return [self.a] @_params.setter def _params(self, params): self.a = params[0]
[docs] def fprop(self, x): self._tmp_x = x pos = ca.maximum(x, 0) neg = self.a.array * ca.minimum(x, 0) return pos + neg
[docs] def bprop(self, y_grad): pos = ca.nnet.relu_d(self._tmp_x) neg_mask = self._tmp_x < 0 a_grad = neg_mask * self._tmp_x * y_grad ca.sum(a_grad, out=self.a.grad_array) return (pos + self.a.array * neg_mask) * y_grad
[docs] def y_shape(self, x_shape): return x_shape