/// <summary> /// Generates failed checks that correspond to output shapes incompatibilities between /// the model and the BrainParameters. /// </summary> /// <param name="model"> /// The Barracuda engine model for loading static parameters /// </param> /// <param name="brainParameters"> /// The BrainParameters that are used verify the compatibility with the InferenceEngine /// </param> /// <param name="actuatorComponents">Array of attached actuator components.</param> /// <param name="isContinuous"> /// Whether the model is expecting continuous or discrete control. /// </param> /// <param name="modelContinuousActionSize"> /// The size of the continuous action output that is expected by the model. /// </param> /// <param name="modelSumDiscreteBranchSizes"> /// The size of the discrete action output that is expected by the model. /// </param> /// <returns> /// A IEnumerable of string corresponding to the incompatible shapes between model /// and BrainParameters. /// </returns> static IEnumerable <string> CheckOutputTensorShape( Model model, BrainParameters brainParameters, ActuatorComponent[] actuatorComponents, ModelActionType isContinuous, int modelContinuousActionSize, int modelSumDiscreteBranchSizes) { var failedModelChecks = new List <string>(); if (isContinuous == ModelActionType.Unknown) { failedModelChecks.Add("Cannot infer type of Control from the provided model."); return(failedModelChecks); } if (isContinuous == ModelActionType.Continuous && brainParameters.VectorActionSpaceType != SpaceType.Continuous) { failedModelChecks.Add( "Model has been trained using Continuous Control but the Brain Parameters " + "suggest Discrete Control."); return(failedModelChecks); } if (isContinuous == ModelActionType.Discrete && brainParameters.VectorActionSpaceType != SpaceType.Discrete) { failedModelChecks.Add( "Model has been trained using Discrete Control but the Brain Parameters " + "suggest Continuous Control."); return(failedModelChecks); } var tensorTester = new Dictionary <string, Func <BrainParameters, ActuatorComponent[], TensorShape?, int, int, string> >(); // This will need to change a bit for hybrid action spaces. if (isContinuous == ModelActionType.Continuous) { tensorTester[TensorNames.ActionOutput] = CheckContinuousActionOutputShape; } else { tensorTester[TensorNames.ActionOutput] = CheckDiscreteActionOutputShape; } // If the model expects an output but it is not in this list foreach (var name in model.outputs) { if (tensorTester.ContainsKey(name)) { var tester = tensorTester[name]; var error = tester.Invoke(brainParameters, actuatorComponents, model.GetShapeByName(name), modelContinuousActionSize, modelSumDiscreteBranchSizes); if (error != null) { failedModelChecks.Add(error); } } } return(failedModelChecks); }
/// <summary> /// Generates failed checks that correspond to output shapes incompatibilities between /// the model and the BrainParameters. /// </summary> /// <param name="isContinuous"> Whether the model is expecting continuous or /// discrete control.</param> /// <param name="modelActionSize"> The size of the action output that is expected /// by the model.</param> /// <returns>A IEnumerable of string corresponding to the incompatible shapes between /// model and BrainParameters.</returns> private void CheckOutputTensorShape(ModelActionType isContinuous, int modelActionSize) { if (isContinuous == ModelActionType.Unknown) { _failedModelChecks.Add( "Cannot infer type of Control from the provided model."); return; } if (isContinuous == ModelActionType.Continuous && _brainParameters.vectorActionSpaceType != SpaceType.continuous) { _failedModelChecks.Add( "Model has been trained using Continuous Control but the Brain Parameters " + "suggest Discrete Control."); return; } if (isContinuous == ModelActionType.Discrete && _brainParameters.vectorActionSpaceType != SpaceType.discrete) { _failedModelChecks.Add( "Model has been trained using Discrete Control but the Brain Parameters " + "suggest Continuous Control."); return; } var tensorTester = new Dictionary <string, Func <TensorShape, int, string> >(); if (_brainParameters.vectorActionSpaceType == SpaceType.continuous) { tensorTester[TensorNames.ActionOutput] = CheckContinuousActionOutputShape; } else { tensorTester[TensorNames.ActionOutput] = CheckDiscreteActionOutputShape; } // If the model expects an output but it is not in this list foreach (var name in _model.outputs) { if (tensorTester.ContainsKey(name)) { var tester = tensorTester[name]; var error = tester.Invoke(_model.GetShapeByName(name), modelActionSize); if (error != null) { _failedModelChecks.Add(error); } } } }
/// <summary> /// Generates failed checks that correspond to inputs expected by the model that are not /// present in the BrainParameters. /// </summary> /// <param name="memory"> /// The memory size that the model is expecting. /// </param> /// <param name="isContinuous"> /// Whether the model is expecting continuous or discrete control. /// </param> /// <returns> /// A IEnumerable of string corresponding to the failed input presence checks. /// </returns> private void CheckInputTensorPresence(int memory, ModelActionType isContinuous) { var tensorsNames = GetInputTensors().Select(x => x.name).ToList(); // If there is no Vector Observation Input but the Brain Parameters expect one. if ((m_BrainParameters.vectorObservationSize != 0) && (!tensorsNames.Contains(TensorNames.VectorObservationPlacholder))) { m_FailedModelChecks.Add( "The model does not contain a Vector Observation Placeholder Input. " + "You must set the Vector Observation Space Size to 0."); } // If there are not enough Visual Observation Input compared to what the // Brain Parameters expect. for (var visObsIndex = 0; visObsIndex < m_BrainParameters.cameraResolutions.Length; visObsIndex++) { if (!tensorsNames.Contains( TensorNames.VisualObservationPlaceholderPrefix + visObsIndex)) { m_FailedModelChecks.Add( "The model does not contain a Visual Observation Placeholder Input " + "for visual observation " + visObsIndex + "."); } } // If the model has a non-negative memory size but requires a recurrent input if (memory > 0) { if (!tensorsNames.Any(x => x.EndsWith("_h")) || !tensorsNames.Any(x => x.EndsWith("_c"))) { m_FailedModelChecks.Add( "The model does not contain a Recurrent Input Node but has memory_size."); } } // If the model uses discrete control but does not have an input for action masks if (isContinuous == ModelActionType.Discrete) { if (!tensorsNames.Contains(TensorNames.ActionMaskPlaceholder)) { m_FailedModelChecks.Add( "The model does not contain an Action Mask but is using Discrete Control."); } } }
/// <summary> /// Generates failed checks that correspond to inputs expected by the model that are not /// present in the BrainParameters. /// </summary> /// <param name="model"> /// The Barracuda engine model for loading static parameters /// </param> /// <param name="brainParameters"> /// The BrainParameters that are used verify the compatibility with the InferenceEngine /// </param> /// <param name="memory"> /// The memory size that the model is expecting. /// </param> /// <param name="isContinuous"> /// Whether the model is expecting continuous or discrete control. /// </param> /// <returns> /// A IEnumerable of string corresponding to the failed input presence checks. /// </returns> static IEnumerable <string> CheckInputTensorPresence( Model model, BrainParameters brainParameters, int memory, ModelActionType isContinuous) { var failedModelChecks = new List <string>(); var tensorsNames = GetInputTensors(model).Select(x => x.name).ToList(); // If there is no Vector Observation Input but the Brain Parameters expect one. if ((brainParameters.vectorObservationSize != 0) && (!tensorsNames.Contains(TensorNames.VectorObservationPlacholder))) { failedModelChecks.Add( "The model does not contain a Vector Observation Placeholder Input. " + "You must set the Vector Observation Space Size to 0."); } // TODO reenable checks there are enough Visual Observation Placeholder in the model. // If the model has a non-negative memory size but requires a recurrent input if (memory > 0) { if (!tensorsNames.Any(x => x.EndsWith("_h")) || !tensorsNames.Any(x => x.EndsWith("_c"))) { failedModelChecks.Add( "The model does not contain a Recurrent Input Node but has memory_size."); } } // If the model uses discrete control but does not have an input for action masks if (isContinuous == ModelActionType.Discrete) { if (!tensorsNames.Contains(TensorNames.ActionMaskPlaceholder)) { failedModelChecks.Add( "The model does not contain an Action Mask but is using Discrete Control."); } } return(failedModelChecks); }
/// <summary> /// Generates failed checks that correspond to inputs expected by the model that are not /// present in the BrainParameters. /// </summary> /// <param name="model"> /// The Barracuda engine model for loading static parameters /// </param> /// <param name="brainParameters"> /// The BrainParameters that are used verify the compatibility with the InferenceEngine /// </param> /// <param name="memory"> /// The memory size that the model is expecting. /// </param> /// <param name="isContinuous"> /// Whether the model is expecting continuous or discrete control. /// </param> /// <param name="sensorComponents">Array of attached sensor components</param> /// <returns> /// A IEnumerable of string corresponding to the failed input presence checks. /// </returns> static IEnumerable <string> CheckInputTensorPresence( Model model, BrainParameters brainParameters, int memory, ModelActionType isContinuous, SensorComponent[] sensorComponents ) { var failedModelChecks = new List <string>(); var tensorsNames = GetInputTensors(model).Select(x => x.name).ToList(); // If there is no Vector Observation Input but the Brain Parameters expect one. if ((brainParameters.VectorObservationSize != 0) && (!tensorsNames.Contains(TensorNames.VectorObservationPlaceholder))) { failedModelChecks.Add( "The model does not contain a Vector Observation Placeholder Input. " + "You must set the Vector Observation Space Size to 0."); } // If there are not enough Visual Observation Input compared to what the // sensors expect. var visObsIndex = 0; for (var sensorIndex = 0; sensorIndex < sensorComponents.Length; sensorIndex++) { var sensor = sensorComponents[sensorIndex]; if (!sensor.IsVisual()) { continue; } if (!tensorsNames.Contains( TensorNames.VisualObservationPlaceholderPrefix + visObsIndex)) { failedModelChecks.Add( "The model does not contain a Visual Observation Placeholder Input " + $"for sensor component {visObsIndex} ({sensor.GetType().Name})."); } visObsIndex++; } var expectedVisualObs = GetNumVisualInputs(model); // Check if there's not enough visual sensors (too many would be handled above) if (expectedVisualObs > visObsIndex) { failedModelChecks.Add( $"The model expects {expectedVisualObs} visual inputs," + $" but only found {visObsIndex} visual sensors." ); } // If the model has a non-negative memory size but requires a recurrent input if (memory > 0) { if (!tensorsNames.Any(x => x.EndsWith("_h")) || !tensorsNames.Any(x => x.EndsWith("_c"))) { failedModelChecks.Add( "The model does not contain a Recurrent Input Node but has memory_size."); } } // If the model uses discrete control but does not have an input for action masks if (isContinuous == ModelActionType.Discrete) { if (!tensorsNames.Contains(TensorNames.ActionMaskPlaceholder)) { failedModelChecks.Add( "The model does not contain an Action Mask but is using Discrete Control."); } } return(failedModelChecks); }