Hi, I am trying to implement a dot product layer. I have gotten to a point where I am able to do an element-wise multiplication. After that, if I understand correctly, I will have to add an activation layer that can sum all the columns (i.e. reduce along dimension 1). I am trying the below code but it doesn’t work as expected and it just outputs the input provided
ComputationGraph model;
ComputationGraphConfiguration conf;
NeuralNetConfiguration.Builder confBuilder = new NeuralNetConfiguration.Builder();
// ---------------------
// ---------------------
// layering
ComputationGraphConfiguration.GraphBuilder graphBuilder = confBuilder.graphBuilder();
graphBuilder.addInputs("layer_input_");
graphBuilder.setInputTypes(InputType.inferInputType(Nd4j.ones(1, 6)));
graphBuilder.addVertex("layer_output_Betas_", new SubsetVertex(0, 2), "layer_input_");
graphBuilder.addVertex("layer_output_F_", new SubsetVertex(3, 5), "layer_input_");
graphBuilder.addLayer("denselayer",
new DenseLayer.Builder().nIn(3).nOut(1).activation(Activation.IDENTITY)
.build(),
"layer_output_Betas_");
// dot product of betas and factors
graphBuilder.addVertex("product_vertex",
new ElementWiseVertex(ElementWiseVertex.Op.Product), "layer_output_Betas_", "layer_output_F_");
graphBuilder.addLayer("layer_product_",
new ActivationLayer.Builder().activation(Activation.IDENTITY).build(), "product_vertex");
graphBuilder.addLayer("layer_dot", new ActivationLayer.Builder().activation(new SumActivation()).build(), "layer_product_");
// graphBuilder.addLayer("layer_dot_",
// new GlobalPoolingLayer.Builder().poolingDimensions(1).poolingType(PoolingType.SUM).build(), "layer_product_");
// graphBuilder.inputPreProcessor("layer_dot_", new FeedForwardToRnnPreProcessor());
graphBuilder.addLayer("layer_output_", new OutputLayer.Builder(new LossMSE())
.nIn(1)
.nOut(1)
.activation(new ActivationIdentity())
.build(), "layer_dot_");
graphBuilder.setOutputs("layer_output_", "denselayer");
SumActivation.java
public class SumActivation extends BaseActivationFunction {
@Override
public INDArray getActivation(INDArray in, boolean training) {
Sum op = new Sum(in, 1);
Nd4j.getExecutioner().execAndReturn(op);
// return op.getZ();
return in;
}
@Override
public Pair<INDArray, INDArray> backprop(INDArray in, INDArray epsilon) {
assertShape(in, epsilon);
Sum op = new Sum(in, 1);
Nd4j.getExecutioner().execAndReturn(op);
return new Pair<>(in, null);
}
}
The execAndReturn method updates the input NDArray for other activations but over here it doesn’t update the input array. Also, if I return a op.getZ() it throws an error. Any ideas what am I doing incorrectly here?