use of org.nd4j.autodiff.samediff.SDVariable in project nd4j by deeplearning4j.
the class SpaceToDepth method doDiff.
@Override
public List<SDVariable> doDiff(List<SDVariable> i_v) {
// Gradient to SpaceToDepth is just DepthToSpace of same block size and data format.
SDVariable gradient = i_v.get(0);
SDVariable ret = sameDiff.depthToSpace(gradient, blockSize, dataFormat);
return Arrays.asList(ret);
}
use of org.nd4j.autodiff.samediff.SDVariable in project nd4j by deeplearning4j.
the class Sum method doDiff.
@Override
public List<SDVariable> doDiff(List<SDVariable> i_v1) {
// Out = sum(in)
// dL/dIn = dL/dOut * dOut/dIn
// = dL/dOut * 1
// But broadcast to shape of the input
// TODO shape may not always be defined?
int origRank = Shape.rankFromShape(arg().getShape());
SDVariable broadcastable = sameDiff.f().reductionBroadcastableWithOrigShape(origRank, dimensions, i_v1.get(0));
SDVariable ret = sameDiff.onesLike(arg()).mul(broadcastable);
return Arrays.asList(ret);
}
use of org.nd4j.autodiff.samediff.SDVariable in project nd4j by deeplearning4j.
the class TensorMmul method doDiff.
@Override
public List<SDVariable> doDiff(List<SDVariable> i_v1) {
List<SDVariable> ret = new ArrayList<>();
int[] bAxes = range(0, rarg().getShape().length);
int[] aAxes = range(0, larg().getShape().length);
int aRank = larg().getShape().length;
int bRank = rarg().getShape().length;
int[][] sumAxes = new int[][] { mod(axes[0], aRank), mod(axes[1], bRank) };
int[][] deletedAxes = new int[][] { removeIndex(aAxes, sumAxes[0]), removeIndex(bAxes, sumAxes[1]) };
int[] gAxes = range(0, i_v1.get(0).getShape().length);
int[][] firstAxes = new int[][] { Arrays.copyOfRange(gAxes, deletedAxes[0].length, gAxes.length), deletedAxes[1] };
int[][] secondAxes = new int[][] { deletedAxes[0], Arrays.copyOfRange(gAxes, 0, deletedAxes[0].length) };
// tensor matrix multiply gradient wrt second variable
int[] firstPerm = argsort(combine(deletedAxes[0], keep(argsort(sumAxes[1]), sumAxes[0])));
SDVariable firstResult = doTensorMmul(i_v1.get(0), rarg(), firstAxes);
SDVariable permuted = f().permute(firstResult, firstPerm);
ret.add(permuted);
// tensor matrix multiply gradient wrt first variable
int[] secondPerm = argsort(combine(keep(argsort(sumAxes[0]), sumAxes[1]), deletedAxes[1]));
SDVariable secondResult = doTensorMmul(i_v1.get(0), larg(), secondAxes);
SDVariable secondPermuted = f().permute(secondResult, secondPerm);
ret.add(secondPermuted);
return ret;
}
use of org.nd4j.autodiff.samediff.SDVariable in project nd4j by deeplearning4j.
the class EuclideanDistance method doDiff.
@Override
public List<SDVariable> doDiff(List<SDVariable> i_v1) {
// ddist(x,y)/dxi = (xi-yi)/dist(x,y)
SDVariable euc = outputVariables()[0];
SDVariable difference = larg().sub(rarg());
SDVariable divBroadcastable;
// TODO shape may not always be defined?
int origRank = Shape.rankFromShape(arg().getShape());
if (!(dimensions.length == 1 && dimensions[0] == Integer.MAX_VALUE)) {
// 1x1 output case
divBroadcastable = i_v1.get(0).div(euc);
} else {
divBroadcastable = f().reductionBroadcastableWithOrigShape(origRank, dimensions, i_v1.get(0).div(euc));
}
SDVariable gradX = difference.mul(divBroadcastable);
SDVariable gradY = f().neg(gradX);
return Arrays.asList(gradX, gradY);
}
use of org.nd4j.autodiff.samediff.SDVariable in project nd4j by deeplearning4j.
the class Variance method doDiff.
@Override
public List<SDVariable> doDiff(List<SDVariable> i_v1) {
// If out = var(in) then:
// dL/dIn = dL/dOut * dOut/dIn
// with dOut/dIn = (in-mean) * 2/(n-1)
int n = f().getReductionLength(this);
int origRank = Shape.rankFromShape(arg().getShape());
SDVariable broadcastableMean = f().reductionBroadcastableWithOrigShape(origRank, dimensions, f().mean(arg(), dimensions));
SDVariable broadcastableGrad = f().reductionBroadcastableWithOrigShape(origRank, dimensions, i_v1.get(0));
SDVariable dOutdIn = arg().sub(broadcastableMean).mul(2.0 / (biasCorrected ? (n - 1) : n));
SDVariable dLdIn = dOutdIn.mul(broadcastableGrad);
return Arrays.asList(dLdIn);
}
Aggregations