docs: public Map<String,InputType> getLayerActivationTypes(boolean addPreprocIfNecessary, InputType... inputTypes){
  
          if (inputTypes == null || inputTypes.length != networkInputs.size()) {
              throw new IllegalArgumentException(
                      "Invalid number of InputTypes: cannot add preprocessors if number of InputType "
                              + "objects differs from number of network inputs");
          }
  
          //Now: need to do essentially a forward pass through the network, to work out what type of preprocessors to add
          //To do this: need to know what the output types are for each GraphVertex.
  
          //Do topological sort
          List<String> topologicalOrdering = topologicalOrdering();
  
          //Now, given the topological sort: do equivalent of forward pass
          Map<String, InputType> vertexOutputs = new LinkedHashMap<>();
          int currLayerIdx = -1;
          for (String s : topologicalOrdering) {
              int inputIdx = networkInputs.indexOf(s);
              if (inputIdx != -1) {
                  vertexOutputs.put(s, inputTypes[inputIdx]);
                  continue;
              }
  
              GraphVertex gv = vertices.get(s);
  
              List<InputType> inputTypeList = new ArrayList<>();
  
              if (gv instanceof LayerVertex) {
                  //Add preprocessor, if necessary:
                  String in = vertexInputs.get(s).get(0);
                  InputType layerInput = vertexOutputs.get(in);
                  inputTypeList.add(layerInput);
  
                  LayerVertex lv = (LayerVertex) gv;
                  Layer l = lv.getLayerConf().getLayer();
  
                  //Preprocessors - add if necessary
                  if (lv.getPreProcessor() == null && addPreprocIfNecessary) {
                      //But don't override preprocessors that are manually defined; if none has been defined,
                      //add the appropriate preprocessor for this input type/layer combination
                      InputPreProcessor preproc = l.getPreProcessorForInputType(layerInput);
                      lv.setPreProcessor(preproc);
                  }
  
                  //Set nIn value for layer (if not already set)
                  InputType afterPreproc = layerInput;
                  if (lv.getPreProcessor() != null) {
                      InputPreProcessor ip = lv.getPreProcessor();
                      afterPreproc = ip.getOutputType(layerInput);
                  }
                  l.setNIn(afterPreproc, false);
  
                  currLayerIdx++;
              } else {
                  List<String> inputs = vertexInputs.get(s);
                  if (inputs != null) {
                      for (String inputVertexName : inputs) {
                          inputTypeList.add(vertexOutputs.get(inputVertexName));
                      }
                  }
              }
  
              InputType outputFromVertex =
                      gv.getOutputType(currLayerIdx, inputTypeList.toArray(new InputType[inputTypeList.size()]));
              vertexOutputs.put(s, outputFromVertex);
          }
  
          return vertexOutputs;
      }