use of com.yahoo.tensor.functions.Reduce in project vespa by vespa-engine.
the class TensorFlowFeatureConverter method reduceBatchDimensionExpression.
private ExpressionNode reduceBatchDimensionExpression(TensorFunction function, TypeContext<Reference> context) {
TensorFunction result = function;
TensorType type = function.type(context);
if (type.dimensions().size() > 1) {
List<String> reduceDimensions = new ArrayList<>();
for (TensorType.Dimension dimension : type.dimensions()) {
if (dimension.size().orElse(-1L) == 1) {
reduceDimensions.add(dimension.name());
}
}
if (reduceDimensions.size() > 0) {
result = new Reduce(function, Reduce.Aggregator.sum, reduceDimensions);
}
}
return new TensorFunctionNode(result);
}
use of com.yahoo.tensor.functions.Reduce in project vespa by vespa-engine.
the class Reshape method reshape.
public static TensorFunction reshape(TensorFunction inputFunction, TensorType inputType, TensorType outputType) {
if (!tensorSize(inputType).equals(tensorSize(outputType))) {
throw new IllegalArgumentException("New and old shape of tensor must have the same size when reshaping");
}
// Conceptually, reshaping consists on unrolling a tensor to an array using the dimension order,
// then use the dimension order of the new shape to roll back into a tensor.
// Here we create a transformation tensor that is multiplied with the from tensor to map into
// the new shape. We have to introduce temporary dimension names and rename back if dimension names
// in the new and old tensor type overlap.
ExpressionNode unrollFrom = unrollTensorExpression(inputType);
ExpressionNode unrollTo = unrollTensorExpression(outputType);
ExpressionNode transformExpression = new ComparisonNode(unrollFrom, TruthOperator.EQUAL, unrollTo);
TensorType transformationType = new TensorType.Builder(inputType, outputType).build();
Generate transformTensor = new Generate(transformationType, new GeneratorLambdaFunctionNode(transformationType, transformExpression).asLongListToDoubleOperator());
TensorFunction outputFunction = new Reduce(new com.yahoo.tensor.functions.Join(inputFunction, transformTensor, ScalarFunctions.multiply()), Reduce.Aggregator.sum, inputType.dimensions().stream().map(TensorType.Dimension::name).collect(Collectors.toList()));
return outputFunction;
}
use of com.yahoo.tensor.functions.Reduce in project vespa by vespa-engine.
the class Join method lazyGetFunction.
@Override
protected TensorFunction lazyGetFunction() {
if (!allInputTypesPresent(2)) {
return null;
}
if (!allInputFunctionsPresent(2)) {
return null;
}
TensorFlowOperation a = largestInput();
TensorFlowOperation b = smallestInput();
List<String> aDimensionsToReduce = new ArrayList<>();
List<String> bDimensionsToReduce = new ArrayList<>();
int sizeDifference = a.type().get().rank() - b.type().get().rank();
for (int i = 0; i < b.type().get().rank(); ++i) {
TensorType.Dimension bDim = b.type().get().dimensions().get(i);
TensorType.Dimension aDim = a.type().get().dimensions().get(i + sizeDifference);
long bSize = bDim.size().orElse(-1L);
long aSize = aDim.size().orElse(-1L);
if (bSize == 1L && aSize != 1L) {
bDimensionsToReduce.add(bDim.name());
}
if (aSize == 1L && bSize != 1L) {
aDimensionsToReduce.add(bDim.name());
}
}
TensorFunction aReducedFunction = a.function().get();
if (aDimensionsToReduce.size() > 0) {
aReducedFunction = new Reduce(a.function().get(), Reduce.Aggregator.sum, aDimensionsToReduce);
}
TensorFunction bReducedFunction = b.function().get();
if (bDimensionsToReduce.size() > 0) {
bReducedFunction = new Reduce(b.function().get(), Reduce.Aggregator.sum, bDimensionsToReduce);
}
return new com.yahoo.tensor.functions.Join(aReducedFunction, bReducedFunction, operator);
}
use of com.yahoo.tensor.functions.Reduce in project vespa by vespa-engine.
the class Mean method lazyGetFunction.
// todo: optimization: if keepDims and one reduce dimension that has size 1: same as identity.
@Override
protected TensorFunction lazyGetFunction() {
if (!allInputTypesPresent(2)) {
return null;
}
TensorFunction inputFunction = inputs.get(0).function().get();
TensorFunction output = new Reduce(inputFunction, Reduce.Aggregator.avg, reduceDimensions);
if (shouldKeepDimensions()) {
// multiply with a generated tensor created from the reduced dimensions
TensorType.Builder typeBuilder = new TensorType.Builder();
for (String name : reduceDimensions) {
typeBuilder.indexed(name, 1);
}
TensorType generatedType = typeBuilder.build();
ExpressionNode generatedExpression = new ConstantNode(new DoubleValue(1));
Generate generatedFunction = new Generate(generatedType, new GeneratorLambdaFunctionNode(generatedType, generatedExpression).asLongListToDoubleOperator());
output = new com.yahoo.tensor.functions.Join(output, generatedFunction, ScalarFunctions.multiply());
}
return output;
}
use of com.yahoo.tensor.functions.Reduce in project vespa by vespa-engine.
the class TensorTransformer method replaceMaxAndMinFunction.
private ExpressionNode replaceMaxAndMinFunction(FunctionNode node) {
ExpressionNode arg1 = node.children().get(0);
ExpressionNode arg2 = node.children().get(1);
TensorFunctionNode.TensorFunctionExpressionNode expression = TensorFunctionNode.wrapArgument(arg1);
Reduce.Aggregator aggregator = Reduce.Aggregator.valueOf(node.getFunction().name());
String dimension = ((ReferenceNode) arg2).getName();
return new TensorFunctionNode(new Reduce(expression, aggregator, dimension));
}
Aggregations