def loadNetParamFromString(paramstring): from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() net = proto.NetParameter() try: net.ParseFromString(paramstring) return net except: pass
def buildRootInfo(self, name=""): """ Builds "solver" info object of the state dictionary """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() protosolver = proto.SolverParameter() descr = info.ParameterGroupDescriptor(protosolver) params = descr.parameter().copy() return self.buildInfo(name,params, [])
def __initAvailableLayerTypes(self): """Generate information about available layer types only once. self.__initAvailableParameterGroupDescriptors() needs to be called before this method.""" from backend.caffe.path_loader import PathLoader caffe = PathLoader().importCaffe() layerNameMainParts = list(caffe.layer_type_list()) res = {} paramsPerLayerType = {} # calculate common parameters of all layer types # by removing all which will be used for one specific layer type only # also keep in mind which ones have been removed to readd them to specific layers commonParams = self._availableParameterGroupDescriptors[ "LayerParameter"].parameter() #use .parameter() on purpose layerSpecificParameters = set() for nameMainPart in layerNameMainParts: specificParamsName = [nameMainPart + "Parameter"] if moreLayerNameParameter.has_key(nameMainPart): specificParamsName.append(moreLayerNameParameter[nameMainPart]) paramsPerLayerType[nameMainPart] = {} for key, value in commonParams.items(): if value.isParameterGroup() and value.parameterName( ) in specificParamsName: paramsPerLayerType[nameMainPart][key] = value layerSpecificParameters.add(key) # special case: shared params for loss layers key = "loss_param" value = commonParams[key] del commonParams[key] for nameMainPart in layerNameMainParts: if LayerType.getCategoryByName( nameMainPart) == LayerType.CATEGORY_LOSS: paramsPerLayerType[nameMainPart][key] = value # TODO is there a special case for the TransformationParameter? # create each layer type after one another for nameMainPart in layerNameMainParts: # add common params to the specific ones layerTypeParam = paramsPerLayerType[nameMainPart].keys() paramsPerLayerType[nameMainPart].update(commonParams) irrelevant = layerSpecificParameters.difference(layerTypeParam) res[nameMainPart] = LayerType(nameMainPart, paramsPerLayerType[nameMainPart], layerTypeParam, irrelevant) self._commonParams = commonParams self._availableLayerTypes = res
def getIterFromSolverstate(solverstate): """ Parse the iterations from the solverstate file. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() try: state = proto.SolverState() with open(solverstate, 'rb') as f: state.ParseFromString(f.read()) return state.iter except Exception as e: print(str(e))
def loadNetParameter(caffemodel): """ Return a NetParameter protocol buffer loaded from the caffemodel. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() net = proto.NetParameter() try: with open(caffemodel, 'rb') as f: net.ParseFromString(f.read()) return net except: pass
def getCaffemodelFromSolverstate(solverstate): """ Parse the filename of the caffemodel file from the solverstate file. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() try: state = proto.SolverState() with open(solverstate, 'rb') as f: state.ParseFromString(f.read()) return state.learned_net except Exception as e: print(str(e))
def _import_dictionary(netdict): """fill the ProtoTxt-Net with data from the dictionary""" from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() net = proto.NetParameter() for entry in netdict: if entry == "layerOrder": continue if entry == "layers": _extract_layer(netdict["layers"], netdict["layerOrder"], net) continue _insert(entry, netdict[entry], net) return net
def bareNet(name): """ Creates a dictionary of a networks with default values where required. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() net = proto.NetParameter() descr = info.ParameterGroupDescriptor(net) params = descr.parameter().copy() del params["layer"] del params["layers"] res = _extract_param(net, params) res["layers"] = {} res["layerOrder"] = [] res["name"] = unicode(name) return res
def loadSolver(solverstring): """ Return a dictionary which represent the caffe-solver-prototxt solverstring """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() solver = proto.SolverParameter() # Get DESCRIPTION for meta infos descr = info.ParameterGroupDescriptor(solver) # "Parse" the solver-definition in prototxt-format try: text_format.Merge(solverstring, solver) except ParseError as ex: raise ParseException(str(ex)) params = descr.parameter().copy() # All Parameters of the solver return copy.deepcopy(_extract_param(solver, params))
def verifyConsistency(self): '''check if all entries have the same channel number and size. This may take a lot of time since every entry has to be checked.''' from backend.caffe.path_loader import PathLoader caffe = PathLoader().importCaffe() if self.getDataCount() < 2: return True first = self._getFirstDatum() if first: channels = first.channels width = first.width height = first.height iter = self._getIter() if iter: for key, value in iter: raw_datum = value datum = caffe.proto.caffe_pb2.Datum() datum.ParseFromString(raw_datum) if channels is not datum.channels \ or width is not datum.width \ or height is not datum.height: return False return True
def _import_solver(solverdict): from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() solver = proto.SolverParameter() for entry in solverdict: # special case: inline-net definition in solver # (required to handle layers and layerOrder the same way it is handled for a standalone net definition) if entry == "net_param": net = _import_dictionary(solverdict["net_param"]) solver.net_param.MergeFrom(net) else: _insert(entry, solverdict[entry], solver) return solver
def _caffeProtobufModules(): """ Returns all available Classes of caffe_pb2 in a dictionary """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() global _caffeprotomodulesvar if _caffeprotomodulesvar is None: current_module = sys.modules[proto.__name__] _caffeprotomodulesvar = dict( inspect.getmembers(current_module, inspect.isclass)) return _caffeprotomodulesvar
def _bareLayer(layertype, name): """ Creates a dictionary of the given layertype with the given name initialized with default values if required. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() res = {"type": layertype} layerParamInst = proto.LayerParameter() res["parameters"] = _extract_param( layerParamInst, info.CaffeMetaInformation().commonParameters()) res["parameters"]["name"] = unicode(name) layerparamkeys = layertype.layerParamKeys() for layerparamkey in layerparamkeys: layerTypeParam = layertype.parameters()[layerparamkey] layerTypeParamInst = layerTypeParam.protoclass()() res["parameters"][layerparamkey] = _extract_param( layerTypeParamInst, layerTypeParam.parameter()) res["parameters"]["type"] = unicode(layertype.name()) return res
def extractNetFromSolver(solverstring): """Read a protoxt string(!) of a solver and return the network protoxt string(!). This works only, if the solver specifies a network using the "net_param" parameter. A reference to a file using the "net" parameter can not be handled by this method. """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() # create empty solver message solver = proto.SolverParameter() # "Parse" the solver-definition in prototxt-format try: text_format.Merge(solverstring, solver) # extract net as a message and convert it into a string netString = text_format.MessageToString(solver.net_param) return netString except ParseError as ex: raise ParseException(str(ex))
def __initAvailableParameterGroupDescriptors(self): """Generate information about available parameter only once using this method. See description of self.availableParameterGroupDescriptors(). """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() current_module = sys.modules[proto.__name__] res = {} for (el, val) in inspect.getmembers(current_module, inspect.isclass): res[el] = ParameterGroupDescriptor(val) self._availableParameterGroupDescriptors = res
def _getCurrentDatum(self): from backend.caffe.path_loader import PathLoader caffe = PathLoader().importCaffe() if self._cursor: raw_datum = self._cursor.value() datum = caffe.proto.caffe_pb2.Datum() try: datum.ParseFromString(raw_datum) except: Log.error("LMDB does not contain valid data: " + self._path, self.logid) return None return datum
def _getFirstDatum(self): from backend.caffe.path_loader import PathLoader caffe = PathLoader().importCaffe() iter = self._getIter() if iter: for key, value in iter: raw_datum = value datum = caffe.proto.caffe_pb2.Datum() try: datum.ParseFromString(raw_datum) except: Log.error( "LEVELDB does not contain valid data: " + self._path, self.logid) return None return datum
def __initAvailableSolverTypes(self): """Generate information about available solver types only once. self.__initAvailableParameterGroupDescriptors() needs to be called before this method.""" from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() # DO NOT REMOVE the following import statement, although your IDE might say it's unused. It's not! from caffe._caffe import Solver as SolverBaseClassInfo # Unfortunately, there isn't a preexisting method to get all solver (names). # But, there is a base class which is subclassed by all existing solvers. # Use those subclasses to gain the names of all solvers. solverNamesFull = [ cls.__name__ for cls in vars()['SolverBaseClassInfo'].__subclasses__() ] # All those names end with the suffix "Solver". # Remove that suffix to be consistent with the names of available LayerTypes. solverNameMainParts = [] for name in solverNamesFull: solverNameMainParts.append(name.replace("Solver", "")) # Get all (common) params of a solver type # TODO try to separate params which should be available only for a specific SolverType. # Unfortunately, there doesn't seem to exist any way to automatically do that. There are only a few comments # in the caffe.proto file which would allow hardcoding some special cases. But is that a good idea? commonParams = self._availableParameterGroupDescriptors[ "SolverParameter"].parameter() # use .parameter() on purpose # create each solver type after one another res = {} for nameMainPart in solverNameMainParts: res[nameMainPart] = SolverType(nameMainPart, commonParams) self._availableSolverTypes = res
# from https://www.eriksmistad.no/visualizing-learned-features-of-a-caffe-neural-network/ # test code, will be changed from backend.caffe.path_loader import PathLoader caffe = PathLoader().importCaffe() from gui.main_window.docks.weight_visualization import visualize_weights # Load model net = caffe.Net( '/Users/sandtil/Documents/Developer/pyenv/Barista/test/examples/mnist/sessions/20161221_151232_203/net.prototxt', '/Users/sandtil/Documents/Developer/pyenv/Barista/test/examples/mnist/sessions/20161221_151232_203/snapshots/lenet_iter_10000.caffemodel', caffe.TEST) visualize_weights(net, 'conv1', filename='conv1') #visualize_weights(net, 'conv2', filename='conv2.png')
def loadNet(netstring): """ Load the prototxt string "netstring" into a dictionary. The dictionary has the following form { "name": "Somenetwork", "input_dim": [1,2,1,1], "state": { "phase": "TRAIN" }, ... "layers": { "somerandomid1": { "type": LayerType Instance of Pooling-Layer, "parameters": { "pooling_param": [ "kernel_size": 23, "engine": "DEFAULT" ] .... "input_param": [ {"shape": {"dim": [...], .... }, {"shape": {"dim": [...], .... }, ] } }, "somerandomid2": {"type": ..., "parameters": ....} }, "layerOrder": ["somerandomid1", "somerandomid2", ....] } """ from backend.caffe.path_loader import PathLoader proto = PathLoader().importProto() # Load Protoclass for parsing net = proto.NetParameter() # Get DESCRIPTION for meta infos descr = info.ParameterGroupDescriptor(net) # "Parse" the netdefinition in prototxt-format try: text_format.Merge(netstring, net) except ParseError as ex: raise ParseException(str(ex)) params = descr.parameter().copy() # All Parameters of the network # add logger output if deprecated layers have been found, to inform the user that those can't be parsed yet if len(net.layers) > 0: callerId = Log.getCallerId('protoxt-parser') Log.log( "The given network contains deprecated layer definitions which are not supported and will be dropped.", callerId) # Layers is deprecated, Layer will be handled seperatly and linked to "Layers" key del params["layers"] del params["layer"] if params.has_key("layerOrder"): raise ValueError('Key layerOrder not expected!') # Extract every other parameters res = _extract_param(net, params) res["layers"], res["layerOrder"] = _load_layers(net.layer) res = copy.deepcopy(res) return res