Source code for bgd.layers.fc

# layers/fc.py
# author : Antoine Passemiers, Robin Petit

__all__ = [
    'FullyConnected'
]

import numpy as np

from bgd.initializers import ZeroInitializer, GlorotUniformInitializer
from .layer import Layer

[docs]class FullyConnected(Layer): """ Fully connected (dense) neural layer. Each output neuron is a weighted sum of its inputs with possibly a bias. Args: n_in (int): Number of input neurons. n_out (int): Number of output neurons. copy (bool): Whether to copy layer output. with_bias (bool): Whether add a bias to output neurons. dtype (type): Type of weights and biases. initializer (:class:`bgd.initializers.Initializer`): Initializer of the weights. bias_initializer (:class:`bgd.initializers.Initializer`): Initializer of the biases. Attributes: weights (:obj:`np.ndarray`): Matrix of weights. biases (:obj:`np.ndarray`): Vector of biases. """ def __init__(self, n_in, n_out, copy=False, with_bias=True, dtype=np.float32, initializer=GlorotUniformInitializer(), bias_initializer=ZeroInitializer()): Layer.__init__(self, copy=copy, save_output=False) self.with_bias = with_bias self.dtype = dtype self.n_in = n_in self.n_out = n_out self.initializer = initializer self.bias_initializer = bias_initializer self.weights = self.initializer.initialize((self.n_in, self.n_out), dtype=self.dtype) if self.with_bias: self.biases = self.bias_initializer.initialize((1, self.n_out), dtype=self.dtype) else: self.biases = None
[docs] def _forward(self, X): # Output: X * W + b return np.dot(X, self.weights) + self.biases
[docs] def _backward(self, error): gradient_weights = np.dot(self.current_input.T, error) if self.with_bias: gradient_bias = np.sum(error, axis=0, keepdims=True) gradients = (gradient_weights, gradient_bias) else: gradients = gradient_weights if self.propagate: signal = np.dot(error, self.weights.T) else: signal = None return (signal, gradients)
[docs] def get_parameters(self): if self.with_bias: return (self.weights, self.biases) return (self.weights,)
[docs] def update_parameters(self, delta_fragments): self.weights -= delta_fragments[0] if self.with_bias: self.biases -= delta_fragments[1]