public static void validateShapes(int inHeight, int inWidth, int kernelHeight, int kernelWidth, int strideHeight, int strideWidth, int padHeight, int padWidth) { // Check filter > size + padding if (kernelHeight > (inHeight + 2 * padHeight)) throw new InvalidInputTypeException("Invalid input: activations into layer are h=" + inHeight + " but kernel size is " + kernelHeight + " with padding " + padHeight); if (kernelWidth > (inWidth + 2 * padWidth)) throw new InvalidInputTypeException("Invalid input: activations into layer are w=" + inWidth + " but kernel size is " + kernelWidth + " with padding " + padWidth); // Check stride if ((strideHeight <= 0) || (strideWidth <= 0)) throw new InvalidInputTypeException("Invalid stride: strideHeight is " + strideHeight + " and strideWidth is " + strideWidth + " and both should be great than 0"); // Below is to confirm an integer comes out of the calculation but this is taken care of in nd4j //Check proposed filter/padding size actually works: // if ((inHeight - kernelHeight + 2 * padHeight) % strideHeight != 0) { // throw new InvalidInputTypeException("Invalid input/configuration: activations into layer are inputHeight=" + inHeight + ", heightPadding=" + padHeight // + ", kernelHeight = " + kernelHeight + ", strideHeight = " + strideHeight + ". (inputHeight-kernelHeight+2*heightPadding)/strideHeight is not an integer"); // } // if ((inWidth - kernelWidth + 2 * padWidth) % strideWidth != 0) // throw new InvalidInputTypeException("Invalid input/configuration: activations into layer are inputWidth=" + inWidth + ", widthPadding=" + padWidth // + ", kernelWidth = " + kernelWidth + ", strideWidth = " + strideWidth + ". (inputWidth-kernelWidth+2*widthPadding)/strideWidth is not an integer"); } }
@Override public InputType getOutputType(int layerIndex, InputType... vertexInputs) throws InvalidInputTypeException { if (vertexInputs.length != 1) throw new InvalidInputTypeException("Invalid input: Preprocessor vertex expects " + "exactly one input"); return preProcessor.getOutputType(vertexInputs[0]); }
@Override public InputType getOutputType(int layerIndex, InputType... vertexInputs) throws InvalidInputTypeException { if (vertexInputs.length != 1) throw new InvalidInputTypeException("Invalid input type: cannot get last time step of more than 1 input"); if (vertexInputs[0].getType() != InputType.Type.RNN) { throw new InvalidInputTypeException( "Invalid input type: cannot get subset of non RNN input (got: " + vertexInputs[0] + ")"); } return InputType.feedForward(((InputType.InputTypeRecurrent) vertexInputs[0]).getSize()); }
@Override public InputType getOutputType(int layerIndex, InputType... vertexInputs) throws InvalidInputTypeException { if (vertexInputs.length != 1) { throw new InvalidInputTypeException( "LayerVertex expects exactly one input. Got: " + Arrays.toString(vertexInputs)); } //Assume any necessary preprocessors have already been added InputType afterPreprocessor; if (preProcessor == null) afterPreprocessor = vertexInputs[0]; else afterPreprocessor = preProcessor.getOutputType(vertexInputs[0]); return layerConf.getLayer().getOutputType(layerIndex, afterPreprocessor); }
@Override public InputType getOutputType(int layerIndex, InputType... vertexInputs) throws InvalidInputTypeException { if (vertexInputs.length != 1) throw new InvalidInputTypeException("Invalid input type: cannot duplicate more than 1 input"); int tsLength = 1; //TODO work this out properly if (vertexInputs[0].getType() == InputType.Type.FF) { return InputType.recurrent(((InputType.InputTypeFeedForward) vertexInputs[0]).getSize(), tsLength); } else if (vertexInputs[0].getType() != InputType.Type.CNNFlat) { return InputType.recurrent(((InputType.InputTypeConvolutionalFlat) vertexInputs[0]).getFlattenedSize(), tsLength); } else { throw new InvalidInputTypeException( "Invalid input type: cannot duplicate to time series non feed forward (or CNN flat) input (got: " + vertexInputs[0] + ")"); } }
@Override public InputType getOutputType(int layerIndex, InputType... vertexInputs) throws InvalidInputTypeException { if (vertexInputs.length != 1) { throw new InvalidInputTypeException( "SubsetVertex expects single input type. Received: " + Arrays.toString(vertexInputs)); } switch (vertexInputs[0].getType()) { case FF: return InputType.feedForward(to - from + 1); case RNN: return InputType.recurrent(to - from + 1); case CNN: InputType.InputTypeConvolutional conv = (InputType.InputTypeConvolutional) vertexInputs[0]; int depth = conv.getDepth(); if (to >= depth) { throw new InvalidInputTypeException("Invalid range: Cannot select depth subset [" + from + "," + to + "] inclusive from CNN activations with " + " [depth,width,height] = [" + depth + "," + conv.getWidth() + "," + conv.getHeight() + "]"); } return InputType.convolutional(conv.getHeight(), conv.getWidth(), from - to + 1); case CNNFlat: //TODO work out how to do this - could be difficult... throw new UnsupportedOperationException( "Subsetting data in flattened convolutional format not yet supported"); default: throw new RuntimeException("Unknown input type: " + vertexInputs[0]); } }
throw new InvalidInputTypeException( "Invalid input: ElementWise vertex cannot process activations of different types:" + " first type = " + first.getType() + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: ElementWise vertex cannot process activations of different types:" + " first type = " + InputType.Type.CNN + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: ElementWise vertex cannot process CNN activations of different sizes:" + "first [depth,width,height] = [" + fd + "," + fw + "," + fh
throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot currently merge CNN data in flattened format. Got: " + vertexInputs); for (int i = 0; i < vertexInputs.length; i++) { if (vertexInputs[i].getType() != first.getType()) { throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot merge activations of different types:" + " first type = " + first.getType() + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot process activations of different types:" + " first type = " + InputType.Type.CNN + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot merge CNN activations of different width/heights:" + "first [depth,width,height] = [" + fd + "," + fw + "," + fh
throw new InvalidInputTypeException( "Invalid input: StackVertex cannot currently merge CNN data in flattened format. Got: " + vertexInputs); for (int i = 0; i < vertexInputs.length; i++) { if (vertexInputs[i].getType() != first.getType()) { throw new InvalidInputTypeException( "Invalid input: StackVertex cannot merge activations of different types:" + " first type = " + first.getType() + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: StackVertex cannot process activations of different types:" + " first type = " + InputType.Type.CNN + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: StackVertex cannot merge CNN activations of different width/heights:" + "first [depth,width,height] = [" + fd + "," + fw + "," + fh
throw new InvalidInputTypeException( "Invalid input: UnstackVertex cannot currently merge CNN data in flattened format. Got: " + vertexInputs); for (int i = 0; i < vertexInputs.length; i++) { if (vertexInputs[i].getType() != first.getType()) { throw new InvalidInputTypeException( "Invalid input: UnstackVertex cannot merge activations of different types:" + " first type = " + first.getType() + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: UnstackVertex cannot process activations of different types:" + " first type = " + InputType.Type.CNN + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: UnstackVertex cannot merge CNN activations of different width/heights:" + "first [depth,width,height] = [" + fd + "," + fw + "," + fh
throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot currently merge CNN data in flattened format. Got: " + vertexInputs); for (int i = 0; i < vertexInputs.length; i++) { if (vertexInputs[i].getType() != first.getType()) { throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot merge activations of different types:" + " first type = " + first.getType() + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot process activations of different types:" + " first type = " + InputType.Type.CNN + ", input type " + (i + 1) throw new InvalidInputTypeException( "Invalid input: MergeVertex cannot merge CNN activations of different width/heights:" + "first [depth,width,height] = [" + fd + "," + fw + "," + fh