/*******************************************************************************
 * DIANNE  - Framework for distributed artificial neural networks
 * Copyright (C) 2015  iMinds - IBCN - UGent
 *
 * This file is part of DIANNE.
 *
 * DIANNE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Tim Verbelen, Steven Bohez
 *******************************************************************************/
package be.iminds.iot.dianne.nn.learn.criterion;

import be.iminds.iot.dianne.api.nn.learn.Criterion;
import be.iminds.iot.dianne.tensor.Tensor;
import be.iminds.iot.dianne.tensor.TensorOps;

/**
 * Mean squared error criterion
 * 
 * @author tverbele
 *
 */
public class MSECriterion implements Criterion {

	protected Tensor diff;
	protected Tensor error;
	protected Tensor grad;
	
	public MSECriterion() {
		this.error = new Tensor(1);
	}
	
	@Override
	public Tensor error(final Tensor output, final Tensor target) {
		diff = TensorOps.sub(diff, output, target);
		error.set(TensorOps.dot(diff, diff) / (output.dim() == 2 ? output.size(1) : output.size(0)), 0);
		return error;
	}

	@Override
	public Tensor grad(final Tensor output, final Tensor target) {
		grad = TensorOps.mul(grad, diff, 2.0f / (output.dim() == 2 ? output.size(1) : output.size(0)));
		return grad;
	}

}

@@ -1328,31 +1328,29 @@
 erion %7B%0A%0A%09pr
-otec
+iva
 te
-d
  Tensor diff
@@ -1350,31 +1350,29 @@
 or diff;%0A%09pr
-otected
+ivate
  Tensor erro
@@ -1381,15 +1381,13 @@
 %0A%09pr
-otec
+iva
 te
-d
  Ten
@@ -1398,16 +1398,42 @@
 grad;%0A%09%0A
+%09private float div = 1;%0A%09%0A
 %09public 
@@ -1612,47 +1612,198 @@
 ;%0A%09%09
-error.set(TensorOps.dot(diff, diff) / (
+%0A%09%09// to determine if it is batch or not ... use following rule of thumb%0A%09%09// 1d = no batch, 2d = batched 1d, 3d = no batch image, 4d = batched image, 5d = batched volumetric%0A%09%09int%5B%5D dims = 
 outp
@@ -1812,55 +1812,275 @@
 .dim
+s
 ()
- == 2 ? output.size(1) : output.size(0))
+;%0A%09%09int d = dims.length;%0A%09%09if(d == 2)%7B%0A%09%09%09div = dims%5B1%5D;%0A%09%09%7D else if(d == 4)%7B%0A%09%09%09div = dims%5B1%5D*dims%5B2%5D*dims%5B3%5D;%0A%09%09%7D else if(d == 5)%7B%0A%09%09%09div = dims%5B1%5D*dims%5B2%5D*dims%5B3%5D*dims%5B4%5D;%0A%09%09%7D else %7B%0A%09%09%09div = output.size();%0A%09%09%7D%0A%09%09error.set(TensorOps.dot(diff, diff) / div
 , 0);
+%09%09
 %0A%09%09r
@@ -2217,61 +2217,11 @@
 f / 
-(output.dim() == 2 ? output.size(1) : output.size(0))
+div
 );%0A%09

fix MSECriterion in case of multi dimensional output