use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SumReducerLayer method eval.
@Nonnull
@Override
public Result eval(@Nonnull final Result... inObj) {
Arrays.stream(inObj).forEach(nnResult -> nnResult.addRef());
Arrays.stream(inObj).forEach(x -> x.getData().addRef());
return new Result(TensorArray.wrap(IntStream.range(0, inObj[0].getData().length()).parallel().mapToDouble(dataIndex -> {
double sum = 0;
for (@Nonnull final Result element : inObj) {
@Nullable Tensor tensor = element.getData().get(dataIndex);
@Nullable final double[] input = tensor.getData();
for (final double element2 : input) {
sum += element2;
}
tensor.freeRef();
}
return sum;
}).mapToObj(x -> new Tensor(new double[] { x }, new int[] { 1 })).toArray(i -> new Tensor[i])), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
for (@Nonnull final Result in_l : inObj) {
if (in_l.isAlive()) {
@Nonnull TensorArray tensorArray = TensorArray.wrap(IntStream.range(0, in_l.getData().length()).parallel().mapToObj(dataIndex -> {
final double delta = data.get(dataIndex).get(0);
@Nonnull final Tensor passback = new Tensor(in_l.getData().getDimensions());
for (int i = 0; i < Tensor.length(in_l.getData().getDimensions()); i++) {
passback.set(i, delta);
}
return passback;
}).toArray(i -> new Tensor[i]));
in_l.accumulate(buffer, tensorArray);
}
}
}) {
@Override
protected void _free() {
Arrays.stream(inObj).forEach(x -> x.getData().freeRef());
Arrays.stream(inObj).forEach(nnResult -> nnResult.freeRef());
}
@Override
public boolean isAlive() {
for (@Nonnull final Result element : inObj) if (element.isAlive()) {
return true;
}
return false;
}
};
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SingleDerivativeTester method getLearningGradient.
@Nonnull
private Tensor getLearningGradient(@Nonnull final Layer component, final int layerNum, @Nonnull final Tensor outputPrototype, final Tensor... inputPrototype) {
component.setFrozen(false);
final double[] stateArray = component.state().get(layerNum);
final int stateLen = stateArray.length;
@Nonnull final Tensor gradient = new Tensor(stateLen, outputPrototype.length());
for (int j = 0; j < outputPrototype.length(); j++) {
final int j_ = j;
@Nonnull final DeltaSet<Layer> buffer = new DeltaSet<Layer>();
Result[] array = ConstantResult.batchResultArray(new Tensor[][] { inputPrototype });
@Nullable final Result eval = component.eval(array);
for (@Nonnull Result result : array) {
result.getData().freeRef();
result.freeRef();
}
@Nonnull TensorArray tensorArray = TensorArray.wrap(new Tensor(outputPrototype.getDimensions()).set((k) -> k == j_ ? 1 : 0));
eval.accumulate(buffer, tensorArray);
eval.getData().freeRef();
eval.freeRef();
final DoubleBuffer<Layer> deltaFlushBuffer = buffer.getMap().values().stream().filter(x -> x.target == stateArray).findFirst().orElse(null);
if (null != deltaFlushBuffer) {
for (int i = 0; i < stateLen; i++) {
gradient.set(new int[] { i, j_ }, deltaFlushBuffer.getDelta()[i]);
}
}
buffer.freeRef();
}
return gradient;
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SingleDerivativeTester method getFeedbackGradient.
@Nonnull
private Tensor getFeedbackGradient(@Nonnull final Layer component, final int inputIndex, @Nonnull final Tensor outputPrototype, @Nonnull final Tensor... inputPrototype) {
final Tensor inputTensor = inputPrototype[inputIndex];
final int inputDims = inputTensor.length();
@Nonnull final Tensor result = new Tensor(inputDims, outputPrototype.length());
for (int j = 0; j < outputPrototype.length(); j++) {
final int j_ = j;
@Nonnull final PlaceholderLayer<Tensor> inputKey = new PlaceholderLayer<Tensor>(new Tensor(1));
inputKey.getKey().freeRef();
final Result[] copyInput = Arrays.stream(inputPrototype).map(x -> new Result(TensorArray.create(x), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
}) {
@Override
public boolean isAlive() {
return false;
}
}).toArray(i -> new Result[i]);
copyInput[inputIndex].getData().freeRef();
copyInput[inputIndex].freeRef();
double[] target = new double[inputDims * outputPrototype.length()];
copyInput[inputIndex] = new Result(TensorArray.create(inputTensor), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
if (1 != data.length())
throw new AssertionError();
if (data.length() != 1)
throw new AssertionError();
@Nonnull final Tensor gradientBuffer = new Tensor(inputDims, outputPrototype.length());
if (!Arrays.equals(inputTensor.getDimensions(), data.getDimensions())) {
throw new AssertionError();
}
IntStream.range(0, data.length()).forEach(dataIndex -> {
for (int i = 0; i < inputDims; i++) {
@Nullable Tensor tensor = data.get(dataIndex);
gradientBuffer.set(new int[] { i, j_ }, tensor.getData()[i]);
tensor.freeRef();
}
});
buffer.get(inputKey, target).addInPlace(gradientBuffer.getData()).freeRef();
gradientBuffer.freeRef();
}) {
@Override
public boolean isAlive() {
return true;
}
};
@Nullable final Result eval;
try {
eval = component.eval(copyInput);
} finally {
for (@Nonnull Result nnResult : copyInput) {
nnResult.freeRef();
nnResult.getData().freeRef();
}
}
@Nonnull final DeltaSet<Layer> deltaSet = new DeltaSet<Layer>();
@Nonnull TensorArray tensorArray = TensorArray.wrap(new Tensor(outputPrototype.getDimensions()).set(j, 1));
try {
eval.accumulate(deltaSet, tensorArray);
final Delta<Layer> inputDelta = deltaSet.getMap().get(inputKey);
if (null != inputDelta) {
@Nonnull Tensor tensor = new Tensor(inputDelta.getDelta(), result.getDimensions());
result.addInPlace(tensor);
tensor.freeRef();
}
} finally {
eval.getData().freeRef();
eval.freeRef();
deltaSet.freeRef();
inputKey.freeRef();
}
}
return result;
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SingleDerivativeTester method testFrozen.
/**
* Test frozen.
*
* @param component the component
* @param inputPrototype the input prototype
*/
public void testFrozen(@Nonnull final Layer component, @Nonnull Tensor[] inputPrototype) {
final int inElements = Arrays.stream(inputPrototype).mapToInt(x -> x.length()).sum();
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().freeze();
List<TensorArray> inputCopies = Arrays.stream(inputPrototype).map(TensorArray::wrap).collect(Collectors.toList());
Result[] input = inputCopies.stream().map((tensorArray) -> new Result(tensorArray, (@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(input);
} finally {
for (@Nonnull Result result : input) {
result.freeRef();
}
frozen.freeRef();
for (@Nonnull TensorArray tensorArray : inputCopies) {
tensorArray.freeRef();
}
}
@Nonnull final DeltaSet<Layer> buffer;
TensorList tensorList;
TensorList evalData = eval.getData();
try {
buffer = new DeltaSet<Layer>();
tensorList = evalData.copy();
eval.accumulate(buffer, tensorList);
} finally {
evalData.freeRef();
eval.freeRef();
}
final List<Delta<Layer>> deltas = component.state().stream().map(doubles -> {
return buffer.stream().filter(x -> x.target == doubles).findFirst().orElse(null);
}).filter(x -> x != null).collect(Collectors.toList());
buffer.freeRef();
if (!deltas.isEmpty() && !component.state().isEmpty()) {
throw new AssertionError("Frozen component listed in delta. Deltas: " + deltas);
}
if (!reachedInputFeedback.get() && 0 < inElements) {
throw new RuntimeException("Frozen component did not pass input backwards");
}
}
Aggregations