def read(self, path, length, offset): """ Reads given file """ dbg.log('*** read %s, %s, %s', (path, length, offset)) self._openedFiles[path].seek(offset) return self._openedFiles[path].read(length)
def deleteFile(self, id, file_type): """ Poslední pomocná metoda pro práci se soubory zajišťuje smazání souboru daného typu, který je určen řetězcem a to pro konkrétní neuronovou síť, která je specifikovaná pomocí identifikátoru neuronové sítě. Tato metoda se využívá při mazání neuronové sítě, kdy se zároveň mažou všechny soubory k dané neuronové síti včetně uložených klasifikátorů a dočasných souborů. Signature: neural_network.deleteFile(int id, string file_type) @id Id Neuronove site @file_type typ souboru Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu bool data true pokud se podarilo ulozit } """ file_path = server.globals.rpcObjects['neural_network'].getPath(id, file_type, bypass_rpc_status_decorator=True) if os.path.isfile(file_path): os.remove(file_path) else: dbg.log("Soubor " + file_type + " neexistuje (" + file_path +")", INFO=3) return False #endif return True
def getattr(self, path): """ Returns node attributes """ dbg.log("*** getattr %s", path) try: if isImage(path): fname = self._getCacheFilename(path) dbg.log("fname: %s", fname) if not os.path.exists(fname): st = os.stat(self.root + path) else: st = os.stat(fname) # endif else: st = os.stat(self.root + path) # endif except: dbg.logTB() # endtry return st
def createClassifier(self, neural_network_id): """ Tato metoda má na starosti vytváření klasifikátoru. Jako parametr očekává identifikátor neuronové sítě z které se má klasifikátor vytvořit. Metoda si poté načte potřebné parametry z databáze a vytvoří příslušný klasifikátor, který následně vrátí. Jedná se o pomocnou metodu, kterou využívá pouze Backend. Signature: classify.createClassifier(int neural_network_id) @param { int neural_network_id ID neuronove site } Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu object data Nacteny klasifikator } """ neural_network = server.globals.rpcObjects['neural_network'].get(neural_network_id, bypass_rpc_status_decorator=True) model_config = server.globals.rpcObjects['neural_network'].getPath(neural_network_id, 'model', bypass_rpc_status_decorator=True) # Nacteni cesty k snapshotu nad kterym se bude provadet klasifikace snapshot_path = server.globals.rpcObjects['neural_network'].getSnapshotPath(neural_network_id, neural_network['pretrained_iteration'], bypass_rpc_status_decorator=True) # Vygenerovani cesty pro mean file soubor pro klasifikaci mean_file_path = server.globals.rpcObjects['neural_network'].getPath(neural_network_id, 'mean_file', bypass_rpc_status_decorator=True) dbg.log("Classifier file paths:\nModel config: " + model_config + "\nSnapshot: " + snapshot_path + "\nMeanFile:" + mean_file_path, INFO=3) # Pokud je nastavena cesta mean file souboru, tak jej precti mean_file = None if mean_file_path: mean_file = numpy.load(mean_file_path) #endif if neural_network['gpu'] == None: gpu_mode = self.config.caffe.gpu_mode else: gpu_mode = neural_network['gpu'] caffe.set_mode_gpu() #endif # create caffe classicifer net = caffe.Classifier( model_config, snapshot_path, mean=mean_file, channel_swap=(2,1,0), raw_scale=255, ) if server.globals.config.caffe.init_networks_on_start and not neural_network_id in server.globals.neuralNetworks: if neural_network['keep_saved']: server.globals.neuralNetworks[neural_network_id] = net #endif #endif dbg.log(str(net), INFO=3) return net
def getattr(self, path): """ Returns node attributes """ dbg.log('*** getattr %s', path) try: if (isImage(path)): fname = self._getCacheFilename(path) dbg.log('fname: %s', fname) if (not os.path.exists(fname)): st = os.stat(self.root + path) else: st = os.stat(fname) #endif else: st = os.stat(self.root + path) #endif except: dbg.logTB() #endtry return st
def read(self, path, length, offset): """ Reads given file """ dbg.log("*** read %s, %s, %s", (path, length, offset)) self._openedFiles[path].seek(offset) return self._openedFiles[path].read(length)
def emit(self, record): """ Emits a record. Logs the record using the DbgLog library. """ try: severity = self.getDbgLogSeverity(record) if not severity > 0: return level = self.getDbgLogLevel(record) if not level: return kwargs = {level: severity} # Do not format message if it wont be logged. if not dbg.checkLevel(**kwargs): return # The message is already formated, prevent formatting by DbgLog msg = self.format(record).replace('%', '%%') location = (record.filename, record.funcName, record.lineno) dbg.log(msg, location=location, **kwargs) except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record)
def release(self, path, flags): """ Release given file """ dbg.log('*** release %s, %s', (path, flags)) self._openedFiles[path].close() del self._openedFiles[path] return 0
def readdir(self, path, offset): """ Returns list of nodes in directory """ dbg.log("*** readdir %s, %s", (path, offset)) for entry in os.listdir(self.root + path): if isImage(entry) or os.path.isdir(self.root + path + "/" + entry): yield fuse.Direntry(entry)
def get_scheme(self): header = self.server.getInHeadersFor('X-Scheme') dbg.log('Header: %s', header, DBG=1) scheme = header[0][1].lower() if header else None if scheme not in ('http', 'https'): scheme = 'http' #endif return scheme
def release(self, path, flags): """ Release given file """ dbg.log("*** release %s, %s", (path, flags)) self._openedFiles[path].close() del self._openedFiles[path] return 0
def picture_set__edit_pictures_POST(id, learning_set, learning_subset): dbg.log(str(request.files['file'])) data = request.files['file'].read() result = conf.backend.proxy.picture.save(id, learning_set, learning_subset, fastrpc.Binary(data)) if result.get("status") != 200: return redirect('/picture-set/edit/%d/%s/%s?status=1&message=picture_set_edit_pictures_failed'%(id, learning_set, learning_subset)) #endif return redirect('/picture-set/edit/%d/%s/%s?status=0&message=picture_set_edit_pictures_ok'%(id, learning_set, learning_subset))
def readdir(self, path, offset): """ Returns list of nodes in directory """ dbg.log('*** readdir %s, %s', (path, offset)) for entry in os.listdir(self.root + path): if (isImage(entry) or os.path.isdir(self.root + path + '/' + entry)): yield fuse.Direntry(entry)
def getPath(self, neural_network_id, file_type): """ Vrati cestu k souboru neuronove site. Cesta je vygenerovana dle ID neuronove site a dle typu souboru Signature: neural_network.getPath(int neural_network_id, string file_type) @neural_network_id Id Neuronove site @file_type Typ souboru Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu string data Cesta k souboru } """ base_folder = self.config.neural_networks.base_path if file_type == 'solver': filename = self.config.neural_networks.solver_file elif file_type == 'model': filename = self.config.neural_networks.deploy_file elif file_type == 'trainmodel': filename = self.config.neural_networks.trainmodel_file elif file_type == 'mean_file': filename = self.config.neural_networks.classify_mean_file elif file_type == 'snapshot_dir': filename = self.config.neural_networks.snapshots_folder elif file_type == 'base_dir': filename = '' elif file_type == 'temp_dir': filename = self.config.neural_networks.temp_folder elif file_type == 'log_dir': filename = self.config.neural_networks.logs_folder elif file_type == 'new_log': filename = os.path.join(self.config.neural_networks.logs_folder, datetime.datetime.now().strftime(self.config.neural_networks.log_timestamp_format) + self.config.neural_networks.log_extension) elif file_type == 'train_source_path': filename = os.path.join(self.config.neural_networks.temp_folder, self.config.neural_networks.train_db_folder) elif file_type == 'train_meanfile_path': filename = os.path.join(self.config.neural_networks.temp_folder, self.config.neural_networks.train_mean_file) elif file_type == 'validate_source_path': filename = os.path.join(self.config.neural_networks.temp_folder, self.config.neural_networks.validation_db_folder) elif file_type == 'validate_meanfile_path': filename = os.path.join(self.config.neural_networks.temp_folder, self.config.neural_networks.validation_mean_file) else: raise Exception(500, "Unknown file type (" + file_type + ")") #endif path = os.path.join(base_folder, str(neural_network_id), filename) dbg.log("path: " + str(file_type) + " | " + path) return path
def __getNextNeuralNetwork(self): """ Další interní metoda Daemona, která nevyžaduje žádné vstupní parametry. Jedná se o metodu, která zastřešuje komunikaci s Backendem díky které zjišťuje jestli existuje ve frontě pro učení neuronových sítí záznam, který je ve stavu waiting a tudíž čeká na naučení. """ # Precteme z databaze dalsi neuronovou sit pripravenou ve fronte k uceni result = self.config.backend.proxy.learning_queue.getNext() dbg.log(str(result), INFO=3) return result['data']
def save(self, picture_set_id, learning_set, learning_subset, binary): """ Tato metoda umožňuje nahrát novou fotografii do databáze fotografií. Metoda očekává čtyři parametry, kdy první tři parametry jsou identifikátory a čtvrtý parametr jsou binární data fotografie, která je nahrána z administračního rozhraní. První parametr je identifikátor databáze fotografií, druhý identifikuje kategorii do které fotografie patří a třetí identifikátor slouží pro upřesnění sekce ve které má být fotografie použita. Výstupem metody je pole, které obsahuje dvě hodnoty. Hodnota pod klíčem id udává identifikátor fotografie a hodnota pod klíčem hash udává unikátní hash v rámci systému. Signature: picture_set.delete(int picture_set_id) @picture_set_id Id sady Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu bool data Uspesne smazano } """ if learning_set not in self.config.pictures.LEARNING_SETS: raise Exception(402, "Unknown learning_set: %s" % learning_set) # endif picture_set = server.globals.rpcObjects["picture_set"].get(picture_set_id, bypass_rpc_status_decorator=True) if learning_subset not in picture_set["learning_subsets"]: raise Exception(402, "Unknown learning_subset: %s" % learning_subset) # endif # Ulozeni souboru na disk path = "%s/%d/%s/%s" % (self.config.pictures.base_path, picture_set_id, learning_set, learning_subset) dbg.log("picture.save: Path=%s", path, DBG=1) file_name = md5(binary.data).hexdigest() file_path = "%s/%s" % (path, file_name) f = open(file_path, "wb") f.write(binary.data) f.close() dbg.log("Picture saved successfully: %s", file_path, INFO=3) # Ulozeni metadat do DB query = """ INSERT INTO picture (`picture_set_id`,`learning_set`,`learning_subset_id`,`hash`) VALUE (%s, %s, %s, %s) """ params = (picture_set_id, learning_set, picture_set["learning_subsets"][learning_subset], file_name) self.cursor.execute(query, params) picture_id = self.cursor.lastrowid return {"id": picture_id, "hash": file_name}
def __startLearningProcess(self, queue_info): """ Interní metoda, která zajišťuje započatí učení neuronové sítě na frameworku Caffe. Vstupním parametrem je pole, které obsahuje načtené informace z databáze o neuronové síti a databázi fotografií na kterých se má učení provádět. """ dbg.log("Start learning network with id " + str(queue_info['neural_network_id']), INFO=3) pid = self._startCaffeLearning(queue_info['neural_network_id'], queue_info['picture_set_id'], queue_info['start_iteration']) if pid: self._savePid(pid) return True #endif return False
def _processIteration(self): """ Hlavní cyklus Daemona. Zde probíhá všechna logika Daemona, který zde kontroluje jestli aktuálně běží učení a pokud ne, tak jestli existuje neuronová síť, která čeká na učení. """ if self.__learningInProgress(): dbg.log("Learning still in progress", INFO=2) return #endif queue_info = self.__getNextNeuralNetwork() if queue_info: try: self.__startLearningProcess(queue_info) except Exception, e: dbg.log('Exception occured during starting learning process') self.__stopLearningProcess() raise
def __stopLearningProcess(self): """ Zastavení učícího procesu. Tato interní metoda je zavolána pokud Daemon dostane systémový signál SIGABRT. Po přijetí tohoto signálu dojde ke kontrole jestli nějaké učení běží a pokud ano, tak bude následně ukončeno. V dalším cyklu Daemona pak může započíst učení nové. """ dbg.log("STOP LEARNING!", INFO=3) # Zastavime ucici proces if not self.__learningInProgress(): dbg.log("Learning NOT in progress", WARN=2) return False #endif pid = self._readPid() # Odstraneni zaznamu v databazi self.config.backend.proxy.learning_queue.deleteLearning() # Odstraneni souboru s bezicim PID pid_file = self.config.caffe.pid_file if os.path.isfile(pid_file): os.remove(pid_file) else: dbg.log('PID soubor uceni neexistuje', INFO=3) return False #endif # Zastaveni processu os.kill(pid, self.KILL_SIGNAL) return True
def neural_network__learn_stat_GET(id, log_name): neural_network = {} if id: result = conf.backend.proxy.neural_network.getLogs(id) if result.get("status") != 200: return redirect('/neural-network?status=1&message=neural_network_not_found') #endif logs = result.get("data") #endif if log_name: result = conf.backend.proxy.neural_network.learningStatus(id, log_name) if result.get("status") != 200: return redirect('/neural-network?status=1&message=neural_network_log_error') #endif data = result.get("data") dbg.log("data >>>" + str(data), INFO=3) #endif return render_teng("neural-network_learn-stat.html", log_list=logs, learn_data=data)
def render_teng(template, **data): """ Vyrenderuje stranku pres Teng dataRoot - Teng data root template - Template filename """ dbg.log("Generating page %s", (template, ), INFO=2) if data is None: data = {} #endif data["YEAR"] = datetime.now().year data["STATUS"] = request.args.get("status") data["MESSAGE"] = request.args.get("message") data_root = conf.teng.createDataRoot(data) # Generate page res = conf.teng.generatePage( templateFilename=template, data=data_root, configFilename=conf.template.configFile, dictionaryFilename=conf.template.dictionaryFile, contentType="text/html", encoding="UTF-8" ) # Log if error for error in res["errorLog"]: dbg.log("%s:%s:%s: %s", (error["filename"], error["line"], error["column"], error["message"]), ERR=2) #endfor # Send page to user return res["output"]
def main(self, *a, **kw): """ main """ dbg.filename = self.log dbg.log('Root: %s', self.root) dbg.log('Cache dir: %s', self.cache_dir) if (not os.path.exists(self.cache_dir)): os.makedirs(self.cache_dir) #endif self.width = int(self.width) self.height = int(self.height) dbg.log('Size: %sx%s', (self.width, self.height)) dbg.log('Init complete.') return fuse.Fuse.main(self, *a, **kw)
def main(self, *a, **kw): """ main """ dbg.filename = self.log dbg.log("Root: %s", self.root) dbg.log("Cache dir: %s", self.cache_dir) if not os.path.exists(self.cache_dir): os.makedirs(self.cache_dir) # endif self.width = int(self.width) self.height = int(self.height) dbg.log("Size: %sx%s", (self.width, self.height)) dbg.log("Init complete.") return fuse.Fuse.main(self, *a, **kw)
def __learningInProgress(self): """ Interní metoda Daemona, která zjišťuje jestli právě probíhá nějaké učení. Metoda nevyžaduje žádné parametry a vrací hodnotu typu boolean konkrétně hodnotu True pokud nějaké učení právě probíhá. Metoda funguje tak, že pokud existuje soubor s uloženým PID, tak jej načte a následně zkontroluje jestli v systému běží proces se zadaným PID. Pokud neběží, tak vypíše do logu chybu, že daný proces neběžel a vrátí False, čímž dá najevo, že žádné aktuální učení neprobíhá. """ pid = self._readPid() if pid: # Pokud existuje soubor s PID, zkontrolujeme, ze dany proces bezi if psutil.pid_exists(pid): # Pokud proces bezi, vratime True return True else: dbg.log("Ucici proces nebezi!", INFO=3) #self.__stopLearningProcess() #endif # Pokud pidfile neexistuje, nebo je prazdny, vratime False return False
def _add_learning_subsets(self, picture_sets): """ Pomocná interní metoda, která očekává jako vstupní parametr pole s identifikátory databází fotografií a vrací pole, kde jsou přidány informace kolik je fotografií v jednotlivých kategoriích a sekcích v rámci vybraných databází fotografií. Tato metoda je využita v administračním rozhraní, kde na stránce s databázemi fotografií zobrazuje informace kolik fotografií je v daných kategoriích a sekcích. Administrátor na základě této informace může doplňovat fotografie do sekcí, které obsahují málo fotografií. """ if type(picture_sets) not in (list, tuple, set): picture_sets = [picture_sets] # endif dbg.log("picture_sets: %s", str(picture_sets), DBG=1) if picture_sets: picture_sets_dict = {} for picture_set in picture_sets: picture_set["pictures_counts"] = {} picture_set["learning_subsets"] = {} for learning_set in self.config.pictures.LEARNING_SETS: picture_set["pictures_counts"][learning_set] = {} # endfor picture_sets_dict[picture_set["id"]] = picture_set # endfor dbg.log("picture_sets_dict: %s", repr(picture_sets_dict), DBG=1) query = """ SELECT learning_subset.picture_set_id AS picture_set_id, learning_set.id AS learning_set, learning_subset.id AS learning_subset_id, learning_subset.name AS learning_subset_name, COUNT(picture.id) AS count FROM learning_set JOIN learning_subset LEFT JOIN picture ON (picture.learning_set=learning_set.id AND picture.picture_set_id=learning_subset.picture_set_id AND picture.learning_subset_id=learning_subset.id) WHERE learning_subset.picture_set_id IN (%s) GROUP BY learning_subset.picture_set_id, learning_set.id, learning_subset.id """ % ",".join( map(str, picture_sets_dict.keys()) ) self.cursor.execute(query) pictures_counts = self.cursor.fetchall() dbg.log("pictures_counts: %s", repr(pictures_counts), DBG=1) for pictures_count in pictures_counts: picture_sets_dict[pictures_count["picture_set_id"]]["pictures_counts"][pictures_count["learning_set"]][ pictures_count["learning_subset_name"] ] = pictures_count["count"] picture_sets_dict[pictures_count["picture_set_id"]]["learning_subsets"][ pictures_count["learning_subset_name"] ] = pictures_count["learning_subset_id"] # endfor # endif return picture_sets
def open(self, path, flags): """ Opens given file """ dbg.log("*** open %s, %s", (path, flags)) if not self._openedFiles.has_key(path): if not isImage(path): self._openedFiles[path] = open(self.root + path, "rb") else: fname = self._getCacheFilename(path) dbg.log("fname: %s", fname) if not os.path.exists(fname): dbg.log("Write thumbnail %s for path %s" % (fname, path)) resizeImage(self.root + path, fname, self.width, self.height, self.quality) # endif self._openedFiles[path] = open(fname, "rb") # endif # endif return 0
def open(self, path, flags): """ Opens given file """ dbg.log('*** open %s, %s', (path, flags)) if (not self._openedFiles.has_key(path)): if (not isImage(path)): self._openedFiles[path] = open(self.root + path, 'rb') else: fname = self._getCacheFilename(path) dbg.log('fname: %s', fname) if (not os.path.exists(fname)): dbg.log('Write thumbnail %s for path %s' % (fname, path)) resizeImage(self.root + path, fname, self.width, self.height, self.quality) #endif self._openedFiles[path] = open(fname, 'rb') #endif #endif return 0
def _makepath(self, path): if os.path.exists(path): dbg.log("Path already exists: %s", path, WARN=2) else: dbg.log("Creating path: %s", path, INFO=1) os.makedirs(path)
def _learningStatus(self, neural_network_id, log_name): """ Pro vypsání stavu učení slouží právě tato metoda, která jako parametry očekává identifikátor modelu o kterém má vypsat statistiku učení a databázi fotografií nad kterou se učení provádělo. Návratovou hodnotou je pole s daty, které bude možné v administračním rozhraním vykreslit do podoby grafu nebo případné jiné vizualizace. """ result = self.config.backend.proxy.neural_network.getLogPath(neural_network_id, log_name) log_path = result['data'] dbg.log(log_path, INFO=3) # Otevreni souboru s logem uceni file = open(log_path, 'r') if not file: raise self.ProcessException("Logovaci soubor uceni neexistuje (" + log_path + ")!") #endif # Priprava navratove hodnoty results = {} act_iteration = False has_snapshot = False is_restored = False # Cteni konfiguracniho souboru for line in file: # V souboru jsme nasli ze byl vytvoreny snapshot (plati pro cislo iterace uvedene pod nim) m_snapshot = re.search("Snapshotting\s+solver\s+state\s+to", line, flags=re.IGNORECASE) if m_snapshot: has_snapshot = True #endif # Pokud jsme nekdy obnovili snapshot, tak ponechame predchozi hodnoty, protoze obnova snapshotu neobsahuje namerene hodnoty m_restoring = re.search("Restoring\sprevious\ssolver\sstatus\sfrom", line, flags=re.IGNORECASE) if m_restoring: is_restored = True #endif # V souboru jsme nasli cislo testovane iterace m_iter = re.search("Iteration\s+(\d+),\s+Testing\s+net", line, flags=re.IGNORECASE) if m_iter: if not is_restored: act_iteration = int(m_iter.group(1)) results[act_iteration] = { self.ACCURACY: 0.0, self.LOSS: 0.0, self.SNAPSHOT: has_snapshot } else: is_restored = False #endif has_snapshot = False #endif # V souboru jsme nasli vysledky pro testovanou iteraci m_result = re.search("Test\s+net\s+output\s+#(\d+):\s*[^=]+=\s*((?:(?:[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)|nan))", line, flags=re.IGNORECASE) if m_result: value = m_result.group(2) if value == 'nan': value = 0 #endif value = float(value) if act_iteration: if m_result.group(1) == '0': results[act_iteration][self.ACCURACY] = value elif m_result.group(1) == '1': results[act_iteration][self.LOSS] = value #endif #endif #endif #endfor file.close() return results
def learningStatus(self, neural_network_id, learn_log): """ Účelem této metody je získat statistiku učení neuronové sítě pro daný log učení. Parametry metody jsou identifikátor neuronové sítě a název logu, který se má zpracovat. Pokud log učení neexistuje, tak tato metoda vyvolá vyjímku. Díky využití metody getLogs() pro zobrazení seznamu logů v administračním rozhraní je zajištěno, že log skutečně existuje. Klíčem v poli je číslo iterace, které se má v grafu zobrazit na ose x. Dále v poli pod tímto klíčem jsou tři prvky, kde prvek pod klíčem accuracy obsahuje hodnotu y, která udává přesnost klasifikátoru nad učícími daty. Druhý prvek je pod klíčem loss a obsahuje hodnotu y, která udává velikost chyby nad validačními daty. Třetí prvek pod klíčem snapshot obsahuje boolean hodnotu, která nám sděluje jestli se v dané iteraci ukládal snapshot či nikoliv. Tato informace je vhodná pokud v konfiguraci solveru jsou nastaveny rozdílné hodnoty parametrů test_interval a snapshot což způsobí, že ukládání probíhá jindy než validace klasifikátoru. Jelikož se tyto hodnoty čtou z logu, tak může nastat případ, že metoda bude vracet, že se klasifikátor v dané iteraci uložil, ale přitom klasifikátor na disku neexistuje. To může nastat pokud administrátor ručně smaže daný soubor z disku. Tato informace sděluje, jestli byl stav klasifikátoru uložen, nikoliv jestli aktuálně existuje. Signature: neural_network.learningStatus(int neural_network_id, string learn_log) @neural_network_id Id Neuronove site @learn_log Id nazev logu Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu array data { float accuracy presnost na ucicich datech float loss chyba na testovacich datech bool snapshot priznak ze se provedlo ulozeni klasifikatoru pro tuto iteraci } } """ log_path = server.globals.rpcObjects['neural_network'].getLogPath(neural_network_id, learn_log, bypass_rpc_status_decorator=True) dbg.log(log_path, INFO=3) # Otevreni souboru s logem uceni file = open(log_path, 'r') if not file: raise self.ProcessException("Logovaci soubor uceni neexistuje (" + log_path + ")!") #endif # Priprava navratove hodnoty results = {} act_iteration = False has_snapshot = False is_restored = False # Cteni konfiguracniho souboru for line in file: # V souboru jsme nasli ze byl vytvoreny snapshot (plati pro cislo iterace uvedene pod nim) m_snapshot = re.search("Snapshotting\s+solver\s+state\s+to", line, flags=re.IGNORECASE) if m_snapshot: has_snapshot = True #endif # Pokud jsme nekdy obnovili snapshot, tak ponechame predchozi hodnoty, protoze obnova snapshotu neobsahuje namerene hodnoty m_restoring = re.search("Restoring\sprevious\ssolver\sstatus\sfrom", line, flags=re.IGNORECASE) if m_restoring: is_restored = True #endif # V souboru jsme nasli cislo testovane iterace m_iter = re.search("Iteration\s+(\d+),\s+Testing\s+net", line, flags=re.IGNORECASE) if m_iter: if not is_restored: act_iteration = int(m_iter.group(1)) results[act_iteration] = { self.ACCURACY: 0.0, self.LOSS: 0.0, self.SNAPSHOT: has_snapshot } else: is_restored = False #endif has_snapshot = False #endif # V souboru jsme nasli vysledky pro testovanou iteraci m_result = re.search("Test\s+net\s+output\s+#(\d+):\s*[^=]+=\s*((?:(?:[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)|nan))", line, flags=re.IGNORECASE) if m_result: value = m_result.group(2) if value == 'nan': value = 0 #endif value = float(value) if act_iteration: if m_result.group(1) == '0': results[act_iteration][self.ACCURACY] = value elif m_result.group(1) == '1': results[act_iteration][self.LOSS] = value #endif #endif #endif #endfor file.close() return results
def test(self, id, picture_set_id): """ Metoda, která je schopna provést testování přesnosti neuronové sítě. Očekávané parametry metody jsou identifikátor neuronové sítě a identifikátor databáze fotografií, která se má použit pro testování. Zadaná databáze fotografií musí mít nějaké přiřazené fotografie do sekce testing, protože z této sekce se budou fotografie načítat. Je možné model testovat i na jiné databázi fotografií než na které byl naučen. To se může hodit, pokud chceme otestovat vhodnost naučeného klasifikátoru pro jinou úlohu nebo pokud chceme mít více testovacích databází fotografií pro daný klasifikátor. Návratová hodnota metody je pole ve kterém je po řádcích uložen log obsahující výsledky testování. Signature: neural_network.test(int id, int picture_set_id) @id Id Neuronove site @picture_set_id Id sady obrazku Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu array data pole s vygenerovanymi radky textu } """ params = {'learning_set': 'testing'} pictures = server.globals.rpcObjects['picture'].listSimple(picture_set_id, params, bypass_rpc_status_decorator=True) dbg.log("pictures: " + str(pictures), INFO=3) max_images = int(self.config.test.max_images) print_results = [] start = 0 correct = 0 wrong = 0 wrong_false = 0 wrong_true = 0 wrong_60 = 0 wrong_70 = 0 wrong_80 = 0 wrong_90 = 0 wrong_100 = 0 correct_sum = 0 wrong_sum = 0 wrong_false_sum = 0 wrong_true_sum = 0 stop = max_images wrong_false_files = [] wrong_true_files = [] failed_classify = 0 script_false = "#!/bin/bash\n" script_true = "#!/bin/bash\n" while 1: pictures_block = pictures[start:stop] classify_images = [] images_categories = {} if len(pictures_block) < 1: break start = stop stop += max_images for picture in pictures_block: subset = picture['learning_subset_id'] hash = picture['hash'] images_categories[hash] = subset classify_images.append({'id': hash, 'path': hash}) #endfor dbg.log("classify loop", INFO=3) results = server.globals.rpcObjects['classify'].classify(id, classify_images, bypass_rpc_status_decorator=True) dbg.log("results:" + str(results), INFO=3) failed_classify += len(pictures_block) - len(results) for hash in results: correct_category = images_categories[hash] # Kategorie v DB zacina od 1, v caffe zacina od 0 category = (results[hash][0]['category'] + 1) percentage = results[hash][0]['percentage'] if category == correct_category: correct += 1 correct_sum += percentage message='OK' else: wrong += 1 wrong_sum += percentage message='Wrong' if (category - correct_category) < 0: wrong_false += 1 wrong_false_sum += percentage wrong_false_files.append("{0:.4f}".format(percentage) + "\t" + hash) script_false += "xdg-open " + hash + "\nsleep 3\n" else: wrong_true += 1 wrong_true_sum += percentage wrong_true_files.append("{0:.4f}".format(percentage) + "\t" + hash) script_true += "xdg-open " + hash + "\nsleep 3\n" if percentage < 0.6: wrong_60 += 1 elif percentage < 0.7: wrong_70 += 1 elif percentage < 0.8: wrong_80 += 1 elif percentage < 0.9: wrong_90 += 1 elif percentage < 1: wrong_100 += 1 #print_results.append(hash + ":\n\t" + message + "\t(" + "{0:.4f}".format(percentage) + ")") #endfor #endwhile script_false += "sleep 300" script_true += "sleep 300" print_results.append("----------------------------------------") print_results.append("Script True") print_results.append(script_true) print_results.append("Script False") print_results.append(script_false) print_results.append("----------------------------------------") print_results.append("Wrong True files") # for record in wrong_true_files: # print_results.append(record) print_results.append("----------------------------------------") print_results.append("Wrong False files") for record in wrong_false_files: print_results.append(record) print_results.append("----------------------------------------") print_results.append("Wrong") print_results.append("Wrong False:\t" + str(wrong_false)) print_results.append("Wrong True:\t" + str(wrong_true)) print_results.append("Wrong < 0.6:\t" + str(wrong_60)) print_results.append("Wrong < 0.7:\t" + str(wrong_70)) print_results.append("Wrong < 0.8:\t" + str(wrong_80)) print_results.append("Wrong < 0.9:\t" + str(wrong_90)) print_results.append("Wrong < 1.0:\t" + str(wrong_100)) print_results.append("----------------------------------------") print_results.append("Average values") if correct > 0: print_results.append("Correct:\t\t" + str(correct_sum/correct)) if wrong > 0: print_results.append("Wrong:\t\t" + str(wrong_sum/wrong)) if wrong_true > 0: print_results.append("Wrong True:\t" + str(wrong_true_sum/wrong_true)) if wrong_false > 0: print_results.append("Wrong False:\t" + str(wrong_false_sum/wrong_false)) print_results.append("----------------------------------------") print_results.append("Final results") print_results.append("Failed:\t\t" + str(failed_classify)) print_results.append("Correct:\t\t" + str(correct)) print_results.append("Wrong:\t\t" + str(wrong)) print_results.append("Total:\t\t" + str(correct + wrong)) return print_results
def classify(self, neural_network_id, images, number_of_categories = None): """ Funkce pro zpracovani obrazku Signature: classify.classify(int neural_network_id, struct images) @param { int neuralNetworkId ID neuronove site array( struct { imageId ID obrazku path Cesta k obrazku } ) } Returns: struct { int status 200 = OK string statusMessage Textovy popis stavu struct data { imageId { category Cislo kategorie percentage Velikost shody s danou kategorii } } } """ # Nacteni nebo vytvoreni klasifikatoru if neural_network_id in server.globals.neuralNetworks: net = server.globals.neuralNetworks[neural_network_id] else: net = self.createClassifier(neural_network_id, bypass_rpc_status_decorator=True) #endif # if we get only one image, convert it to array of one image object if not isinstance(images, list): images = [images] # array of loaded images input_images=[] for image in images: if 'data' in image: input_images.append(self._load_image_from_binary(image['data'].data)) elif 'path' in image: try: input_images.append(caffe.io.load_image(image['path'])) except Exception as e: dbg.log('Exception - ' + image['path'] + ': ' + str(e), ERR=3) #endif # start prediction prediction = [] try: prediction = net.predict(input_images) except Exception as e: dbg.log('Exception - prediction: ' + str(e), ERR=3) # process results result={} i = 0 # crop categories array if number_of_categories == None: slice_size = int(self.config.classify.number_of_categories) else: slice_size = int(number_of_categories) #endif # go through all predicted images for scores in prediction: # get category id with best match categoryIds = (-scores).argsort() if slice_size != 0: categoryIds = categoryIds[:slice_size] # save prediction results categories = [] for id in categoryIds: categories.append({"category":id,"percentage":float(scores[id])}) result[str(images[i]['id'])] = categories; i += 1 return result
def _startCaffeLearning(self, neural_network_id, picture_set, start_iteration = 0): """ Pomocná metoda, která zastřešuje započatí učení nad Frameworkem Caffe. V této metodě se volají veškeré pomocné skripty, které jsou potřeba, aby mohlo započít učení. Metoda očekává tři parametry kterými jsou identifikátor neuronové sítě, identifikátor databáze fotografií a volitelný parametr, který udává číslo iterace od kterého se má učení spustit. Tento parametr se využívá, pokud již klasifikátor naučený byl a chceme v učení pokračovat. Pokud se tento parametr nevyplní, tak se jako výchozí hodnota nastaví hodnota 0, tudíž bude klasifikátor učen od začátku. """ learn_script = self.config.caffe.learn_script create_imagenet_script = self.config.caffe.create_imagenet_script create_mean_file_script = self.config.caffe.create_mean_file_script # Cteni konfigurace solveru z databaze solver_config_path = self._getPath(neural_network_id, 'solver') solver_config = util.readProtoSolverFile(solver_config_path) # Parsovani cest ze souboru imagenet_train_val.prototxt layer_config = util.readProtoLayerFile(solver_config.net) layer_paths = util.parseLayerPaths(layer_config) # Ziskat picture set a vygenerovat soubory s cestami k obrazkum (validacni a ucici) picture_files = self._createFilesWithImages(neural_network_id, picture_set) # Otevreni souboru pro zapis learn_log_path = self._getPath(neural_network_id, 'new_log') dir = os.path.dirname(learn_log_path) if not os.path.exists(dir): os.makedirs(dir) #endif dbg.log('Learning log: ' + learn_log_path, INFO=3) learn_log = open(learn_log_path, 'w') if not learn_log: raise self.ProcessException("Nemuzu vytvorit soubor s logem uceni (" + learn_log_path + ")!") #endif # Vymazat stare uloznene obrazky pokud existuji if os.path.exists(layer_paths[util.TRAIN][util.SOURCE]): shutil.rmtree(layer_paths[util.TRAIN][util.SOURCE]) endif if os.path.exists(layer_paths[util.VALIDATE][util.SOURCE]): shutil.rmtree(layer_paths[util.VALIDATE][util.SOURCE]) endif # Vytvoreni argumentu pro spusteni skriptu pro vytvoreni databaze obrazku. Prvni parametr je cesta ke skriptu create_args = [] create_args.append(create_imagenet_script) create_args.append(picture_files[util.TRAIN]) create_args.append(picture_files[util.VALIDATE]) create_args.append(layer_paths[util.TRAIN][util.SOURCE]) create_args.append(layer_paths[util.VALIDATE][util.SOURCE]) dbg.log("create_args " + str(create_args), INFO=3) # Vytvorit imagenet pomoci souboru s obrazky a zadanych cest kde se maji vytvorit subprocess.call(create_args) # Vytvoreni argumentu pro spusteni skriptu pro vytvoreni mean souboru obrazku pro trenovaci obrazky create_mean_file_args = [] create_mean_file_args.append(create_mean_file_script) create_mean_file_args.append(layer_paths[util.TRAIN][util.SOURCE]) create_mean_file_args.append(layer_paths[util.TRAIN][util.MEAN_FILE]) dbg.log("create_mean_file_args " + str(create_mean_file_args), INFO=3) # Vytvorit mean file pro trenovaci obrazky subprocess.call(create_mean_file_args) # Vygenerovani cesty pro mean file soubor pro klasifikaci mean_file_path = self._getPath(neural_network_id, 'mean_file') dir = os.path.dirname(mean_file_path) if not os.path.exists(dir): os.makedirs(dir) #endif # Vytvoreni binarniho souboru, ktery dokaze nacist numpy. # Tento soubor je potreba pro klasifikaci obrazku, vyse vytvoreny mean file se pouziva pro trenovani site. self._createClassifyMeanFile(layer_paths[util.TRAIN][util.MEAN_FILE], mean_file_path) # Vytvoreni argumentu pro spusteni skriptu pro vytvoreni mean souboru obrazku pro validacni obrazky create_mean_file_args = [] create_mean_file_args.append(create_mean_file_script) create_mean_file_args.append(layer_paths[util.VALIDATE][util.SOURCE]) create_mean_file_args.append(layer_paths[util.VALIDATE][util.MEAN_FILE]) # Vytvorit mean file pro validacni obrazky subprocess.call(create_mean_file_args) # Vytvoreni solver souboru pro uceni self._generateSolverFile(solver_config_path, network['id']) # Vytvoreni argumentu pro spusteni skriptu pro uceni neuronove site. Prvni parametr je cesta ke skriptu learn_args = [] learn_args.append(learn_script) learn_args.append('train') learn_args.append('-solver=' + solver_config_path) if start_iteration: if not solver_config.snapshot_prefix: raise self.ProcessException("Nepodarilo se precist prefix nazvu souboru s ulozenym ucenim (" + solver_config.snapshot_prefix + ")!") #endif dbg.log("Prefix souboru s ulozenym ucenim: " + solver_config.snapshot_prefix, INFO=3) result = self.config.backend.proxy.neural_network.getSnapshotStatePath(neural_network_id, start_iteration) saved_file_path = result['data'] learn_args.append('-snapshot=' + saved_file_path) #endif dbg.log(str(learn_args), INFO=3) p = subprocess.Popen(learn_args, stderr=learn_log, stdout=learn_log) if p: return p.pid #endif return False