using System.Collections.Generic; namespace MLAgents.InferenceBrain { /// /// Mapping between the output Tensor names and the method that will use the /// output tensors and the Agents present in the batch to update their action, memories and /// value estimates. /// A TensorApplier implements a Dictionary of strings (node names) to an Action. /// This action takes as input the Tensor and the Dictionary of Agent to AgentInfo for /// the current batch. /// public class TensorApplier { /// /// A tensor Applier's Execute method takes a Tensor and a Dictionary of Agent to AgentInfo. /// Uses the data contained inside the Tensor to modify the state of the Agent. The Tensors /// are assumed to have the batch size on the first dimension and the agents to be ordered /// the same way in the dictionary and in the Tensor. /// public interface Applier { /// /// Applies the values in the Tensor to the Agents present in the agentInfos /// /// The Tensor containing the data to be applied to the Agents /// Dictionary of Agents to AgentInfo that will reveive /// the values of the Tensor. void Apply(Tensor tensor, Dictionary agentInfo); } Dictionary _dict = new Dictionary(); /// /// Returns a new TensorAppliers object. /// /// The BrainParameters used to determine what Appliers will be /// used /// The seed the Appliers will be initialized with. public TensorApplier(BrainParameters bp, int seed) { _dict[TensorNames.ValueEstimateOutput] = new ValueEstimateApplier(); if (bp.vectorActionSpaceType == SpaceType.continuous) { _dict[TensorNames.ActionOutput] = new ContinuousActionOutputApplier(); } else { _dict[TensorNames.ActionOutput] = new DiscreteActionOutputApplier( bp.vectorActionSize, seed); } _dict[TensorNames.RecurrentOutput] = new MemoryOutputApplier(); _dict[TensorNames.RecurrentOutput_C] = new BarracudaMemoryOutputApplier(true); _dict[TensorNames.RecurrentOutput_H] = new BarracudaMemoryOutputApplier(false); } /// /// Updates the state of the agents based on the data present in the tensor. /// /// Enumerable of tensors containing the data. /// Dictionary of Agent to AgentInfo that contains the /// Agents that will be updated using the tensor's data /// One of the tensor does not have an /// associated applier. public void ApplyTensors( IEnumerable tensors, Dictionary agentInfos) { foreach (var tensor in tensors) { if (!_dict.ContainsKey(tensor.Name)) { throw new UnityAgentsException( "Unknow tensor expected as output : "+tensor.Name); } _dict[tensor.Name].Apply(tensor, agentInfos); } } } }