protected synchronized Map<String,INDArray> ffToLayerActivationsDetached(boolean train, @NonNull FwdPassType fwdPassType, boolean storeLastForTBPTT,
                                                                int layerIndex, int[] excludeIdxs, @NonNull INDArray[] features,
                                                                INDArray[] fMask, INDArray[] lMask, boolean clearLayers){
        if(layerIndex < 0 || layerIndex >= topologicalOrder.length){
            throw new IllegalArgumentException("Invalid layer index - index must be >= 0 and < " + topologicalOrder.length
                    + ", got index " + layerIndex);
        }

        setInputs(features);
        setLayerMaskArrays(fMask, lMask);

        //Verify that no workspace is open externally
        WorkspaceUtils.assertNoWorkspacesOpen("Expected no workspace active before call to ffToLayerActivationsDetached", true);

        LayerWorkspaceMgr workspaceMgr;
        WorkspaceMode wsm = (train ? configuration.getTrainingWorkspaceMode() : configuration.getInferenceWorkspaceMode());
        if (wsm == WorkspaceMode.NONE) {
            workspaceMgr = LayerWorkspaceMgr.noWorkspaces();
        } else {
            workspaceMgr = LayerWorkspaceMgr.builder()
                    .noWorkspaceFor(ArrayType.ACTIVATIONS)
                    .with(ArrayType.INPUT, WS_LAYER_WORKING_MEM, WS_LAYER_WORKING_MEM_CONFIG)
                    .with(ArrayType.FF_WORKING_MEM, WS_LAYER_WORKING_MEM, WS_LAYER_WORKING_MEM_CONFIG)
                    .with(ArrayType.RNN_FF_LOOP_WORKING_MEM, WS_RNN_LOOP_WORKING_MEM, WS_RNN_LOOP_WORKING_MEM_CONFIG)
                    .build();

            if(features[0].isAttached()){
                //Don't leverage out of async DataMultiSetIterator workspaces
                workspaceMgr.setNoLeverageOverride(features[0].data().getParentWorkspace().getId());
            }
        }
        workspaceMgr.setHelperWorkspacePointers(helperWorkspaces);

        Map<String, INDArray> activations = new HashMap<>();

        //Add the inputs:
        for( int i=0; i<features.length; i++){
            activations.put(configuration.getNetworkInputs().get(i), features[i]);
        }

        //Do forward pass according to the topological ordering of the network
        for (int i = 0; i <= layerIndex; i++) {
            GraphVertex current = vertices[topologicalOrder[i]];
            String vName = current.getVertexName();
            int vIdx = current.getVertexIndex();

            if(excludeIdxs != null && ArrayUtils.contains(excludeIdxs, vIdx)){
                continue;
            }

            try(MemoryWorkspace wsFFWorking = workspaceMgr.notifyScopeEntered(ArrayType.FF_WORKING_MEM)){
                VertexIndices[] inputsTo = current.getOutputVertices();

                INDArray out;
                if(current.isInputVertex()){
                    out = inputs[vIdx];
                } else {

                    if(fwdPassType == FwdPassType.STANDARD) {
                        //Standard feed-forward case
                        out = current.doForward(train, workspaceMgr);
                    } else if(fwdPassType == FwdPassType.RNN_TIMESTEP){
                        if (current.hasLayer()) {
                            //Layer
                            INDArray input = current.getInputs()[0];
                            Layer l = current.getLayer();
                            if (l instanceof RecurrentLayer) {
                                out = ((RecurrentLayer) l).rnnTimeStep(reshapeTimeStepInput(input), workspaceMgr);
                            }  else if(l instanceof org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer && ((org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer)l).getUnderlying() instanceof RecurrentLayer){
                                RecurrentLayer rl = ((RecurrentLayer) ((org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer)l).getUnderlying());
                                out = rl.rnnTimeStep(reshapeTimeStepInput(input), workspaceMgr);
                            } else if (l instanceof MultiLayerNetwork) {
                                out = ((MultiLayerNetwork) l).rnnTimeStep(reshapeTimeStepInput(input));
                            } else {
                                //non-recurrent layer
                                out = current.doForward(train, workspaceMgr);
                            }
                        } else {
                            //GraphNode
                            out = current.doForward(train, workspaceMgr);
                        }
                    } else if(fwdPassType == FwdPassType.RNN_ACTIVATE_WITH_STORED_STATE) {
                        if (current.hasLayer()) {
                            Layer l = current.getLayer();
                            if (l instanceof RecurrentLayer) {
                                out = ((RecurrentLayer) l).rnnActivateUsingStoredState(current.getInputs()[0], train, storeLastForTBPTT, workspaceMgr);
                            } else if(l instanceof org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer && ((org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer)l).getUnderlying() instanceof RecurrentLayer) {
                                RecurrentLayer rl = (RecurrentLayer) ((org.deeplearning4j.nn.layers.wrapper.BaseWrapperLayer)l).getUnderlying();
                                out = rl.rnnActivateUsingStoredState(current.getInputs()[0], train,storeLastForTBPTT, workspaceMgr);
                            } else if (l instanceof MultiLayerNetwork) {
                                List<INDArray> temp = ((MultiLayerNetwork) l).rnnActivateUsingStoredState(
                                        current.getInputs()[0], train, storeLastForTBPTT);
                                out = temp.get(temp.size() - 1);
                            } else {
                                //non-recurrent layer
                                out = current.doForward(train, workspaceMgr);
                            }
                        } else {
                            out = current.doForward(train, workspaceMgr);
                        }
                    } else {
                        throw new IllegalArgumentException("Unsupported forward pass type for this method: " + fwdPassType);
                    }
                    validateArrayWorkspaces(workspaceMgr, out, ArrayType.ACTIVATIONS, vName, false, "Feed forward (inference)");
                }
                activations.put(current.getVertexName(), out);

                if(inputsTo != null) {  //May be null for output vertices (which don't feed into any other vertices)
                    for (VertexIndices v : inputsTo) {
                        //Note that we don't have to do anything special here: the activations are always detached in
                        // this method
                        int inputToIndex = v.getVertexIndex();
                        int vIdxEdge = v.getVertexEdgeNumber();
                        vertices[inputToIndex].setInput(vIdxEdge, out, workspaceMgr);
                    }
                }

                if(clearLayers) {
                    current.clear();
                }
            }
        }

        return activations;
    }
protected synchronized Map < String , INDArray > ffToLayerActivationsDetached ( boolean train , @ NonNull FwdPassType fwdPassType , boolean storeLastForTBPTT , int layerIndex , int [ ] excludeIdxs , @ NonNull INDArray [ ] features , INDArray [ ] fMask , INDArray [ ] lMask , boolean clearLayers ) { if ( layerIndex < 0 || layerIndex >= topologicalOrder . length ) { throw new IllegalArgumentException ( "Invalid layer index - index must be >= 0 and < " + topologicalOrder . length + ", got index " + layerIndex ) ; } setInputs ( features ) ; setLayerMaskArrays ( fMask , lMask ) ; WorkspaceUtils . assertNoWorkspacesOpen ( "Expected no workspace active before call to ffToLayerActivationsDetached" , true ) ; LayerWorkspaceMgr workspaceMgr ; WorkspaceMode wsm = ( train ? configuration . getTrainingWorkspaceMode ( ) : configuration . getInferenceWorkspaceMode ( ) ) ; if ( wsm == WorkspaceMode . NONE ) { workspaceMgr = LayerWorkspaceMgr . noWorkspaces ( ) ; } else { workspaceMgr = LayerWorkspaceMgr . builder ( ) . noWorkspaceFor ( ArrayType . ACTIVATIONS ) . with ( ArrayType . INPUT , WS_LAYER_WORKING_MEM , WS_LAYER_WORKING_MEM_CONFIG ) . with ( ArrayType . FF_WORKING_MEM , WS_LAYER_WORKING_MEM , WS_LAYER_WORKING_MEM_CONFIG ) . with ( ArrayType . RNN_FF_LOOP_WORKING_MEM , WS_RNN_LOOP_WORKING_MEM , WS_RNN_LOOP_WORKING_MEM_CONFIG ) . build ( ) ; if ( features [ 0 ] . isAttached ( ) ) { workspaceMgr . setNoLeverageOverride ( features [ 0 ] . data ( ) . getParentWorkspace ( ) . getId ( ) ) ; } } workspaceMgr . setHelperWorkspacePointers ( helperWorkspaces ) ; Map < String , INDArray > activations = new HashMap < > ( ) ; for ( int i = 0 ; i < features . length ; i ++ ) { activations . put ( configuration . getNetworkInputs ( ) . get ( i ) , features [ i ] ) ; } for ( int i = 0 ; i <= layerIndex ; i ++ ) { GraphVertex current = vertices [ topologicalOrder [ i ] ] ; String vName = current . getVertexName ( ) ; int vIdx = current . getVertexIndex ( ) ; if ( excludeIdxs != null && ArrayUtils . contains ( excludeIdxs , vIdx ) ) { continue ; } try ( MemoryWorkspace wsFFWorking = workspaceMgr . notifyScopeEntered ( ArrayType . FF_WORKING_MEM ) ) { VertexIndices [ ] inputsTo = current . getOutputVertices ( ) ; INDArray out ; if ( current . isInputVertex ( ) ) { out = inputs [ vIdx ] ; } else { if ( fwdPassType == FwdPassType . STANDARD ) { out = current . doForward ( train , workspaceMgr ) ; } else if ( fwdPassType == FwdPassType . RNN_TIMESTEP ) { if ( current . hasLayer ( ) ) { INDArray input = current . getInputs ( ) [ 0 ] ; Layer l = current . getLayer ( ) ; if ( l instanceof RecurrentLayer ) { out = ( ( RecurrentLayer ) l ) . rnnTimeStep ( reshapeTimeStepInput ( input ) , workspaceMgr ) ; } else if ( l instanceof org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer && ( ( org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer ) l ) . getUnderlying ( ) instanceof RecurrentLayer ) { RecurrentLayer rl = ( ( RecurrentLayer ) ( ( org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer ) l ) . getUnderlying ( ) ) ; out = rl . rnnTimeStep ( reshapeTimeStepInput ( input ) , workspaceMgr ) ; } else if ( l instanceof MultiLayerNetwork ) { out = ( ( MultiLayerNetwork ) l ) . rnnTimeStep ( reshapeTimeStepInput ( input ) ) ; } else { out = current . doForward ( train , workspaceMgr ) ; } } else { out = current . doForward ( train , workspaceMgr ) ; } } else if ( fwdPassType == FwdPassType . RNN_ACTIVATE_WITH_STORED_STATE ) { if ( current . hasLayer ( ) ) { Layer l = current . getLayer ( ) ; if ( l instanceof RecurrentLayer ) { out = ( ( RecurrentLayer ) l ) . rnnActivateUsingStoredState ( current . getInputs ( ) [ 0 ] , train , storeLastForTBPTT , workspaceMgr ) ; } else if ( l instanceof org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer && ( ( org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer ) l ) . getUnderlying ( ) instanceof RecurrentLayer ) { RecurrentLayer rl = ( RecurrentLayer ) ( ( org . deeplearning4j . nn . layers . wrapper . BaseWrapperLayer ) l ) . getUnderlying ( ) ; out = rl . rnnActivateUsingStoredState ( current . getInputs ( ) [ 0 ] , train , storeLastForTBPTT , workspaceMgr ) ; } else if ( l instanceof MultiLayerNetwork ) { List < INDArray > temp = ( ( MultiLayerNetwork ) l ) . rnnActivateUsingStoredState ( current . getInputs ( ) [ 0 ] , train , storeLastForTBPTT ) ; out = temp . get ( temp . size ( ) - 1 ) ; } else { out = current . doForward ( train , workspaceMgr ) ; } } else { out = current . doForward ( train , workspaceMgr ) ; } } else { throw new IllegalArgumentException ( "Unsupported forward pass type for this method: " + fwdPassType ) ; } validateArrayWorkspaces ( workspaceMgr , out , ArrayType . ACTIVATIONS , vName , false , "Feed forward (inference)" ) ; } activations . put ( current . getVertexName ( ) , out ) ; if ( inputsTo != null ) { for ( VertexIndices v : inputsTo ) { int inputToIndex = v . getVertexIndex ( ) ; int vIdxEdge = v . getVertexEdgeNumber ( ) ; vertices [ inputToIndex ] . setInput ( vIdxEdge , out , workspaceMgr ) ; } } if ( clearLayers ) { current . clear ( ) ; } } } return activations ; }
Feed-forward through the network - returning all array activations detached from any workspace.
Note that no workspace should be active externally when calling this method (an exception will be thrown
if a workspace is open externally)

@param train             Training mode (true) or test/inference mode (false)
@param fwdPassType       Type of forward pass to perform (STANDARD or RNN_ACTIVATE_WITH_STORED_STATE only)
@param storeLastForTBPTT ONLY used if fwdPassType == FwdPassType.RNN_ACTIVATE_WITH_STORED_STATE
@param layerIndex        Index (inclusive) to stop forward pass at. For all layers, use numLayers-1
@param excludeIdxs       Layers (vertices) to exclude from forward pass. These layers will be skipped, and hence
are usually output layers or at the end of the network. May be null.
@param features          Input feature arrays
@param fMask             Feature mask arrays. May be null.
@param lMask             Label mask array. May be null.
@param clearLayers       Whether the layer inputs should be cleared
@return Map of activations (including the input), detached from any workspace