package be.iminds.iot.dianne.nn.module.layer;

import be.iminds.iot.dianne.nn.module.AbstractTrainableModule;
import be.iminds.iot.dianne.tensor.Tensor;

public class Linear extends AbstractTrainableModule {

	private Tensor weights;
	private Tensor bias;
	
	private Tensor gradWeights;
	private Tensor gradBias;
	
	public Linear(int inSize, int outSize){
		super();
		
		weights = factory.createTensor(outSize, inSize);
		bias = factory.createTensor(outSize);
		
		weights.rand();
		bias.rand();
	}
	
	@Override
	protected void forward() {
		output = factory.getTensorMath().addmv(output, bias, weights, input);
	}

	@Override
	protected void backward() {
		gradInput = factory.getTensorMath().tmv(gradInput, weights, gradOutput);
	}

	@Override
	public void accGradParameters() {
		// TODO accumulate instead of replace!
		gradWeights = factory.getTensorMath().vv(gradWeights, gradOutput, input);
		gradBias = gradOutput.clone(gradBias);
	}

}

@@ -361,24 +361,232 @@
 per();%0A%09%09%0A%09%09
+parameters = factory.createTensor(outSize, inSize+1);%0A%09%09gradParameters = factory.createTensor(outSize, inSize+1);%0A%09%09%0A%09%09weights = parameters.narrow(1, 0, inSize);%0A%09%09bias = parameters.narrow(1, inSize, 1);%0A%09%09//
 weights = fa
@@ -620,24 +620,26 @@
  inSize);%0A%09%09
+//
 bias = facto
@@ -989,49 +989,8 @@
 ) %7B%0A
-%09%09// TODO accumulate instead of replace!%0A
 %09%09gr
@@ -1025,16 +1025,19 @@
 rMath().
+add
 vv(gradW
@@ -1039,24 +1039,37 @@
 gradWeights,
+ gradWeights,
  gradOutput,
@@ -1094,33 +1094,66 @@
 s = 
-gradOutput.clone(gradBias
+factory.getTensorMath().add(gradBias, gradBias, gradOutput
 );%0A%09

implement accGradParameters of Linear