def buildNetwork(*layers, **options): """Build arbitrarily deep networks. `layers` should be a list or tuple of integers, that indicate how many neurons the layers should have. `bias` and `outputbias` are flags to indicate whether the network should have the corresponding biases; both default to True. To adjust the classes for the layers use the `hiddenclass` and `outclass` parameters, which expect a subclass of :class:`NeuronLayer`. If the `recurrent` flag is set, a :class:`RecurrentNetwork` will be created, otherwise a :class:`FeedForwardNetwork`. If the `fast` flag is set, faster arac networks will be used instead of the pybrain implementations.""" # options opt = {'bias': True, 'hiddenclass': SigmoidLayer, 'outclass': LinearLayer, 'outputbias': True, 'peepholes': False, 'recurrent': False, 'fast': False, } for key in options: if key not in opt.keys(): raise NetworkError('buildNetwork unknown option: %s' % key) opt[key] = options[key] if len(layers) < 2: raise NetworkError('buildNetwork needs 2 arguments for input and output layers at least.') # Bind the right class to the Network name network_map = { (False, False): FeedForwardNetwork, (True, False): RecurrentNetwork, } try: network_map[(False, True)] = _FeedForwardNetwork network_map[(True, True)] = _RecurrentNetwork except NameError: if opt['fast']: raise NetworkError("No fast networks available.") if opt['hiddenclass'].sequential or opt['outclass'].sequential: if not opt['recurrent']: # CHECKME: a warning here? opt['recurrent'] = True Network = network_map[opt['recurrent'], opt['fast']] n = Network() # linear input layer n.addInputModule(LinearLayer(layers[0], name='in')) # output layer of type 'outclass' n.addOutputModule(opt['outclass'](layers[-1], name='out')) if opt['bias']: # add bias module and connection to out module, if desired n.addModule(BiasUnit(name='bias')) if opt['outputbias']: n.addConnection(FullConnection(n['bias'], n['out'])) # arbitrary number of hidden layers of type 'hiddenclass' for i, num in enumerate(layers[1:-1]): layername = 'hidden%i' % i if issubclass(opt['hiddenclass'], LSTMLayer): n.addModule(opt['hiddenclass'](num, peepholes=opt['peepholes'], name=layername)) else: n.addModule(opt['hiddenclass'](num, name=layername)) if opt['bias']: # also connect all the layers with the bias n.addConnection(FullConnection(n['bias'], n[layername])) # connections between hidden layers for i in range(len(layers) - 3): n.addConnection(FullConnection(n['hidden%i' % i], n['hidden%i' % (i + 1)])) # other connections if len(layers) == 2: # flat network, connection from in to out n.addConnection(FullConnection(n['in'], n['out'])) else: # network with hidden layer(s), connections from in to first hidden and last hidden to out n.addConnection(FullConnection(n['in'], n['hidden0'])) n.addConnection(FullConnection(n['hidden%i' % (len(layers) - 3)], n['out'])) # recurrent connections if issubclass(opt['hiddenclass'], LSTMLayer): if len(layers) > 3: errorexit("LSTM networks with > 1 hidden layers are not supported!") n.addRecurrentConnection(FullConnection(n['hidden0'], n['hidden0'])) n.sortModules() return n
def buildNetwork(*layers, **options): """Build arbitrary deep networks. `layers` should be a list or tuple of integers, that indicate how many neurons the layers shoudl have. `bias` and `outputbias` are flags to indicate wether the network should have the corresponding biases; both default to True. To adjust the classes for the layers use the `hiddenclass` and `outclass` parameters, which expect a subclass of NeuronLayer. If the `recurrent` flag is set, a RecurrentNetwork will be created, otherwise a FeedForwardNetwork. If the `fast` flag is set, faster arac networks will be used instead of the pybrain implementations.""" # options opt = { 'bias': True, 'hiddenclass': SigmoidLayer, 'outclass': LinearLayer, 'outputbias': True, 'peepholes': False, 'recurrent': False, 'fast': False, } for key in options: if key not in opt.keys(): raise NetworkError('buildNetwork unknown option: %s' % key) opt[key] = options[key] if len(layers) < 2: raise NetworkError( 'buildNetwork needs 2 arguments for input and output layers at least.' ) # Bind the right class to the Network name network_map = { (False, False): FeedForwardNetwork, (True, False): RecurrentNetwork, } try: network_map[(False, True)] = _FeedForwardNetwork network_map[(True, True)] = _RecurrentNetwork except NameError: if opt['fast']: raise NetworkError("No fast networks available.") if opt['hiddenclass'].sequential or opt['outclass'].sequential: if not opt['recurrent']: # CHECKME: a warning here? opt['recurrent'] = True Network = network_map[opt['recurrent'], opt['fast']] n = Network() # linear input layer n.addInputModule(LinearLayer(layers[0], name='in')) # output layer of type 'outclass' n.addOutputModule(opt['outclass'](layers[-1], name='out')) if opt['bias']: # add bias module and connection to out module, if desired n.addModule(BiasUnit(name='bias')) if opt['outputbias']: n.addConnection(FullConnection(n['bias'], n['out'])) # arbitrary number of hidden layers of type 'hiddenclass' for i, num in enumerate(layers[1:-1]): layername = 'hidden%i' % i n.addModule(opt['hiddenclass'](num, name=layername)) if opt['bias']: # also connect all the layers with the bias n.addConnection(FullConnection(n['bias'], n[layername])) # connections between hidden layers for i in range(len(layers) - 3): n.addConnection( FullConnection(n['hidden%i' % i], n['hidden%i' % (i + 1)])) # other connections if len(layers) == 2: # flat network, connection from in to out n.addConnection(FullConnection(n['in'], n['out'])) else: # network with hidden layer(s), connections from in to first hidden and last hidden to out n.addConnection(FullConnection(n['in'], n['hidden0'])) n.addConnection( FullConnection(n['hidden%i' % (len(layers) - 3)], n['out'])) # recurrent connections if issubclass(opt['hiddenclass'], LSTMLayer): if len(layers) > 3: errorexit( "LSTM networks with > 1 hidden layers are not supported!") n.addRecurrentConnection(FullConnection(n['hidden0'], n['hidden0'])) n.sortModules() return n