public GraphBuilder(ComputationGraphConfiguration newConf, NeuralNetConfiguration.Builder globalConfiguration) { ComputationGraphConfiguration clonedConf = newConf.clone(); this.vertices = clonedConf.getVertices(); this.vertexInputs = clonedConf.getVertexInputs(); this.networkInputs = clonedConf.getNetworkInputs(); this.networkOutputs = clonedConf.getNetworkOutputs(); this.pretrain = clonedConf.isPretrain(); this.backprop = clonedConf.isBackprop(); this.backpropType = clonedConf.getBackpropType(); this.tbpttFwdLength = clonedConf.getTbpttFwdLength(); this.tbpttBackLength = clonedConf.getTbpttBackLength(); this.globalConfiguration = globalConfiguration; //this.getGlobalConfiguration().setSeed(clonedConf.getDefaultConfiguration().getSeed()); }
@Override public Pair<Gradient, INDArray[]> doBackward(boolean tbptt) { if (!canDoBackward()) { throw new IllegalStateException("Cannot do backward pass: all epsilons not set. Layer " + vertexName + " (idx " + vertexIndex + ") numInputs " + getNumInputArrays() + "; numOutputs " + getNumOutputConnections()); } Pair<Gradient, INDArray> pair; if (tbptt && layer instanceof RecurrentLayer) { //Truncated BPTT for recurrent layers pair = ((RecurrentLayer) layer).tbpttBackpropGradient(epsilon, graph.getConfiguration().getTbpttBackLength()); } else { //Normal backprop pair = layer.backpropGradient(epsilon); //epsTotal may be null for OutputLayers } if (layerPreProcessor != null) { INDArray eps = pair.getSecond(); eps = layerPreProcessor.backprop(eps, graph.batchSize()); pair.setSecond(eps); } //Layers always have single activations input -> always have single epsilon output during backprop return new Pair<>(pair.getFirst(), new INDArray[] {pair.getSecond()}); }