docs: public String summary(InputType inputType) {
          StringBuilder ret = new StringBuilder();
          ret.append("\n");
  
          List<String[]> lines = new ArrayList<>();
          if(inputType == null){
              lines.add(new String[]{"LayerName (LayerType)", "nIn,nOut", "TotalParams", "ParamsShape"});
          } else {
              lines.add(new String[]{"LayerName (LayerType)", "nIn,nOut", "TotalParams", "ParamsShape", "InputShape", "OutputShape"});
          }
          int[] maxLength = new int[inputType == null ? 4 : 6];
          String[] header = lines.get(0);
          for( int i=0; i<header.length; i++ ){
              maxLength[i] = header[i].length();
          }
  
          int frozenParams = 0;
          for (org.deeplearning4j.nn.api.Layer currentLayer : getLayers()) {
              String name = currentLayer.conf().getLayer().getLayerName();
              if (name == null) {
                  name = String.valueOf(currentLayer.getIndex());
              }
              String paramShape = "-";
              String in = "-";
              String out = "-";
              String[] classNameArr = currentLayer.getClass().getName().split("\\.");
              String className = classNameArr[classNameArr.length - 1];
              String paramCount = String.valueOf(currentLayer.numParams());
              String inShape = "";
              String outShape = "";
              InputPreProcessor preProcessor;
              InputType outType;
              if (inputType != null) {
                  preProcessor = getLayerWiseConfigurations().getInputPreProcess(currentLayer.getIndex());
                  inShape = inputType.toString();
                  if (preProcessor != null) {
                      inputType = preProcessor.getOutputType(inputType);
                      inShape += "--> "+ inputType.toString();
                  }
                  outType = currentLayer.conf().getLayer().getOutputType(currentLayer.getIndex(), inputType);
                  outShape = outType.toString();
                  inputType = outType;
              }
              if (currentLayer.numParams() > 0) {
                  paramShape = "";
                  if (currentLayer instanceof BidirectionalLayer) { // Bidirectional layer is not an FFL
                      BidirectionalLayer bi = (BidirectionalLayer) currentLayer;
                      in = String.valueOf(((Bidirectional)bi.conf().getLayer()).getNIn());
                      out = String.valueOf(((Bidirectional)bi.conf().getLayer()).getNOut());
                  } else {
                      try {
                          in = String.valueOf(((FeedForwardLayer) currentLayer.conf().getLayer()).getNIn());
                          out = String.valueOf(((FeedForwardLayer) currentLayer.conf().getLayer()).getNOut());
                      }
                      catch (Exception e) { // Some layers, like PReLU, are just BaseLayers (but have parameters)
                      }
                  }
                  Set<String> paraNames = currentLayer.paramTable().keySet();
                  for (String aP : paraNames) {
                      String paramS = ArrayUtils.toString(currentLayer.paramTable().get(aP).shape());
                      paramShape += aP + ":" + paramS + ", ";
                  }
                  paramShape = paramShape.subSequence(0, paramShape.lastIndexOf(",")).toString();
              }
              if (currentLayer instanceof FrozenLayer) {
                  frozenParams += currentLayer.numParams();
                  classNameArr = ((FrozenLayer) currentLayer).getInsideLayer().getClass().getName().split("\\.");
                  className = "Frozen " + classNameArr[classNameArr.length - 1];
              }
  
              String[] line;
              if (inputType == null) {
                  line = new String[]{name + " (" + className + ")", in + "," + out, paramCount, paramShape};
              } else {
                  line = new String[]{name + " (" + className + ")", in + "," + out, paramCount,paramShape,inShape,outShape};
              }
              for( int i=0; i<line.length; i++ ){
                  maxLength[i] = Math.max(maxLength[i], line[i] == null ? 0 : line[i].length());
              }
              lines.add(line);
          }
  
          StringBuilder sbFormat = new StringBuilder();
          int totalLength = 0;
          int pos = 0;
          for(int length : maxLength){
              int currLength;
              if(pos++ == maxLength.length-1){
                  currLength = length;
              } else {
                  currLength = length+3;
              }
              sbFormat.append("%-").append(currLength).append("s");
              totalLength += currLength;
          }
          sbFormat.append("\n");
          String format = sbFormat.toString();
  
  
  
          ret.append(StringUtils.repeat("=", totalLength))
                  .append("\n");
  
          boolean first = true;
          for(String[] line : lines){
              String formatted = String.format(format, (Object[])line);
              ret.append(formatted);
              if(first){
                  ret.append(StringUtils.repeat("=", totalLength)).append("\n");
                  first = false;
              }
          }
  
          ret.append(StringUtils.repeat("-", totalLength));
          ret.append(String.format("\n%30s %d", "Total Parameters: ", params().length()));
          ret.append(String.format("\n%30s %d", "Trainable Parameters: ", params().length() - frozenParams));
          ret.append(String.format("\n%30s %d", "Frozen Parameters: ", frozenParams));
          ret.append("\n");
          ret.append(StringUtils.repeat("=", totalLength));
          ret.append("\n");
          return ret.toString();
      }