execute(inputs, outputs) {
        // Dispose any tensors from a prior run to avoid leaking them.
        this.disposeIntermediateTensors();
        inputs = this.mapInputs(inputs);
        const names = Object.keys(inputs).sort();
        this.checkInputs(inputs);
        this.checkInputShapeAndType(inputs);
        outputs = this.mapOutputs(outputs);
        this.checkOutputs(outputs);
        const inputNodes = names.map((name)=>this.graph.nodes[(0, _utils.parseNodeName)(name)[0]]);
        const outputNodeNames = outputs.map((name)=>(0, _utils.parseNodeName)(name)[0]);
        const outputNodeNameSet = new Set(outputNodeNames);
        let outputNodes = outputNodeNames.map((name)=>this.graph.nodes[name]);
        // If no outputs are specified, then use the default outputs of the model.
        if (outputNodes.length === 0) outputNodes = this._outputs;
        const compilationKey = this.getCompilationKey(inputNodes, outputNodes);
        // Do nothing if the compiled graph cache contains the input.
        let compilation = this.compiledMap.get(compilationKey);
        if (compilation == null) {
            compilation = this.compile(inputs, outputNodes);
            this.compiledMap.set(compilationKey, compilation);
        }
        // Keep tensors if KEEP_INTERMEDIATE_TENSORS is on.
        try {
            this.keepIntermediateTensors = (0, _tfjsCore.env)().getBool("KEEP_INTERMEDIATE_TENSORS");
        } catch (e) {
            this.keepIntermediateTensors = false;
            console.warn(e.message);
        }
        const tensorArrayMap = {};
        const tensorListMap = {};
        return (0, _tfjsCore.tidy)(()=>{
            const context = new (0, _executionContext.ExecutionContext)(this.weightMap, tensorArrayMap, tensorListMap, this.functionExecutorMap, this.parseNodeNameCache);
            const tensorsMap = Object.assign({}, this.weightMap);
            if (this.keepIntermediateTensors) this.clonedTensorsMap = this.cloneTensorMap(this.weightMap);
            Object.keys(inputs).forEach((name)=>{
                const [nodeName, index] = (0, _utils.parseNodeName)(name, context);
                const tensors = [];
                tensors[index] = inputs[name];
                tensorsMap[nodeName] = tensors;
                if (this.keepIntermediateTensors) this.clonedTensorsMap[nodeName] = this.cloneTensorList(tensors);
            });
            const tensorsToKeep = this.getFrozenTensorIds(tensorsMap);
            const { orderedNodes, nodeLiveUntilMap } = compilation;
            for (const node of orderedNodes){
                if (tensorsMap[node.name]) continue;
                const tensors = (0, _operationExecutor.executeOp)(node, tensorsMap, context, this._resourceManager);
                if ((0, _tfjsCore.util).isPromise(tensors)) throw new Error(`The execution of the op '${node.op}' returned a promise. ` + `Please use model.executeAsync() instead.`);
                tensorsMap[node.name] = tensors;
                if (this.keepIntermediateTensors) this.clonedTensorsMap[node.name] = this.cloneTensorList(tensors);
                this.checkTensorForDisposalWithNodeLiveUntilInfo(node, tensorsMap, context, tensorsToKeep, outputNodeNameSet, nodeLiveUntilMap.get(node.name));
            }
            // dispose the context for the root executor
            if (this.parent == null) context.dispose(tensorsToKeep);
            return outputs.map((name)=>(0, _utils.getTensor)(name, tensorsMap, context));
        });
    }
Executes the inference for given input tensors.
@param inputs Tensor map for the model inputs, keyed by the input node
names.
@param outputs Optional. output node name from the Tensorflow model, if
no outputs are specified, the default outputs of the model would be used.
You can inspect intermediate nodes of the model by adding them to the
outputs array.