use of com.yahoo.tensor.functions.TensorFunction 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.TensorFunction 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.TensorFunction in project vespa by vespa-engine.
the class Reshape method lazyGetFunction.
@Override
protected TensorFunction lazyGetFunction() {
if (!allInputTypesPresent(2)) {
return null;
}
if (!allInputFunctionsPresent(2)) {
return null;
}
OrderedTensorType inputType = inputs.get(0).type().get();
TensorFunction inputFunction = inputs.get(0).function().get();
return reshape(inputFunction, inputType.type(), type.type());
}
use of com.yahoo.tensor.functions.TensorFunction in project vespa by vespa-engine.
the class TensorFlowImporter method importRankingExpression.
private static void importRankingExpression(TensorFlowModel model, TensorFlowOperation operation) {
if (operation.function().isPresent()) {
String name = operation.node().getName();
if (!model.expressions().containsKey(operation.node().getName())) {
TensorFunction function = operation.function().get();
// Make sure output adheres to standard naming convention
if (isSignatureOutput(model, operation)) {
OrderedTensorType operationType = operation.type().get();
OrderedTensorType standardNamingType = OrderedTensorType.fromTensorFlowType(operation.node());
if (!operationType.equals(standardNamingType)) {
List<String> renameFrom = operationType.dimensionNames();
List<String> renameTo = standardNamingType.dimensionNames();
function = new Rename(function, renameFrom, renameTo);
}
}
try {
// We add all intermediate nodes imported as separate expressions. Only
// those referenced in a signature output will be used. We parse the
// TensorFunction here to convert it to a RankingExpression tree.
model.expression(name, new RankingExpression(name, function.toString()));
} catch (ParseException e) {
throw new RuntimeException("Tensorflow function " + function + " cannot be parsed as a ranking expression", e);
}
}
}
}
use of com.yahoo.tensor.functions.TensorFunction 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);
}
Aggregations