def CreateTrainer(self): """ This method preparing PyBrain trainer. """ backpropTrainer = None FCLogger.info('Initializing PyBrain backpropagating trainer...') try: if self.network: if self.dataSet: FCLogger.debug('Trainer using parameters:') FCLogger.debug(' - PyBrain network previously created,') FCLogger.debug(' - PyBrain dataset previously created,') FCLogger.debug(' - epoch parameter: {}'.format(self._epochs)) FCLogger.debug(' - network learning rate parameter: {}'.format(self._learningRate)) FCLogger.debug(' - momentum parameter: {}'.format(self._momentum)) backpropTrainer = BackpropTrainer(self.network, self.dataSet, learningrate=self._learningRate, momentum=self._momentum) else: raise Exception('PyBrain dataset not exist!') else: raise Exception('PyBrain network not exist!') FCLogger.info('PyBrain network successfully created.') except: backpropTrainer = None FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while creating PyBrain trainer!') finally: self.trainer = backpropTrainer
def SaveNetwork(self): """ Creating dump of network. """ FCLogger.debug('Saving network to PyBrain xml-formatted file...') NetworkWriter.writeToFile(self.network, self.networkFile) FCLogger.info('Network saved to file: {}'.format(os.path.abspath(self.networkFile)))
def CreateReport(self, results=None, fuzzyOutput=True): """ Creating text report after classificate vector-candidates. results is a list of tuples in ClassificationResults() format. fuzzyOutput is a key for show fuzzy values if True. """ FCLogger.debug('Creating Classificate Report File...') noReportCreationErrors = True # successful of Creating Report process flag try: if not results: results = self.ClassificationResults(fullEval=True, needFuzzy=fuzzyOutput) with open(self.reportFile, 'w') as fH: fH.write('Neuronet: {}\n\n'.format( os.path.abspath(self.networkFile))) fH.write('{}\n\n'.format(self.scale)) fH.write('Classification results for candidates vectors:\n\n') head = ' Header: [{}]\t[{}]\n'.format( ' '.join(header for header in self.headers[:self.config[0]]), ' '.join(header for header in self.headers[len(self.headers) - self.config[-1]:]) if len(self.headers) >= self.config[0] + self.config[-1] else '') fH.write(head) fH.write( ' {}\n'.format('-' * len(head) if len(head) < 100 else '-' * 100)) for result in results: if fuzzyOutput: fH.write(' Input: {}\tOutput: {}{}\n'.format( result[0], result[1], '\tExpected: {}'.format( result[2]) if result[2] else '')) else: fH.write(' Input: {}\tOutput: {}{}\n'.format( result[0], result[1], '\tExpected: {}\tError: {}'.format( result[2], result[3]) if result[2] else '')) FCLogger.info('Classificate Report File created: ' + os.path.abspath(self.reportFile)) except: noReportCreationErrors = False FCLogger.error(traceback.format_exc()) FCLogger.error( 'An error occurred while Classificate Report creating!') finally: return noReportCreationErrors
def SaveNetwork(self): """ Creating dump of network. """ FCLogger.debug('Saving network to PyBrain xml-formatted file...') NetworkWriter.writeToFile(self.network, self.networkFile) FCLogger.info('Network saved to file: {}'.format( os.path.abspath(self.networkFile)))
def SaveNetwork(self): """ Creating dump of network. """ FCLogger.debug( 'Autosaving - enabled. Trying to save network as PyBrain xml-formatted file...' ) NetworkWriter.writeToFile(self.network, self.networkFile) FCLogger.info('Current network saved to file: {}'.format( os.path.abspath(self.networkFile)))
def LoadNetwork(self): """ Loading network dump from file. """ FCLogger.debug('Loading network from PyBrain xml-formatted file...') net = None if os.path.exists(self.networkFile): net = NetworkReader.readFrom(self.networkFile) FCLogger.info('Network loaded from dump-file: {}'.format(os.path.abspath(self.networkFile))) else: FCLogger.warning('{} - file with Neural Network configuration not exist!'.format(os.path.abspath(self.networkFile))) self.network = net
def PrepareDataSet(self): """ This method preparing PyBrain dataset from raw data file. """ learnData = None FCLogger.info( 'Converting parsed raw-data into PyBrain dataset format...') try: if self.config: if len(self.config) > 2: learnData = SupervisedDataSet( self.config[0], self.config[-1] ) # first and last values in config tuple else: raise Exception( 'Network config must contains more than 2 parameters!') else: raise Exception('Network config not defined!') # add samples from defuz raw-data as [[input_vector], [output_vector]] for PyBrain network: for sample in self._rawDefuzData: learnData.addSample( sample[:self.config[0]], sample[self.config[0]:self.config[0] + self.config[-1]]) FCLogger.debug( 'PyBrain dataset vectors - target (output) and input:') for line in str(learnData).split('\n'): if line: FCLogger.debug(' {}'.format(line)) FCLogger.info('PyBrain dataset successfully prepared.') except: learnData = None FCLogger.error(traceback.format_exc()) FCLogger.error( 'An error occurred while preparing PyBrain dataset!') finally: self.dataSet = learnData
def CreateNetwork(self): """ This method creating instance of PyBrain network. """ net = None FCLogger.info('Creating PyBrain network...') try: if self.config: if len(self.config) > 2: hLayers = self.config[1:-1] # parameters for hidden layers FCLogger.debug('Neuronet configuration: Config = <inputs, {layers}, outputs>') FCLogger.debug(' - inputs is dimension of all input vectors: {},'.format(self.config[0])) FCLogger.debug(' - outputs is dimension of all output vectors: {},'.format(self.config[-1])) FCLogger.debug(' - count of hidden layers for Neuronet: {},'.format(len(hLayers))) if len(hLayers) <= 10: for nNum, dim in enumerate(hLayers): FCLogger.debug(' ... dimension of {} hidden layer: {}'.format(nNum, dim)) else: FCLogger.debug(' ... dimension of 0 hidden layer: {}'.format(hLayers[0])) FCLogger.debug(' ... dimension of 1 hidden layer: {}'.format(hLayers[1])) FCLogger.debug(' ... skipped ...') FCLogger.debug(' ... dimension of {} hidden layer: {}'.format(len(hLayers) - 2, hLayers[-2])) FCLogger.debug(' ... dimension of {} hidden layer: {}'.format(len(hLayers) - 1, hLayers[-1])) net = buildNetwork(*self.config) # create network with config else: raise Exception('Network config must contains at least 3 parameters: (inputs_count, layer1_count, outputs_count)!') else: raise Exception('Network config not defined!') FCLogger.info('PyBrain network successfully created.') except: net = None FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while preparing PyBrain network!') finally: self.network = net
def LoadNetwork(self): """ Loading network dump from file. """ FCLogger.debug('Loading network from PyBrain xml-formatted file...') net = None if os.path.exists(self.networkFile): net = NetworkReader.readFrom(self.networkFile) FCLogger.info('Network loaded from dump-file: {}'.format( os.path.abspath(self.networkFile))) else: FCLogger.warning( '{} - file with Neural Network configuration not exist!'. format(os.path.abspath(self.networkFile))) self.network = net
def CreateTrainer(self): """ This method preparing PyBrain trainer. """ backpropTrainer = None FCLogger.info('Initializing PyBrain backpropagating trainer...') try: if self.network: if self.dataSet: FCLogger.debug('Trainer using parameters:') FCLogger.debug(' - PyBrain network previously created,') FCLogger.debug(' - PyBrain dataset previously created,') FCLogger.debug(' - epoch parameter: {}'.format( self._epochs)) FCLogger.debug( ' - network learning rate parameter: {}'.format( self._learningRate)) FCLogger.debug(' - momentum parameter: {}'.format( self._momentum)) backpropTrainer = BackpropTrainer( self.network, self.dataSet, learningrate=self._learningRate, momentum=self._momentum) else: raise Exception('PyBrain dataset not exist!') else: raise Exception('PyBrain network not exist!') FCLogger.info('PyBrain network successfully created.') except: backpropTrainer = None FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while creating PyBrain trainer!') finally: self.trainer = backpropTrainer
def DefuzRawData(self): """ Functions parse raw text data and converting fuzzy values to its real represents. """ FCLogger.info('Defuzzyficating raw data ...') defuzData = [] try: for line in self.rawData: defuzValues = [] for itemValue in line: num = 0 try: num = float(itemValue) except Exception: level = self.scale.GetLevelByName( levelName=itemValue.capitalize()) if level: num = level['fSet'].Defuz() else: FCLogger.warning( itemValue + ' - is not correct real or fuzzy value! It is reset at 0.' ) defuzValues.append(num) defuzData.append(defuzValues) except Exception: defuzData = [] FCLogger.error(traceback.format_exc()) FCLogger.error( 'An error occurred while defuzzyficating values in raw data!') finally: self._rawDefuzData = defuzData
def ParseRawDataFile(self): """ Get list of lines with raw string data without first header-line and empty lines. """ raw = [] FCLogger.info('Parsing file with raw data...') try: if self.rawDataFile: with open(self.rawDataFile, newline='') as csvfile: FCLogger.debug('Opened file: {}'.format(self.rawDataFile)) for row in csv.reader(csvfile, delimiter='\t'): if row: raw.append(row) if raw: raw = raw[1:] # use data without first header-line FCLogger.debug('Parsed raw-data vectors:') if len(raw) <= 5: for line in raw: FCLogger.debug(' {}'.format(line)) else: FCLogger.debug(' {}'.format(raw[0])) FCLogger.debug(' {}'.format(raw[1])) FCLogger.debug(' [ ... skipped ... ]') FCLogger.debug(' {}'.format(raw[-2])) FCLogger.debug(' {}'.format(raw[-1])) FCLogger.info('File with raw data successfully parsed.') except: raw = [] FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while parsing raw data file!') finally: self.rawData = raw # list of input vectors without first header line
def PrepareDataSet(self): """ This method preparing PyBrain dataset from raw data file. """ learnData = None FCLogger.info('Converting parsed raw-data into PyBrain dataset format...') try: if self.config: if len(self.config) > 2: learnData = SupervisedDataSet(self.config[0], self.config[-1]) # first and last values in config tuple else: raise Exception('Network config must contains more than 2 parameters!') else: raise Exception('Network config not defined!') # add samples from defuz raw-data as [[input_vector], [output_vector]] for PyBrain network: for sample in self._rawDefuzData: learnData.addSample(sample[:self.config[0]], sample[self.config[0]:self.config[0] + self.config[-1]]) FCLogger.debug('PyBrain dataset vectors - target (output) and input:') for line in str(learnData).split('\n'): if line: FCLogger.debug(' {}'.format(line)) FCLogger.info('PyBrain dataset successfully prepared.') except: learnData = None FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while preparing PyBrain dataset!') finally: self.dataSet = learnData
def CreateReport(self, results=None, fuzzyOutput=True): """ Creating text report after classificate vector-candidates. results is a list of tuples in ClassificationResults() format. fuzzyOutput is a key for show fuzzy values if True. """ noReportCreationErrors = True # successful of Creating Report process flag FCLogger.debug('Creating Classificate Report File...') try: if not results: results = self.ClassificationResults(fullEval=True, needFuzzy=fuzzyOutput) with open(self.reportFile, 'w') as fH: fH.write('Neuronet: {}\n\n'.format(os.path.abspath(self.networkFile))) fH.write('{}\n\n'.format(self.scale)) fH.write('Classification results for candidates vectors:\n\n') for result in results: if fuzzyOutput: fH.write(' Input: {}\tOutput: {}{}\n'.format( result[0], result[1], '\tExpected: {}'.format(result[2]) if result[2] else '')) else: fH.write(' Input: {}\tOutput: {}{}\n'.format( result[0], result[1], '\tExpected: {}\tError: {}'.format(result[2], result[3]) if result[2] else '')) FCLogger.info('Classificate Report File created: {}'.format(os.path.abspath(self.reportFile))) except: noReportCreationErrors = False FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while Classificate Report creating!') finally: return noReportCreationErrors
def Train(self): """ Realize training mechanism. """ try: if self._epochs > 0: if self.trainer: started = datetime.now() FCLogger.info('Max epochs: ' + str(self._epochs)) if os.path.exists(self.bestNetworkFile): os.remove(self.bestNetworkFile ) # remove old best network before training if os.path.exists(self.bestNetworkInfoFile): os.remove( self.bestNetworkInfoFile ) # remove best network info file before training for epoch in range(self._epochs): # --- Updating current progress: self.progress = (epoch + 1) * 100 / self._epochs if (0 < epoch < self._epochs - 1) and (epoch + 1) % self._epochsToUpdate == 0: totTimeSeconds = (datetime.now() - started).total_seconds() timeRemainingSeconds = round(totTimeSeconds / self.progress * 100 - totTimeSeconds) timeInfo = ', total time: {}, time remaining: {}'.format( timedelta(seconds=round(totTimeSeconds)), timedelta(seconds=timeRemainingSeconds)) else: timeInfo = '' FCLogger.info( 'Progress: {:.2f}% (epoch: {} in {}{})'.format( self.progress, self.trainer.epoch + 1, self._epochs, timeInfo)) if (epoch + 1) % self._epochsToUpdate == 0: # Current results is the list of result vectors: [[defuzInput, outputVector, defuzExpectedVector, errorVector], ...]: currentResult = self.ClassificationResults( fullEval=True, needFuzzy=False, showExpectedVector=True, printLog=False) # Counting error as length of list with only vectors with euclidian norm between expected vector and current vector given error > self._epsilon: vectorsWithErrors = [ vecError[3] for vecError in currentResult if math.sqrt(sum([x * x for x in vecError[3]])) > self._epsilon ] self.currentFalsePercent = len( vectorsWithErrors) * 100 / len(currentResult) errorString = '{:.1f}% ({} of {})'.format( self.currentFalsePercent, len(vectorsWithErrors), len(currentResult)) FCLogger.info( ' - false classificated of vectors: ' + errorString) if epoch == 0: self.bestNetworkFalsePercent = self.currentFalsePercent # best percent after first epoch # --- Saving current best network: if self.currentFalsePercent < self.bestNetworkFalsePercent: if os.path.exists(self.networkFile): self.bestNetworkFalsePercent = self.currentFalsePercent FCLogger.info('Best network found:') FCLogger.info(' Config: ' + str(self.config)) FCLogger.info(' Epoch: ' + str(epoch + 1)) FCLogger.info( ' Number of error vectors (Euclidian norm > epsilon): ' + errorString) with open(self.bestNetworkInfoFile, 'w') as fH: fH.write('Best network common results:\n') fH.write(' Config: ' + str(self.config) + '\n') fH.write(' Epoch: ' + str(epoch + 1) + '\n') fH.write( ' Number of error vectors (Euclidian norm > epsilon): ' + errorString + '\n\n') fH.write( 'All of learning parameters of FuzzyNeuroNetwork object:\n' + '-' * 80 + '\n') for param in sorted(self.__dict__): fH.write(' ' + param + ' = ' + str(self.__dict__[param]) + '\n\n') shutil.copyfile(self.networkFile, self.bestNetworkFile) FCLogger.info( 'Best network saved to file: ' + os.path.abspath(self.bestNetworkFile)) FCLogger.info( 'Common information about best network saved to file: ' + os.path.abspath(self.bestNetworkInfoFile)) # --- Stop train if the best network found: if self.currentFalsePercent <= self._stop: FCLogger.info( 'Current percent of false classificated vectors is {:.1f}% less than stop value {:.1f}%.' .format(self.currentFalsePercent, self._stop)) break self.trainer.train() # training network if epoch % 10 == 0: self.SaveNetwork() # dump network every 10th time if self._epochs > 1: self.SaveNetwork( ) # save network at the end of learning # --- Replace last network with the best network: if os.path.exists(self.networkFile) and os.path.exists( self.bestNetworkFile): os.remove(self.networkFile) shutil.copyfile(self.bestNetworkFile, self.networkFile) FCLogger.info( 'Current network replace with the best network.') durationSeconds = round( (datetime.now() - started).total_seconds()) FCLogger.info('Duration of learning: {}'.format( timedelta(seconds=durationSeconds))) else: raise Exception('Trainer instance not created!') else: FCLogger.warning( 'Epoch of learning count is 0. Train not run!') except Exception: FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while Training Fuzzy Network!') return False return True
def CreateNetwork(self): """ This method creating instance of PyBrain network. """ FCLogger.info('Creating PyBrain network...') net = None try: if self.config: if len(self.config) > 2: hLayers = self.config[1:-1] # parameters for hidden layers FCLogger.info( 'Neuronet configuration: Config = <inputs, {layers}, outputs>' ) FCLogger.info( ' - inputs is dimension of all input vectors: ' + str(self.config[0])) FCLogger.info( ' - outputs is dimension of all output vectors: ' + str(self.config[-1])) FCLogger.info( ' - count of hidden layers for Neuronet: ' + str(len(hLayers))) if len(hLayers) <= 10: for nNum, dim in enumerate(hLayers): FCLogger.info(' ... dimension of ' + str(nNum) + ' hidden layer: ' + str(dim)) else: FCLogger.info( ' ... dimension of 0 hidden layer: ' + str(hLayers[0])) FCLogger.info( ' ... dimension of 1 hidden layer: ' + str(hLayers[1])) FCLogger.info(' ... skipped ...') FCLogger.info(' ... dimension of ' + str(len(hLayers) - 2) + ' hidden layer: ' + str(hLayers[-2])) FCLogger.info(' ... dimension of ' + str(len(hLayers) - 1) + ' hidden layer: {}' + str(hLayers[-1])) net = buildNetwork( *self.config) # create network with config else: raise Exception( 'Network config must contains at least 3 parameters: (inputs_count, layer1_count, outputs_count)!' ) else: raise Exception('Network config not defined!') FCLogger.info('PyBrain network successfully created.') except Exception: net = None FCLogger.error(traceback.format_exc()) FCLogger.error( 'An error occurred while preparing PyBrain network!') finally: self.network = net
def PrepareDataSet(self): """ This method preparing PyBrain dataset from raw data file. """ FCLogger.info( 'Converting parsed and defuzzificated raw-data into PyBrain dataset format...' ) learnData = None try: if self.config: if len(self.config) > 2: learnData = SupervisedDataSet( self.config[0], self.config[-1] ) # first and last values in config tuple else: raise Exception( 'Network config must contains more than 2 parameters!') else: raise Exception('Network config not defined!') # add samples from defuz raw-data as [[input_vector], [output_vector]] for PyBrain network: for sample in self._rawDefuzData: learnData.addSample( sample[:self.config[0]], sample[self.config[0]:self.config[0] + self.config[-1]]) FCLogger.debug( 'PyBrain dataset vectors, inputs and outputs (targets):') allInputs = learnData.data['input'][:learnData.endmarker['input']] learnDataInputsString = str(allInputs).split('\n') FCLogger.debug("- input vectors, dim({}, {}):".format( len(allInputs[0]), len(allInputs))) if len(allInputs) <= 10: for strValue in learnDataInputsString: FCLogger.debug(' ' + strValue) else: FCLogger.debug(' ' + learnDataInputsString[0]) FCLogger.debug(' ' + learnDataInputsString[1]) FCLogger.debug(' [ ... skipped ... ]') FCLogger.debug(' ' + learnDataInputsString[-2]) FCLogger.debug(' ' + learnDataInputsString[-1]) allTargets = learnData.data['target'][:learnData. endmarker['target']] learnDataTargetsString = str(allTargets).split('\n') FCLogger.debug("- output vectors, dim({}, {}):".format( len(allTargets[0]), len(allTargets))) if len(allTargets) <= 10: for strValue in learnDataTargetsString: FCLogger.debug(' ' + strValue) else: FCLogger.debug(' ' + learnDataTargetsString[0]) FCLogger.debug(' ' + learnDataTargetsString[1]) FCLogger.debug(' [ ... skipped ... ]') FCLogger.debug(' ' + learnDataTargetsString[-2]) FCLogger.debug(' ' + learnDataTargetsString[-1]) FCLogger.info('PyBrain dataset successfully prepared.') except Exception: learnData = None FCLogger.error(traceback.format_exc()) FCLogger.error( 'An error occurred while preparing PyBrain dataset! Check your configuration parameters!' ) finally: self.dataSet = learnData
def ParseRawDataFile(self): """ Get list of lines with raw string data without first header-line and empty lines. """ FCLogger.info('Parsing file with raw data...') raw = [] try: if self.rawDataFile: with open(self.rawDataFile, newline='') as csvfile: FCLogger.debug('Opened file: ' + self.rawDataFile) FCLogger.debug('Separator symbol used: {}'.format( 'TAB' if self.separator == '\t' else '{}'.format('SPACE' if self.separator == ' ' else self.separator))) FCLogger.debug('Ignored row indexes (1st row is 0): ' + str(self.ignoreRows)) FCLogger.debug( 'Ignored column indexes (1st column is 0): ' + str(self.ignoreColumns)) for row in csv.reader(csvfile, delimiter=self._separator): if row: raw.append(row) if raw: newRaw = [] # removing ignored rows and columns: for indexRow, row in enumerate(raw): if indexRow not in self._ignoreRows or indexRow == 0: newline = [] for indexCol, col in enumerate(row): if indexCol not in self._ignoreColumns: newline.append(col) newRaw.append(newline) self.headers = newRaw[ 0] # header-line is always 1st line in input file raw = newRaw[1:] # cut headers FCLogger.debug( 'Parsed raw-data (without ignored rows and columns):') if len(raw) <= 10: for line in raw: if len(line) <= 10: FCLogger.debug(' ' + str(line)) else: FCLogger.debug( ' [{}, {}, ..., {}, {}]'.format( line[0], line[1], line[-2], line[-1])) else: FCLogger.debug(' {}'.format(raw[0] if len( raw[0]) <= 10 else '[{}, {}, ..., {}, {}]'.format( raw[0][0], raw[0][1], raw[0][-2], raw[0][-1]))) FCLogger.debug(' {}'.format(raw[0] if len( raw[1]) <= 10 else '[{}, {}, ..., {}, {}]'.format( raw[1][0], raw[1][1], raw[1][-2], raw[1][-1]))) FCLogger.debug(' [ ... skipped ... ]') FCLogger.debug( ' {}'.format(raw[0] if len(raw[0]) <= 10 else '[{}, {}, ..., {}, {}]'. format(raw[-2][0], raw[-2][1], raw[-2][-2], raw[-2][-1]))) FCLogger.debug( ' {}'.format(raw[0] if len(raw[0]) <= 10 else '[{}, {}, ..., {}, {}]'. format(raw[-1][0], raw[-1][1], raw[-1][-2], raw[-1][-1]))) FCLogger.info('File with raw data successfully parsed.') else: FCLogger.warning('File with raw data not define or not exist!') except Exception: raw = [] self.headers = [] FCLogger.error(traceback.format_exc()) FCLogger.error('An error occurred while parsing raw data file!') finally: if not raw: FCLogger.warning('Empty raw data file!') self.rawData = raw # list of input vectors without first header line self.DefuzRawData() # defuzzificating raw data