I am doing some hobby coding regarding neural networks, and I was wondering if this is a correct and good use of abstract base classes or not.

import abc
import collections
import math
import weakref

class AbstractNeuron(metaclass=abc.ABCMeta):

    def __init__(self, weights, f=math.tanh, bias=1, biasWeight=0):
        self.weights = weights
        self.f = f
        self.bias = bias
        self.biasWeight = biasWeight

    def __call__(self, inputs):
        return self.activate(inputs)

    @abc.abstractmethod
    def activate(self, inputs):
        raise NotImplementedError

class MappingNeuron(AbstractNeuron):

    def __init__(self, weights=None, f=math.tanh, bias=1, biasWeight=0):
        if weights is None:
            weights = collections.defaultdict(int)
        super().__init__(weights, f, bias, biasWeight)

    def activate(self, inputs):
        return self.f(math.fsum(inputs[key] * self.weights[key] for key in inputs.keys()) + self.bias * self.biasWeight)

class WeakNeuron(MappingNeuron):

    def __init__(self, weights=None, f=math.tanh, bias=1, biasWeight=0):
        if weights is None:
            weights = weakref.WeakKeyDictionary()
        super().__init__(weights, f, bias, biasWeight)

class SequenceNeuron(AbstractNeuron):

    def __init__(self, weights, f=math.tanh, bias=1, biasWeight=0):
        super().__init__(weights, f, bias, biasWeight)

    def activate(self, inputs):
        return self.f(math.fsum(inputs[i] * weight for i, weight in enumerate(self.weights)) + self.bias * self.biasWeight)

I have not used Abstract Base Classes until now, but this is about how I think I would organize your functionality (can not test without usage examples, seems to give syntax error in Python 2.7 but not in 3.2.2):

import abc
import collections
import math
import weakref

class AbstractNeuron(metaclass=abc.ABCMeta):
    def __init__(self, weights, f=math.tanh, bias=1, biasWeight=0):
        self.weights = self.make_weights() if weights is None else weights
        self.f = f
        self.bias = bias
        self.biasWeight = biasWeight

    def __call__(self, inputs):
        return self.activate(inputs)

    @abc.abstractmethod
    def make_weights(self):
        raise NotImplementedError

    @abc.abstractmethod
    def activate(self, inputs):
        raise NotImplementedError

class MappingNeuron(AbstractNeuron):
    def make_weights(self):
        return collections.defaultdict(int)

    def activate(self, inputs):
        return self.f(math.fsum(inputs[key] * self.weights[key] for key in inputs.keys()) + self.bias * self.biasWeight)

class WeakNeuron(MappingNeuron):
    def make_weights(self):
        return weakref.WeakKeyDictionary()

class SequenceNeuron(AbstractNeuron):    
    def make_weights(self):
        raise ValueError('SequenceNeuron weights can not be None!')

    def activate(self, inputs):
        return self.f(math.fsum(inputs[i] * weight for i, weight in enumerate(self.weights)) + self.bias * self.biasWeight)
commented: Thank you for the response. +7
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.