use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SumMetaLayer method eval.
@Nullable
@Override
public Result eval(@Nonnull final Result... inObj) {
final Result input = inObj[0];
Arrays.stream(inObj).forEach(nnResult -> nnResult.addRef());
final int itemCnt = input.getData().length();
if (null == lastResult || minBatches < itemCnt) {
@Nonnull final ToDoubleFunction<Coordinate> f = (c) -> IntStream.range(0, itemCnt).mapToDouble(dataIndex -> input.getData().get(dataIndex).get(c)).sum();
lastResult = input.getData().get(0).mapCoords(f);
}
return new Result(TensorArray.wrap(lastResult), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
if (input.isAlive()) {
@Nullable final Tensor delta = data.get(0);
@Nonnull final Tensor[] feedback = new Tensor[itemCnt];
Arrays.parallelSetAll(feedback, i -> new Tensor(delta.getDimensions()));
@Nonnull final ToDoubleFunction<Coordinate> f = (inputCoord) -> {
for (int inputItem = 0; inputItem < itemCnt; inputItem++) {
feedback[inputItem].add(inputCoord, delta.get(inputCoord));
}
return 0;
};
delta.mapCoords(f);
@Nonnull TensorArray tensorArray = TensorArray.wrap(feedback);
input.accumulate(buffer, tensorArray);
}
}) {
@Override
protected void _free() {
Arrays.stream(inObj).forEach(nnResult -> nnResult.freeRef());
}
@Override
public boolean isAlive() {
return input.isAlive();
}
};
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class ProductInputsLayer method eval.
@Nonnull
@Override
public Result eval(@Nonnull final Result... inObj) {
assert inObj.length > 1;
Arrays.stream(inObj).forEach(x -> x.getData().addRef());
Arrays.stream(inObj).forEach(nnResult -> nnResult.addRef());
for (int i = 1; i < inObj.length; i++) {
final int dim0 = Tensor.length(inObj[0].getData().getDimensions());
final int dimI = Tensor.length(inObj[i].getData().getDimensions());
if (dim0 != 1 && dimI != 1 && dim0 != dimI) {
throw new IllegalArgumentException(Arrays.toString(inObj[0].getData().getDimensions()) + " != " + Arrays.toString(inObj[i].getData().getDimensions()));
}
}
return new Result(Arrays.stream(inObj).parallel().map(x -> {
TensorList data = x.getData();
data.addRef();
return data;
}).reduce((l, r) -> {
TensorArray productArray = TensorArray.wrap(IntStream.range(0, Math.max(l.length(), r.length())).parallel().mapToObj(i1 -> {
@Nullable final Tensor left = l.get(1 == l.length() ? 0 : i1);
@Nullable final Tensor right = r.get(1 == r.length() ? 0 : i1);
Tensor product = Tensor.product(left, right);
left.freeRef();
right.freeRef();
return product;
}).toArray(i -> new Tensor[i]));
l.freeRef();
r.freeRef();
return productArray;
}).get(), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList delta) -> {
for (@Nonnull final Result input : inObj) {
if (input.isAlive()) {
@Nonnull TensorList passback = Arrays.stream(inObj).parallel().map(x -> {
TensorList tensorList = x == input ? delta : x.getData();
tensorList.addRef();
return tensorList;
}).reduce((l, r) -> {
TensorArray productList = TensorArray.wrap(IntStream.range(0, Math.max(l.length(), r.length())).parallel().mapToObj(j -> {
@Nullable final Tensor left = l.get(1 == l.length() ? 0 : j);
@Nullable final Tensor right = r.get(1 == r.length() ? 0 : j);
Tensor product = Tensor.product(left, right);
left.freeRef();
right.freeRef();
return product;
}).toArray(j -> new Tensor[j]));
l.freeRef();
r.freeRef();
return productList;
}).get();
final TensorList inputData = input.getData();
if (1 == inputData.length() && 1 < passback.length()) {
TensorArray newValue = TensorArray.wrap(passback.stream().reduce((a, b) -> {
@Nullable Tensor c = a.addAndFree(b);
b.freeRef();
return c;
}).get());
passback.freeRef();
passback = newValue;
}
if (1 == Tensor.length(inputData.getDimensions()) && 1 < Tensor.length(passback.getDimensions())) {
TensorArray newValue = TensorArray.wrap(passback.stream().map((a) -> {
@Nonnull Tensor b = new Tensor(a.sum());
a.freeRef();
return b;
}).toArray(i -> new Tensor[i]));
passback.freeRef();
passback = newValue;
}
input.accumulate(buffer, passback);
}
}
}) {
@Override
public boolean isAlive() {
for (@Nonnull final Result element : inObj) if (element.isAlive()) {
return true;
}
return false;
}
@Override
protected void _free() {
Arrays.stream(inObj).forEach(nnResult -> nnResult.freeRef());
Arrays.stream(inObj).forEach(x -> x.getData().freeRef());
}
};
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class ReLuActivationLayer method eval.
@Nonnull
@Override
public Result eval(final Result... inObj) {
final Result input = inObj[0];
final TensorList indata = input.getData();
input.addRef();
indata.addRef();
weights.addRef();
final int itemCnt = indata.length();
return new Result(TensorArray.wrap(IntStream.range(0, itemCnt).parallel().mapToObj(dataIndex -> {
@Nullable Tensor tensorElement = indata.get(dataIndex);
@Nonnull final Tensor tensor = tensorElement.multiply(weights.get(0));
tensorElement.freeRef();
@Nullable final double[] outputData = tensor.getData();
for (int i = 0; i < outputData.length; i++) {
if (outputData[i] < 0) {
outputData[i] = 0;
}
}
return tensor;
}).toArray(i -> new Tensor[i])), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList delta) -> {
if (!isFrozen()) {
IntStream.range(0, delta.length()).parallel().forEach(dataIndex -> {
@Nullable Tensor deltaTensor = delta.get(dataIndex);
@Nullable final double[] deltaData = deltaTensor.getData();
@Nullable Tensor inputTensor = indata.get(dataIndex);
@Nullable final double[] inputData = inputTensor.getData();
@Nonnull final Tensor weightDelta = new Tensor(weights.getDimensions());
@Nullable final double[] weightDeltaData = weightDelta.getData();
for (int i = 0; i < deltaData.length; i++) {
weightDeltaData[0] += inputData[i] < 0 ? 0 : deltaData[i] * inputData[i];
}
buffer.get(ReLuActivationLayer.this, weights.getData()).addInPlace(weightDeltaData).freeRef();
deltaTensor.freeRef();
inputTensor.freeRef();
weightDelta.freeRef();
});
}
if (input.isAlive()) {
final double weight = weights.getData()[0];
@Nonnull TensorArray tensorArray = TensorArray.wrap(IntStream.range(0, delta.length()).parallel().mapToObj(dataIndex -> {
@Nullable Tensor deltaTensor = delta.get(dataIndex);
@Nullable final double[] deltaData = deltaTensor.getData();
@Nullable Tensor inTensor = indata.get(dataIndex);
@Nullable final double[] inputData = inTensor.getData();
@Nonnull final int[] dims = inTensor.getDimensions();
@Nonnull final Tensor passback = new Tensor(dims);
for (int i = 0; i < passback.length(); i++) {
passback.set(i, inputData[i] < 0 ? 0 : deltaData[i] * weight);
}
inTensor.freeRef();
deltaTensor.freeRef();
return passback;
}).toArray(i -> new Tensor[i]));
input.accumulate(buffer, tensorArray);
}
}) {
@Override
protected void _free() {
input.freeRef();
indata.freeRef();
weights.freeRef();
}
@Override
public boolean isAlive() {
return input.isAlive() || !isFrozen();
}
};
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class ScaleMetaLayer method eval.
@Nullable
@Override
public Result eval(@Nonnull final Result... inObj) {
final int itemCnt = inObj[0].getData().length();
Arrays.stream(inObj).forEach(nnResult -> nnResult.addRef());
Arrays.stream(inObj).forEach(x -> x.getData().addRef());
final Tensor[] tensors = IntStream.range(0, itemCnt).mapToObj(dataIndex -> inObj[0].getData().get(dataIndex).mapIndex((v, c) -> v * inObj[1].getData().get(0).get(c))).toArray(i -> new Tensor[i]);
Tensor tensor0 = tensors[0];
tensor0.addRef();
return new Result(TensorArray.wrap(tensors), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
if (inObj[0].isAlive()) {
@Nonnull TensorArray tensorArray = TensorArray.wrap(data.stream().map(t -> {
@Nullable Tensor t1 = inObj[1].getData().get(0);
@Nullable Tensor tensor = t.mapIndex((v, c) -> {
return v * t1.get(c);
});
t.freeRef();
t1.freeRef();
return tensor;
}).toArray(i -> new Tensor[i]));
inObj[0].accumulate(buffer, tensorArray);
}
if (inObj[1].isAlive()) {
@Nullable final Tensor passback = tensor0.mapIndex((v, c) -> {
return IntStream.range(0, itemCnt).mapToDouble(i -> data.get(i).get(c) * inObj[0].getData().get(i).get(c)).sum();
});
tensor0.freeRef();
@Nonnull TensorArray tensorArray = TensorArray.wrap(IntStream.range(0, inObj[1].getData().length()).mapToObj(i -> i == 0 ? passback : passback.map(v -> 0)).toArray(i -> new Tensor[i]));
inObj[1].accumulate(buffer, tensorArray);
}
Arrays.stream(inObj).forEach(x -> x.getData().addRef());
}) {
@Override
protected void _free() {
Arrays.stream(inObj).forEach(nnResult -> nnResult.freeRef());
}
@Override
public boolean isAlive() {
return inObj[0].isAlive() || inObj[1].isAlive();
}
};
}
use of com.simiacryptus.mindseye.lang.TensorArray in project MindsEye by SimiaCryptus.
the class SimpleActivationLayer method eval.
@Nonnull
@Override
public Result eval(@Nonnull final Result... inObj) {
final TensorList indata0 = inObj[0].getData();
final int itemCnt = indata0.length();
assert 0 < itemCnt;
Arrays.stream(inObj).forEach(nnResult -> nnResult.addRef());
Arrays.stream(inObj).forEach(nnResult -> nnResult.getData().addRef());
@Nonnull final Tensor[] inputGradientA = new Tensor[itemCnt];
return new Result(TensorArray.wrap(IntStream.range(0, itemCnt).parallel().mapToObj(dataIndex -> {
@Nullable final Tensor input = indata0.get(dataIndex);
@Nonnull final Tensor output = new Tensor(indata0.getDimensions());
@Nonnull final Tensor inputGradient = new Tensor(input.length());
inputGradientA[dataIndex] = inputGradient;
@Nonnull final double[] results = new double[2];
for (int i = 0; i < input.length(); i++) {
eval(input.getData()[i], results);
inputGradient.set(i, results[1]);
output.set(i, results[0]);
}
input.freeRef();
return output;
}).toArray(i -> new Tensor[i])), (@Nonnull final DeltaSet<Layer> buffer, @Nonnull final TensorList data) -> {
if (inObj[0].isAlive()) {
@Nonnull TensorArray tensorArray = TensorArray.wrap(IntStream.range(0, itemCnt).parallel().mapToObj(dataIndex -> {
@Nonnull final Tensor passback = new Tensor(data.getDimensions());
@Nullable final double[] gradientData = inputGradientA[dataIndex].getData();
@Nullable Tensor tensor = data.get(dataIndex);
IntStream.range(0, passback.length()).forEach(i -> {
final double v = gradientData[i];
if (Double.isFinite(v)) {
passback.set(i, tensor.get(i) * v);
}
});
tensor.freeRef();
return passback;
}).toArray(i -> new Tensor[i]));
inObj[0].accumulate(buffer, tensorArray);
}
}) {
@Override
protected void _free() {
Arrays.stream(inObj).forEach(nnResult -> nnResult.freeRef());
Arrays.stream(inObj).forEach(nnResult -> nnResult.getData().freeRef());
for (@Nonnull Tensor tensor : inputGradientA) {
tensor.freeRef();
}
}
@Override
public boolean isAlive() {
return inObj[0].isAlive();
}
};
}
Aggregations