org.deeplearning4j.nn.graph.vertex.BaseGraphVertex Maven / Gradle / Ivy
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.nn.graph.vertex;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.deeplearning4j.nn.api.TrainingConfig;
import org.deeplearning4j.nn.graph.ComputationGraph;
import org.deeplearning4j.nn.graph.vertex.impl.LayerVertex;
import org.nd4j.linalg.api.buffer.DataType;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.deeplearning4j.nn.workspace.LayerWorkspaceMgr;
import java.util.Collections;
import java.util.Map;
@Data
public abstract class BaseGraphVertex implements GraphVertex {
protected ComputationGraph graph;
protected String vertexName;
/** The index of this vertex */
protected int vertexIndex;
/**A representation of the vertices that are inputs to this vertex (inputs during forward pass)
* Specifically, if inputVertices[X].getVertexIndex() = Y, and inputVertices[X].getVertexEdgeNumber() = Z
* then the Zth output of vertex Y is the Xth input to this vertex
*/
protected VertexIndices[] inputVertices;
/**A representation of the vertices that this vertex is connected to (outputs duing forward pass)
* Specifically, if outputVertices[X].getVertexIndex() = Y, and outputVertices[X].getVertexEdgeNumber() = Z
* then the output of this vertex (there is only one output) is connected to the Zth input of vertex Y
*/
protected VertexIndices[] outputVertices;
protected INDArray[] inputs;
protected INDArray epsilon;
//Set outputVertex to true when Layer is an OutputLayer, OR For use in specialized situations like reinforcement learning
// For RL situations, this Layer insn't an OutputLayer, but is the last layer in a graph, that gets its error/epsilon
// passed in externally
@Setter @Getter
protected boolean outputVertex;
protected DataType dataType;
protected BaseGraphVertex(ComputationGraph graph, String name, int vertexIndex, VertexIndices[] inputVertices,
VertexIndices[] outputVertices, DataType dataType) {
this.graph = graph;
this.vertexName = name;
this.vertexIndex = vertexIndex;
this.inputVertices = inputVertices;
this.outputVertices = outputVertices;
this.dataType = dataType;
this.inputs = new INDArray[(inputVertices != null ? inputVertices.length : 0)];
}
@Override
public String getVertexName() {
return vertexName;
}
@Override
public int getVertexIndex() {
return vertexIndex;
}
@Override
public int getNumInputArrays() {
return (inputVertices == null ? 0 : inputVertices.length);
}
@Override
public int getNumOutputConnections() {
return (outputVertices == null ? 0 : outputVertices.length);
}
/**A representation of the vertices that are inputs to this vertex (inputs duing forward pass)
* Specifically, if inputVertices[X].getVertexIndex() = Y, and inputVertices[X].getVertexEdgeNumber() = Z
* then the Zth output of vertex Y is the Xth input to this vertex
*/
@Override
public VertexIndices[] getInputVertices() {
return inputVertices;
}
@Override
public void setInputVertices(VertexIndices[] inputVertices) {
this.inputVertices = inputVertices;
this.inputs = new INDArray[(inputVertices != null ? inputVertices.length : 0)];
}
/**A representation of the vertices that this vertex is connected to (outputs duing forward pass)
* Specifically, if outputVertices[X].getVertexIndex() = Y, and outputVertices[X].getVertexEdgeNumber() = Z
* then the Xth output of this vertex is connected to the Zth input of vertex Y
*/
@Override
public VertexIndices[] getOutputVertices() {
return outputVertices;
}
@Override
public void setOutputVertices(VertexIndices[] outputVertices) {
this.outputVertices = outputVertices;
}
@Override
public boolean isInputVertex() {
return false;
}
@Override
public void setInput(int inputNumber, INDArray input, LayerWorkspaceMgr workspaceMgr) {
if (inputNumber >= getNumInputArrays()) {
throw new IllegalArgumentException("Invalid input number");
}
inputs[inputNumber] = input;
}
@Override
public void setEpsilon(INDArray epsilon) {
this.epsilon = epsilon;
}
@Override
public void clear() {
for (int i = 0; i < inputs.length; i++) {
inputs[i] = null;
}
epsilon = null;
if(getLayer() != null){
getLayer().clear();
}
}
@Override
public boolean canDoForward() {
for (INDArray input : inputs) {
if (input == null) {
return false;
}
}
return true;
}
@Override
public boolean canDoBackward() {
for (INDArray input : inputs) {
if (input == null) {
return false;
}
}
return epsilon != null;
}
@Override
public INDArray getEpsilon() {
return epsilon;
}
@Override
public abstract String toString();
@Override
public void setLayerAsFrozen() {
if (!(this instanceof LayerVertex)) {
throw new IllegalArgumentException("Cannot set non layer vertices as frozen");
}
}
@Override
public void clearVertex() {
clear();
}
@Override
public Map paramTable(boolean backpropOnly) {
return Collections.emptyMap();
}
@Override
public long numParams(){
return params() == null ? 0 : params().length();
}
@Override
public TrainingConfig getConfig() {
return null;
}
@Override
public INDArray params() {
return null;
}
@Override
public INDArray getGradientsViewArray() {
return null;
}
@Override
public boolean updaterDivideByMinibatch(String paramName) {
if(hasLayer()){
return getLayer().updaterDivideByMinibatch(paramName);
}
return true;
}
}