Commit 6c42da30 authored by j_stru18's avatar j_stru18

Merge branch 'develop' of IVV5GITHUB01.uni-muenster.de:klemms/PS-2016-NN into develop

parents 7313ffd0 e0b8179d
......@@ -20,3 +20,10 @@ Barista is an open-source graphical high-level interface for the Caffe deep lear
If you have any questions regarding Barista, please feel free to contact the developers at barista(at)uni-muenster.de
** Citing Barista **
If you use Barista in your research, please cite it using the following reference:
Klemm, S. and Scherzinger, A. and Drees, D. and Jiang, X. Barista - a Graphical Tool for Designing and Training Deep Neural Networks. arXiv preprint. arXiv:1802.04626. http://arxiv.org/abs/1802.04626
......@@ -128,35 +128,49 @@ class MinimumTrainingRequirements:
def _checkUniqueBlobNames(self):
"""Checks for duplicate top blob names in all layers and emits error message if duplicates found except
if in-place is permitted (Activation Layer)"""
nonActivationTopBlobNames = []
activationTopBlobNames = []
if in-place is permitted"""
# find all 'real' sources of blobs, i.e. layers that produce a blob as output and are not in-place
blobGenerators = {} # dictionary that saves the sources for every blob name
if hasattr(self._stateData, '__getitem__'):
# inefficient double looping but activation layers can only be checked after non-activation layers
for layer_id, layer in self._stateData["network"]["layers"].iteritems():
if LayerHelper.isLayerIncludedInTrainingPhase(layer) and ("top" in layer["parameters"]):
if not layer["type"].isActivationLayer():
for name in layer["parameters"]["top"]:
if name not in nonActivationTopBlobNames:
nonActivationTopBlobNames.append(name)
else:
self._errorMessages.append((name + " is used more than once as connection name!",
"Duplicate connector name in " + layer["parameters"]["name"]))
for layer_id, layer in self._stateData["network"]["layers"].iteritems():
if LayerHelper.isLayerIncludedInTrainingPhase(layer) and ("top" in layer["parameters"]):
if layer["type"].isActivationLayer():
for name in layer["parameters"]["top"]:
if name not in activationTopBlobNames:
activationTopBlobNames.append(name)
if name in nonActivationTopBlobNames:
if not LayerHelper.isLayerInPlace(layer):
self._errorMessages.append(
(name + " is used more than once as connection name!",
"Duplicate connector name in " + layer["parameters"]["name"]))
else:
self._errorMessages.append((name + " is used more than once as connection name!",
"Duplicate connector name in " + layer["parameters"]["name"]))
parameters = layer.get("parameters", {})
tops = parameters.get("top", [])
bottoms = parameters.get("bottom", [])
# if at least one top blob is also a bottom, check if layer allows in-place
sourced = [blob for blob in tops if blob not in bottoms]
inPlace = [blob for blob in tops if blob in bottoms]
if len(inPlace) > 0 and not layer["type"].allowsInPlace():
for name in inPlace:
self._errorMessages.append((
"{} is reproduced by {}".format(name, parameters.get("name", "[NO NAME]")),
"{} does not support in-place operation".format(parameters.get("name",
"[NO NAME]"))
))
# check all blobs that are generated in one layer if they are generated only once in each phase.
for name in sourced:
phase = [] # this list can hold train, test and both
p = LayerHelper.getLayerPhase(layer)
if p == "":
phase = [LayerHelper.PHASE_TEST, LayerHelper.PHASE_TRAIN]
else:
phase.append(p)
# if a blob already exists, check if it was generated before in the same Phase
if name in blobGenerators:
found_match = False
for candidate in blobGenerators[name]:
intersection = set(phase).intersection(candidate[1])
if len(intersection) > 0:
found_match = True
self._errorMessages.append(("Sources are {} and {} in phase {}".format(
parameters.get("name", "[NO NAME]"),
candidate[0],
list(intersection)[0]),
"{} is generated by multiple layers".format(name)))
if not found_match:
blobGenerators[name].append((parameters.get("name", "[NO NAME]"), phase))
else:
blobGenerators[name] = [(parameters.get("name", "[NO NAME]"), phase)]
def _checkDataLayerExistence(self):
"""Check whether at least one data layer exists (during the training phase)."""
......
......@@ -272,12 +272,16 @@ class LayerType(TopLevelEntityType):
def isActivationLayer(self):
return self._category == self.CATEGORY_ACTIVATION
def allowsInPlace(self):
inPlaceLayers = ['Dropout']
return self._name in inPlaceLayers or self.isActivationLayer()
@staticmethod
def getCategoryByName(layerTypeName):
"""Given its name, determine which category a LayerType does belong to."""
# !!! hard coded list of activation layers could cause problems when more layers are added in caffe
if layerTypeName in ["ReLU", "PReLU", "ELU", "Sigmoid", "TanH", "AbsVal", "Power",
"Exp", "Log", "BNLL", "Threshold", "Bias", "Scale" ]:
"Exp", "Log", "BNLL", "Threshold", "Bias", "Scale"]:
return LayerType.CATEGORY_ACTIVATION
elif "Loss" in layerTypeName:
return LayerType.CATEGORY_LOSS
......
......@@ -438,10 +438,10 @@ class NodeEditor:
self.__networkManager.addLayer(type, scenePosX, scenePosY)
def tryToAddBottomBlob(self, layerID):
def tryToAddBottomBlob(self, layerID, blobName):
""" Notifies the NetworkManager to create a new bottom connector for the given layer. """
self.__networkManager.addBottomBlob(layerID)
self.__networkManager.addBottomBlob(layerID, blobName)
def tryToRemoveBottomBlob(self, layerID, blobIndex):
""" Notifies the NetworkManager to try to remove the bottom connector
......
......@@ -229,7 +229,7 @@ class NodeEditorEventHandler:
if ok:
self.nodeEditor.tryToAddTopBlob(pressedItem.getLayerID(), name)
elif action == addBottomAction:
self.nodeEditor.tryToAddBottomBlob(pressedItem.getLayerID())
self.nodeEditor.tryToAddBottomBlob(pressedItem.getLayerID(), "")
elif action == copyItemsAction:
self.nodeEditor.setCopySelection()
elif action == removeAction:
......
......@@ -120,7 +120,7 @@ class NodeEditorScene(QGraphicsScene):
# add empty bottom blob property
if not emptyBlobAvailable and not topBlobFound:
self.__nodeEditor.tryToAddBottomBlob(bottomLayerID)
self.__nodeEditor.tryToAddBottomBlob(bottomLayerID, "")
# connect nodes
connected = self.__nodeEditor.tryToConnect(topLayerID, topBlobIndex, bottomLayerID, bottomBlobIndex)
......@@ -164,16 +164,20 @@ class NodeEditorScene(QGraphicsScene):
for i in range(0, item.getTopConnectorCount()):
self.__nodeEditor.tryToAddTopBlob(newItem.getLayerID(), item.getTopConnectors()[i].getBlobName())
for connection in item.getTopConnectors()[i].getConnections():
for j in range(item.getTopConnectors()[i].getConnectionCount()-1, -1, -1):
connection = item.getTopConnectors()[i].getConnections()[j]
connection.setTopConnector(newItem.getTopConnectors()[i])
item.getTopConnectors()[i].removeConnection(connection)
newItem.getTopConnectors()[i].addConnection(connection)
# Add bottom connectors
for i in range(0, item.getBottomConnectorCount()):
self.__nodeEditor.tryToAddBottomBlob(newItem.getLayerID())
self.__nodeEditor.tryToAddBottomBlob(newItem.getLayerID(), item.getBottomConnectors()[i].getBlobName())
for j in range(item.getBottomConnectors()[i].getConnectionCount()-1, -1, -1):
connection = item.getBottomConnectors()[i].getConnections()[j]
for connection in item.getBottomConnectors()[i].getConnections():
connection.setBottomConnector(newItem.getBottomConnectors()[i])
item.getBottomConnectors()[i].removeConnection(connection)
newItem.getBottomConnectors()[i].addConnection(connection)
......
......@@ -542,7 +542,7 @@ class NetworkManager(QObject):
# Add one to the count of all layers in the application
self.layerCount += 1
def addBottomBlob(self, layerID):
def addBottomBlob(self, layerID, blobName):
'Adds a bottom entry to the layer with the given id'
def intern(stateDict):
network = stateDict["network"]
......@@ -550,7 +550,7 @@ class NetworkManager(QObject):
layerParams = networkHelper.layerParams(layerID)
if "bottom" not in layerParams:
layerParams.giveProperty("bottom",[])
layerParams["bottom"].pushBack("")
layerParams["bottom"].pushBack(blobName)
# TODO: Instead update in onStateUpdate
#self.nodeEditor.addBottomBlob(layerID, "")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment