/// Uses the Decision Component to decide that action to take public void DecideAction(Dictionary <Agent, AgentInfo> agentInfo) { if (coord != null) { coord.GiveBrainInfo(brain, agentInfo); } if (decision == null) { throw new UnityAgentsException("The Brain is set to Heuristic, but no decision script attached to it"); } foreach (Agent agent in agentInfo.Keys) { agent.UpdateVectorAction(decision.Decide( agentInfo[agent].stackedVectorObservation, agentInfo[agent].visualObservations, agentInfo[agent].reward, agentInfo[agent].done, agentInfo[agent].memories)); } foreach (Agent agent in agentInfo.Keys) { agent.UpdateMemoriesAction(decision.MakeMemory( agentInfo[agent].stackedVectorObservation, agentInfo[agent].visualObservations, agentInfo[agent].reward, agentInfo[agent].done, agentInfo[agent].memories)); } }
/// Uses the communicator to retrieve the actions, memories and values and /// sends them to the agents public void DecideAction(Dictionary <Agent, AgentInfo> agentInfo) { if (coord != null) { coord.GiveBrainInfo(brain, agentInfo); } return; }
/// Uses the continuous inputs or dicrete inputs of the player to /// decide action public void DecideAction(Dictionary <Agent, AgentInfo> agentInfo) { if (coord != null) { coord.GiveBrainInfo(brain, agentInfo); } if (brain.brainParameters.vectorActionSpaceType == SpaceType.continuous) { foreach (Agent agent in agentInfo.Keys) { var action = new float[brain.brainParameters.vectorActionSize]; foreach (ContinuousPlayerAction cha in continuousPlayerActions) { if (Input.GetKey(cha.key)) { action[cha.index] = cha.value; } } agent.UpdateVectorAction(action); } } else { foreach (Agent agent in agentInfo.Keys) { var action = new float[1] { defaultAction }; foreach (DiscretePlayerAction dha in discretePlayerActions) { if (Input.GetKey(dha.key)) { action[0] = (float)dha.value; break; } } agent.UpdateVectorAction(action); } } }
/// Uses the stored information to run the tensorflow graph and generate /// the actions. public void DecideAction(Dictionary <Agent, AgentInfo> agentInfo) { #if ENABLE_TENSORFLOW if (coord != null) { coord.GiveBrainInfo(brain, agentInfo); } int currentBatchSize = agentInfo.Count(); List <Agent> agentList = agentInfo.Keys.ToList(); if (currentBatchSize == 0) { return; } // Create the state tensor if (hasState) { int stateLength = 1; if (brain.brainParameters.vectorObservationSpaceType == SpaceType.continuous) { stateLength = brain.brainParameters.vectorObservationSize; } inputState = new float[currentBatchSize, stateLength *brain.brainParameters.numStackedVectorObservations]; var i = 0; foreach (Agent agent in agentList) { List <float> state_list = agentInfo[agent].stackedVectorObservation; for (int j = 0; j < brain.brainParameters.vectorObservationSize * brain.brainParameters.numStackedVectorObservations; j++) { inputState[i, j] = state_list[j]; } i++; } } // Create the state tensor if (hasPrevAction) { inputPrevAction = new int[currentBatchSize]; var i = 0; foreach (Agent agent in agentList) { float[] action_list = agentInfo[agent].storedVectorActions; inputPrevAction[i] = Mathf.FloorToInt(action_list[0]); i++; } } observationMatrixList.Clear(); for (int observationIndex = 0; observationIndex < brain.brainParameters.cameraResolutions.Count(); observationIndex++) { texturesHolder.Clear(); foreach (Agent agent in agentList) { texturesHolder.Add(agentInfo[agent].visualObservations[observationIndex]); } observationMatrixList.Add( BatchVisualObservations(texturesHolder, brain.brainParameters.cameraResolutions[observationIndex].blackAndWhite)); } // Create the recurrent tensor if (hasRecurrent) { // Need to have variable memory size inputOldMemories = new float[currentBatchSize, memorySize]; var i = 0; foreach (Agent agent in agentList) { float[] m = agentInfo[agent].memories.ToArray(); for (int j = 0; j < m.Count(); j++) { inputOldMemories[i, j] = m[j]; } i++; } } var runner = session.GetRunner(); try { runner.Fetch(graph[graphScope + ActionPlaceholderName][0]); } catch { throw new UnityAgentsException(string.Format(@"The node {0} could not be found. Please make sure the graphScope {1} is correct", graphScope + ActionPlaceholderName, graphScope)); } if (hasBatchSize) { runner.AddInput(graph[graphScope + BatchSizePlaceholderName][0], new int[] { currentBatchSize }); } foreach (TensorFlowAgentPlaceholder placeholder in graphPlaceholders) { try { if (placeholder.valueType == TensorFlowAgentPlaceholder.tensorType.FloatingPoint) { runner.AddInput(graph[graphScope + placeholder.name][0], new float[] { Random.Range(placeholder.minValue, placeholder.maxValue) }); } else if (placeholder.valueType == TensorFlowAgentPlaceholder.tensorType.Integer) { runner.AddInput(graph[graphScope + placeholder.name][0], new int[] { Random.Range((int)placeholder.minValue, (int)placeholder.maxValue + 1) }); } } catch { throw new UnityAgentsException(string.Format(@"One of the Tensorflow placeholder cound nout be found. In brain {0}, there are no {1} placeholder named {2}.", brain.gameObject.name, placeholder.valueType.ToString(), graphScope + placeholder.name)); } } // Create the state tensor if (hasState) { if (brain.brainParameters.vectorObservationSpaceType == SpaceType.discrete) { var discreteInputState = new int[currentBatchSize, 1]; for (int i = 0; i < currentBatchSize; i++) { discreteInputState[i, 0] = (int)inputState[i, 0]; } runner.AddInput(graph[graphScope + VectorObservationPlacholderName][0], discreteInputState); } else { runner.AddInput(graph[graphScope + VectorObservationPlacholderName][0], inputState); } } // Create the previous action tensor if (hasPrevAction) { runner.AddInput(graph[graphScope + PreviousActionPlaceholderName][0], inputPrevAction); } // Create the observation tensors for (int obs_number = 0; obs_number < brain.brainParameters.cameraResolutions.Length; obs_number++) { runner.AddInput(graph[graphScope + VisualObservationPlaceholderName[obs_number]][0], observationMatrixList[obs_number]); } if (hasRecurrent) { runner.AddInput(graph[graphScope + "sequence_length"][0], 1); runner.AddInput(graph[graphScope + RecurrentInPlaceholderName][0], inputOldMemories); runner.Fetch(graph[graphScope + RecurrentOutPlaceholderName][0]); } TFTensor[] networkOutput; try { networkOutput = runner.Run(); } catch (TFException e) { string errorMessage = e.Message; try { errorMessage = string.Format(@"The tensorflow graph needs an input for {0} of type {1}", e.Message.Split(new string[] { "Node: " }, 0)[1].Split('=')[0], e.Message.Split(new string[] { "dtype=" }, 0)[1].Split(',')[0]); } finally { throw new UnityAgentsException(errorMessage); } } // Create the recurrent tensor if (hasRecurrent) { float[,] recurrent_tensor = networkOutput[1].GetValue() as float[, ]; var i = 0; foreach (Agent agent in agentList) { var m = new float[memorySize]; for (int j = 0; j < memorySize; j++) { m[j] = recurrent_tensor[i, j]; } agent.UpdateMemoriesAction(m.ToList()); i++; } } if (brain.brainParameters.vectorActionSpaceType == SpaceType.continuous) { var output = networkOutput[0].GetValue() as float[, ]; var i = 0; foreach (Agent agent in agentList) { var a = new float[brain.brainParameters.vectorActionSize]; for (int j = 0; j < brain.brainParameters.vectorActionSize; j++) { a[j] = output[i, j]; } agent.UpdateVectorAction(a); i++; } } else if (brain.brainParameters.vectorActionSpaceType == SpaceType.discrete) { long[,] output = networkOutput[0].GetValue() as long[, ]; var i = 0; foreach (Agent agent in agentList) { var a = new float[1] { (float)(output[i, 0]) }; agent.UpdateVectorAction(a); i++; } } #else if (agentInfo.Count > 0) { throw new UnityAgentsException(string.Format(@"The brain {0} was set to Internal but the Tensorflow library is not present in the Unity project.", brain.gameObject.name)); } #endif }