use of com.simiacryptus.mindseye.lang.Delta in project MindsEye by SimiaCryptus.
the class FullyConnectedLayer method eval.
@Nonnull
@Override
public Result eval(@Nonnull final Result... inObj) {
final TensorList indata = inObj[0].getData();
indata.addRef();
for (@Nonnull Result result : inObj) {
result.addRef();
}
FullyConnectedLayer.this.addRef();
assert Tensor.length(indata.getDimensions()) == Tensor.length(this.inputDims) : Arrays.toString(indata.getDimensions()) + " == " + Arrays.toString(this.inputDims);
@Nonnull DoubleMatrix doubleMatrix = new DoubleMatrix(Tensor.length(indata.getDimensions()), Tensor.length(outputDims), this.weights.getData());
@Nonnull final DoubleMatrix matrixObj = FullyConnectedLayer.transpose(doubleMatrix);
@Nonnull TensorArray tensorArray = TensorArray.wrap(IntStream.range(0, indata.length()).parallel().mapToObj(dataIndex -> {
@Nullable final Tensor input = indata.get(dataIndex);
@Nullable final Tensor output = new Tensor(outputDims);
matrixObj.mmuli(new DoubleMatrix(input.length(), 1, input.getData()), new DoubleMatrix(output.length(), 1, output.getData()));
input.freeRef();
return output;
}).toArray(i -> new Tensor[i]));
RecycleBin.DOUBLES.recycle(matrixObj.data, matrixObj.data.length);
this.weights.addRef();
return new Result(tensorArray, (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList delta) -> {
if (!isFrozen()) {
final Delta<Layer> deltaBuffer = buffer.get(FullyConnectedLayer.this, this.weights.getData());
final int threads = 4;
IntStream.range(0, threads).parallel().mapToObj(x -> x).flatMap(thread -> {
@Nullable Stream<Tensor> stream = IntStream.range(0, indata.length()).filter(i -> thread == i % threads).mapToObj(dataIndex -> {
@Nonnull final Tensor weightDelta = new Tensor(Tensor.length(inputDims), Tensor.length(outputDims));
Tensor deltaTensor = delta.get(dataIndex);
Tensor inputTensor = indata.get(dataIndex);
FullyConnectedLayer.crossMultiplyT(deltaTensor.getData(), inputTensor.getData(), weightDelta.getData());
inputTensor.freeRef();
deltaTensor.freeRef();
return weightDelta;
});
return stream;
}).reduce((a, b) -> {
@Nullable Tensor c = a.addAndFree(b);
b.freeRef();
return c;
}).map(data -> {
@Nonnull Delta<Layer> layerDelta = deltaBuffer.addInPlace(data.getData());
data.freeRef();
return layerDelta;
});
deltaBuffer.freeRef();
}
if (inObj[0].isAlive()) {
@Nonnull final TensorList tensorList = TensorArray.wrap(IntStream.range(0, indata.length()).parallel().mapToObj(dataIndex -> {
Tensor deltaTensor = delta.get(dataIndex);
@Nonnull final Tensor passback = new Tensor(indata.getDimensions());
FullyConnectedLayer.multiply(this.weights.getData(), deltaTensor.getData(), passback.getData());
deltaTensor.freeRef();
return passback;
}).toArray(i -> new Tensor[i]));
inObj[0].accumulate(buffer, tensorList);
}
}) {
@Override
protected void _free() {
indata.freeRef();
FullyConnectedLayer.this.freeRef();
for (@Nonnull Result result : inObj) {
result.freeRef();
}
FullyConnectedLayer.this.weights.freeRef();
}
@Override
public boolean isAlive() {
return !isFrozen() || Arrays.stream(inObj).anyMatch(x -> x.isAlive());
}
};
}
use of com.simiacryptus.mindseye.lang.Delta in project MindsEye by SimiaCryptus.
the class ImgBandScaleLayer method eval.
/**
* Eval nn result.
*
* @param input the input
* @return the nn result
*/
@Nonnull
public Result eval(@Nonnull final Result input) {
@Nullable final double[] weights = getWeights();
final TensorList inData = input.getData();
inData.addRef();
input.addRef();
@Nullable Function<Tensor, Tensor> tensorTensorFunction = tensor -> {
if (tensor.getDimensions().length != 3) {
throw new IllegalArgumentException(Arrays.toString(tensor.getDimensions()));
}
if (tensor.getDimensions()[2] != weights.length) {
throw new IllegalArgumentException(String.format("%s: %s does not have %s bands", getName(), Arrays.toString(tensor.getDimensions()), weights.length));
}
@Nullable Tensor tensor1 = tensor.mapCoords(c -> tensor.get(c) * weights[c.getCoords()[2]]);
tensor.freeRef();
return tensor1;
};
Tensor[] data = inData.stream().parallel().map(tensorTensorFunction).toArray(i -> new Tensor[i]);
return new Result(TensorArray.wrap(data), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList delta) -> {
if (!isFrozen()) {
final Delta<Layer> deltaBuffer = buffer.get(ImgBandScaleLayer.this, weights);
IntStream.range(0, delta.length()).forEach(index -> {
@Nonnull int[] dimensions = delta.getDimensions();
int z = dimensions[2];
int y = dimensions[1];
int x = dimensions[0];
final double[] array = RecycleBin.DOUBLES.obtain(z);
Tensor deltaTensor = delta.get(index);
@Nullable final double[] deltaArray = deltaTensor.getData();
Tensor inputTensor = inData.get(index);
@Nullable final double[] inputData = inputTensor.getData();
for (int i = 0; i < z; i++) {
for (int j = 0; j < y * x; j++) {
// array[i] += deltaArray[i + z * j];
array[i] += deltaArray[i * x * y + j] * inputData[i * x * y + j];
}
}
inputTensor.freeRef();
deltaTensor.freeRef();
assert Arrays.stream(array).allMatch(v -> Double.isFinite(v));
deltaBuffer.addInPlace(array);
RecycleBin.DOUBLES.recycle(array, array.length);
});
deltaBuffer.freeRef();
}
if (input.isAlive()) {
Tensor[] tensors = delta.stream().map(t -> {
@Nullable Tensor tensor = t.mapCoords((c) -> t.get(c) * weights[c.getCoords()[2]]);
t.freeRef();
return tensor;
}).toArray(i -> new Tensor[i]);
@Nonnull TensorArray tensorArray = TensorArray.wrap(tensors);
input.accumulate(buffer, tensorArray);
}
}) {
@Override
protected void _free() {
inData.freeRef();
input.freeRef();
}
@Override
public boolean isAlive() {
return input.isAlive() || !isFrozen();
}
};
}
use of com.simiacryptus.mindseye.lang.Delta in project MindsEye by SimiaCryptus.
the class SingleDerivativeTester method testUnFrozen.
/**
* Test un frozen.
*
* @param component the component
* @param inputPrototype the input prototype
*/
public void testUnFrozen(@Nonnull final Layer component, Tensor[] inputPrototype) {
inputPrototype = Arrays.stream(inputPrototype).map(tensor -> tensor.copy()).toArray(i -> new Tensor[i]);
@Nonnull final AtomicBoolean reachedInputFeedback = new AtomicBoolean(false);
@Nonnull final Layer frozen = component.copy().setFrozen(false);
List<TensorArray> inputCopies = Arrays.stream(inputPrototype).map(TensorArray::wrap).collect(Collectors.toList());
Result[] inputs = inputCopies.stream().map(tensor -> new Result(tensor, (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
reachedInputFeedback.set(true);
}) {
@Override
public boolean isAlive() {
return true;
}
}).toArray(i -> new Result[i]);
@Nullable final Result eval;
try {
eval = frozen.eval(inputs);
} finally {
for (@Nonnull Result result : inputs) {
result.freeRef();
}
for (@Nonnull TensorArray tensorArray : inputCopies) {
tensorArray.freeRef();
}
}
@Nonnull final DeltaSet<Layer> buffer = new DeltaSet<Layer>();
TensorList tensorList = eval.getData();
eval.accumulate(buffer, tensorList);
eval.freeRef();
@Nullable final List<double[]> stateList = frozen.state();
final List<Delta<Layer>> deltas = stateList.stream().map(doubles -> {
return buffer.stream().filter(x -> x.target == doubles).findFirst().orElse(null);
}).filter(x -> x != null).collect(Collectors.toList());
if (deltas.isEmpty() && !stateList.isEmpty()) {
throw new AssertionError("Nonfrozen component not listed in delta. Deltas: " + deltas);
}
frozen.freeRef();
buffer.freeRef();
if (!reachedInputFeedback.get() && inputPrototype.length != 0) {
throw new RuntimeException("Nonfrozen component did not pass input backwards");
}
}
use of com.simiacryptus.mindseye.lang.Delta in project MindsEye by SimiaCryptus.
the class BatchDerivativeTester method testUnFrozen.
/**
* Test un frozen.
*
* @param component the component
* @param inputPrototype the input prototype
*/
public void testUnFrozen(@Nonnull final Layer component, final Tensor[] inputPrototype) {
@Nonnull final AtomicBoolean reachedInputFeedback = new AtomicBoolean(false);
@Nonnull final Layer frozen = component.copy().setFrozen(false);
@Nullable final Result eval = frozen.eval(new Result(TensorArray.create(inputPrototype), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
reachedInputFeedback.set(true);
}) {
@Override
public boolean isAlive() {
return true;
}
});
@Nonnull final DeltaSet<Layer> buffer = new DeltaSet<Layer>();
TensorList data = eval.getData();
eval.accumulate(buffer, data);
@Nullable final List<double[]> stateList = frozen.state();
final List<Delta<Layer>> deltas = stateList.stream().map(doubles -> {
return buffer.stream().filter(x -> x.target == doubles).findFirst().orElse(null);
}).filter(x -> x != null).collect(Collectors.toList());
if (deltas.isEmpty() && !stateList.isEmpty()) {
throw new AssertionError("Nonfrozen component not listed in delta. Deltas: " + deltas);
}
if (!reachedInputFeedback.get()) {
throw new RuntimeException("Nonfrozen component did not pass input backwards");
}
}
use of com.simiacryptus.mindseye.lang.Delta in project MindsEye by SimiaCryptus.
the class FullyConnectedReferenceLayer method eval.
@Nonnull
@Override
public Result eval(final Result... inObj) {
final Result inputResult = inObj[0];
final TensorList indata = inputResult.getData();
inputResult.addRef();
indata.addRef();
@Nonnull int[] inputDimensions = indata.getDimensions();
assert Tensor.length(inputDimensions) == Tensor.length(this.inputDims) : Arrays.toString(inputDimensions) + " == " + Arrays.toString(this.inputDims);
weights.addRef();
return new Result(TensorArray.wrap(IntStream.range(0, indata.length()).mapToObj(index -> {
@Nullable final Tensor input = indata.get(index);
@Nullable final Tensor output = new Tensor(outputDims);
weights.coordStream(false).forEach(c -> {
int[] coords = c.getCoords();
double prev = output.get(coords[1]);
double w = weights.get(c);
double i = input.get(coords[0]);
double value = prev + w * i;
output.set(coords[1], value);
});
input.freeRef();
return output;
}).toArray(i -> new Tensor[i])), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList delta) -> {
if (!isFrozen()) {
final Delta<Layer> deltaBuffer = buffer.get(FullyConnectedReferenceLayer.this, getWeights().getData());
Tensor[] array = IntStream.range(0, indata.length()).mapToObj(i -> {
@Nullable final Tensor inputTensor = indata.get(i);
@Nullable final Tensor deltaTensor = delta.get(i);
@Nonnull Tensor weights = new Tensor(FullyConnectedReferenceLayer.this.weights.getDimensions());
weights.coordStream(false).forEach(c -> {
int[] coords = c.getCoords();
weights.set(c, inputTensor.get(coords[0]) * deltaTensor.get(coords[1]));
});
inputTensor.freeRef();
deltaTensor.freeRef();
return weights;
}).toArray(i -> new Tensor[i]);
Tensor tensor = Arrays.stream(array).reduce((a, b) -> {
Tensor c = a.addAndFree(b);
b.freeRef();
return c;
}).get();
deltaBuffer.addInPlace(tensor.getData()).freeRef();
tensor.freeRef();
}
if (inputResult.isAlive()) {
@Nonnull final TensorList tensorList = TensorArray.wrap(IntStream.range(0, indata.length()).mapToObj(i -> {
@Nullable final Tensor inputTensor = new Tensor(inputDims);
@Nullable final Tensor deltaTensor = delta.get(i);
weights.coordStream(false).forEach(c -> {
int[] coords = c.getCoords();
inputTensor.set(coords[0], inputTensor.get(coords[0]) + weights.get(c) * deltaTensor.get(coords[1]));
});
deltaTensor.freeRef();
return inputTensor;
}).toArray(i -> new Tensor[i]));
inputResult.accumulate(buffer, tensorList);
}
}) {
@Override
protected void _free() {
indata.freeRef();
inputResult.freeRef();
weights.freeRef();
}
@Override
public boolean isAlive() {
return inputResult.isAlive() || !isFrozen();
}
};
}
Aggregations