Bladeren bron

Initial checkin of a GEM for basic ML functionality within script canvas

Signed-off-by: kberg-amzn <[email protected]>
kberg-amzn 2 jaren geleden
bovenliggende
commit
6d213941ce
69 gewijzigde bestanden met toevoegingen van 1707 en 0 verwijderingen
  1. 0 0
      Gems/MachineLearning/.gitignore
  2. 54 0
      Gems/MachineLearning/Assets/TranslationAssets/Nodes/Computecostgradient_0FA8FC88-6C4B-9260-6CC3-F2154691B279.names
  3. 54 0
      Gems/MachineLearning/Assets/TranslationAssets/Nodes/Createsanewmachinelearningmodel_8B5BA564-BEAF-B290-6224-F82B7618735C.names
  4. 48 0
      Gems/MachineLearning/Assets/TranslationAssets/Nodes/Feedforward_CE7FD101-9866-AD89-0D38-90165BD10B2C.names
  5. 22 0
      Gems/MachineLearning/CMakeLists.txt
  6. 233 0
      Gems/MachineLearning/Code/CMakeLists.txt
  7. 40 0
      Gems/MachineLearning/Code/Include/MachineLearning/INeuralNetwork.h
  8. 41 0
      Gems/MachineLearning/Code/Include/MachineLearning/MachineLearningBus.h
  9. 26 0
      Gems/MachineLearning/Code/Include/MachineLearning/MachineLearningTypeIds.h
  10. 4 0
      Gems/MachineLearning/Code/Platform/Android/PAL_android.cmake
  11. 3 0
      Gems/MachineLearning/Code/Platform/Android/machinelearning_api_files.cmake
  12. 8 0
      Gems/MachineLearning/Code/Platform/Android/machinelearning_private_files.cmake
  13. 8 0
      Gems/MachineLearning/Code/Platform/Android/machinelearning_shared_files.cmake
  14. 4 0
      Gems/MachineLearning/Code/Platform/Linux/PAL_linux.cmake
  15. 3 0
      Gems/MachineLearning/Code/Platform/Linux/machinelearning_api_files.cmake
  16. 3 0
      Gems/MachineLearning/Code/Platform/Linux/machinelearning_editor_api_files.cmake
  17. 8 0
      Gems/MachineLearning/Code/Platform/Linux/machinelearning_private_files.cmake
  18. 8 0
      Gems/MachineLearning/Code/Platform/Linux/machinelearning_shared_files.cmake
  19. 4 0
      Gems/MachineLearning/Code/Platform/Mac/PAL_mac.cmake
  20. 3 0
      Gems/MachineLearning/Code/Platform/Mac/machinelearning_api_files.cmake
  21. 3 0
      Gems/MachineLearning/Code/Platform/Mac/machinelearning_editor_api_files.cmake
  22. 8 0
      Gems/MachineLearning/Code/Platform/Mac/machinelearning_private_files.cmake
  23. 8 0
      Gems/MachineLearning/Code/Platform/Mac/machinelearning_shared_files.cmake
  24. 4 0
      Gems/MachineLearning/Code/Platform/Windows/PAL_windows.cmake
  25. 3 0
      Gems/MachineLearning/Code/Platform/Windows/machinelearning_api_files.cmake
  26. 3 0
      Gems/MachineLearning/Code/Platform/Windows/machinelearning_editor_api_files.cmake
  27. 8 0
      Gems/MachineLearning/Code/Platform/Windows/machinelearning_private_files.cmake
  28. 8 0
      Gems/MachineLearning/Code/Platform/Windows/machinelearning_shared_files.cmake
  29. 4 0
      Gems/MachineLearning/Code/Platform/iOS/PAL_ios.cmake
  30. 3 0
      Gems/MachineLearning/Code/Platform/iOS/machinelearning_api_files.cmake
  31. 8 0
      Gems/MachineLearning/Code/Platform/iOS/machinelearning_private_files.cmake
  32. 8 0
      Gems/MachineLearning/Code/Platform/iOS/machinelearning_shared_files.cmake
  33. 17 0
      Gems/MachineLearning/Code/Source/MachineLearningModule.cpp
  34. 40 0
      Gems/MachineLearning/Code/Source/MachineLearningModuleInterface.cpp
  35. 31 0
      Gems/MachineLearning/Code/Source/MachineLearningModuleInterface.h
  36. 87 0
      Gems/MachineLearning/Code/Source/MachineLearningSystemComponent.cpp
  37. 47 0
      Gems/MachineLearning/Code/Source/MachineLearningSystemComponent.h
  38. 74 0
      Gems/MachineLearning/Code/Source/Models/Layer.cpp
  39. 40 0
      Gems/MachineLearning/Code/Source/Models/Layer.h
  40. 135 0
      Gems/MachineLearning/Code/Source/Models/MultilayerPerceptron.cpp
  41. 52 0
      Gems/MachineLearning/Code/Source/Models/MultilayerPerceptron.h
  42. 17 0
      Gems/MachineLearning/Code/Source/Nodes/ComputeCost.ScriptCanvasNodeable.xml
  43. 18 0
      Gems/MachineLearning/Code/Source/Nodes/ComputeCost.cpp
  44. 24 0
      Gems/MachineLearning/Code/Source/Nodes/ComputeCost.h
  45. 17 0
      Gems/MachineLearning/Code/Source/Nodes/CreateModel.ScriptCanvasNodeable.xml
  46. 25 0
      Gems/MachineLearning/Code/Source/Nodes/CreateModel.cpp
  47. 24 0
      Gems/MachineLearning/Code/Source/Nodes/CreateModel.h
  48. 16 0
      Gems/MachineLearning/Code/Source/Nodes/FeedForward.ScriptCanvasNodeable.xml
  49. 19 0
      Gems/MachineLearning/Code/Source/Nodes/FeedForward.cpp
  50. 24 0
      Gems/MachineLearning/Code/Source/Nodes/FeedForward.h
  51. 39 0
      Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorModule.cpp
  52. 59 0
      Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorSystemComponent.cpp
  53. 34 0
      Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorSystemComponent.h
  54. 11 0
      Gems/MachineLearning/Code/Tests/MachineLearningTests.cpp
  55. 31 0
      Gems/MachineLearning/Code/Tests/Models/LayerTests.cpp
  56. 14 0
      Gems/MachineLearning/Code/Tests/Models/MultilayerPerceptronTests.cpp
  57. 4 0
      Gems/MachineLearning/Code/Tests/Tools/MachineLearningEditorTest.cpp
  58. 13 0
      Gems/MachineLearning/Code/machinelearning_api_files.cmake
  59. 10 0
      Gems/MachineLearning/Code/machinelearning_editor_api_files.cmake
  60. 12 0
      Gems/MachineLearning/Code/machinelearning_editor_private_files.cmake
  61. 11 0
      Gems/MachineLearning/Code/machinelearning_editor_shared_files.cmake
  62. 4 0
      Gems/MachineLearning/Code/machinelearning_editor_tests_files.cmake
  63. 27 0
      Gems/MachineLearning/Code/machinelearning_private_files.cmake
  64. 11 0
      Gems/MachineLearning/Code/machinelearning_shared_files.cmake
  65. 13 0
      Gems/MachineLearning/Code/machinelearning_tests_files.cmake
  66. 16 0
      Gems/MachineLearning/Code/scriptcanvas_autogen_files.cmake
  67. 18 0
      Gems/MachineLearning/Registry/assetprocessor_settings.setreg
  68. 28 0
      Gems/MachineLearning/gem.json
  69. 3 0
      Gems/MachineLearning/preview.png

+ 0 - 0
Gems/MachineLearning/.gitignore


+ 54 - 0
Gems/MachineLearning/Assets/TranslationAssets/Nodes/Computecostgradient_0FA8FC88-6C4B-9260-6CC3-F2154691B279.names

@@ -0,0 +1,54 @@
+{
+    "entries": [
+        {
+            "base": "{0FA8FC88-6C4B-9260-6CC3-F2154691B279}",
+            "context": "ScriptCanvas::Node",
+            "variant": "",
+            "details": {
+                "name": "Compute cost gradient",
+                "category": "MachineLearning",
+                "tooltip": "Calculates the cost gradient for a machine learning model against a set of activations and a set of expected outputs."
+            },
+            "slots": [
+                {
+                    "base": "Input_In_0",
+                    "details": {
+                        "name": "In",
+                        "tooltip": "Parameters controlling cost gradient calculation"
+                    }
+                },
+                {
+                    "base": "DataInput_Model_0",
+                    "details": {
+                        "name": "Model"
+                    }
+                },
+                {
+                    "base": "DataInput_Activations_1",
+                    "details": {
+                        "name": "Activations"
+                    }
+                },
+                {
+                    "base": "DataInput_ExpectedOutput_2",
+                    "details": {
+                        "name": "ExpectedOutput"
+                    }
+                },
+                {
+                    "base": "Output_On In_0",
+                    "details": {
+                        "name": "On In",
+                        "tooltip": "Parameters controlling cost gradient calculation"
+                    }
+                },
+                {
+                    "base": "DataOutput_Cost_0",
+                    "details": {
+                        "name": "Cost"
+                    }
+                }
+            ]
+        }
+    ]
+}

+ 54 - 0
Gems/MachineLearning/Assets/TranslationAssets/Nodes/Createsanewmachinelearningmodel_8B5BA564-BEAF-B290-6224-F82B7618735C.names

@@ -0,0 +1,54 @@
+{
+    "entries": [
+        {
+            "base": "{8B5BA564-BEAF-B290-6224-F82B7618735C}",
+            "context": "ScriptCanvas::Node",
+            "variant": "",
+            "details": {
+                "name": "Create new model",
+                "category": "MachineLearning",
+                "tooltip": "Creates a new untrained machine learning model. All parameters will be initialized to random values."
+            },
+            "slots": [
+                {
+                    "base": "Input_In_0",
+                    "details": {
+                        "name": "In",
+                        "tooltip": "Parameters controlling the new model"
+                    }
+                },
+                {
+                    "base": "DataInput_Input neurons_0",
+                    "details": {
+                        "name": "Input neurons"
+                    }
+                },
+                {
+                    "base": "DataInput_Output neurons_1",
+                    "details": {
+                        "name": "Output neurons"
+                    }
+                },
+                {
+                    "base": "DataInput_Hidden layers_2",
+                    "details": {
+                        "name": "Hidden layers"
+                    }
+                },
+                {
+                    "base": "Output_On In_0",
+                    "details": {
+                        "name": "On In",
+                        "tooltip": "Parameters controlling the new model"
+                    }
+                },
+                {
+                    "base": "DataOutput_Model_0",
+                    "details": {
+                        "name": "Model"
+                    }
+                }
+            ]
+        }
+    ]
+}

+ 48 - 0
Gems/MachineLearning/Assets/TranslationAssets/Nodes/Feedforward_CE7FD101-9866-AD89-0D38-90165BD10B2C.names

@@ -0,0 +1,48 @@
+{
+    "entries": [
+        {
+            "base": "{CE7FD101-9866-AD89-0D38-90165BD10B2C}",
+            "context": "ScriptCanvas::Node",
+            "variant": "",
+            "details": {
+                "name": "Feed forward",
+                "category": "MachineLearning",
+                "tooltip": "Performs a feed-forward operation on the model to obtain a set of outputs given an input."
+            },
+            "slots": [
+                {
+                    "base": "Input_In_0",
+                    "details": {
+                        "name": "In",
+                        "tooltip": "Parameters controlling the feed forward operation"
+                    }
+                },
+                {
+                    "base": "DataInput_Model_0",
+                    "details": {
+                        "name": "Model"
+                    }
+                },
+                {
+                    "base": "DataInput_Activations_1",
+                    "details": {
+                        "name": "Activations"
+                    }
+                },
+                {
+                    "base": "Output_On In_0",
+                    "details": {
+                        "name": "On In",
+                        "tooltip": "Parameters controlling the feed forward operation"
+                    }
+                },
+                {
+                    "base": "DataOutput_Output_0",
+                    "details": {
+                        "name": "Output"
+                    }
+                }
+            ]
+        }
+    ]
+}

+ 22 - 0
Gems/MachineLearning/CMakeLists.txt

@@ -0,0 +1,22 @@
+
+# Query the gem name from the gem.json file if possible
+# otherwise fallback to using MachineLearning
+o3de_find_ancestor_gem_root(gem_path gem_name "${CMAKE_CURRENT_SOURCE_DIR}")
+if (NOT gem_name)
+    set(gem_name "MachineLearning")
+endif()
+
+# Fallback to using the current source CMakeLists.txt directory as the gem root path
+if (NOT gem_path)
+    set(gem_path ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+set(gem_json ${gem_path}/gem.json)
+
+o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
+
+o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
+ly_add_external_target_path(${CMAKE_CURRENT_SOURCE_DIR}/3rdParty)
+
+add_subdirectory(Code)

+ 233 - 0
Gems/MachineLearning/Code/CMakeLists.txt

@@ -0,0 +1,233 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# Currently we are in the Code folder: ${CMAKE_CURRENT_LIST_DIR}
+# Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}
+# Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform
+#       in which case it will see if that platform is present here or in the restricted folder.
+#       i.e. It could here in our gem : Gems/MachineLearning/Code/Platform/<platorm_name>  or
+#            <restricted_folder>/<platform_name>/Gems/MachineLearning/Code
+o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
+# Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the
+# traits for this platform. Traits for a platform are defines for things like whether or not something in this gem
+# is supported by this platform.
+include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
+
+# Check to see if building the Gem Modules are supported for the current platform
+if(NOT PAL_TRAIT_MACHINELEARNING_SUPPORTED)
+    return()
+endif()
+
+# The ${gem_name}.API target declares the common interface that users of this gem should depend on in their targets
+ly_add_target(
+    NAME ${gem_name}.API INTERFACE
+    NAMESPACE Gem
+    FILES_CMAKE
+        machinelearning_api_files.cmake
+        ${pal_dir}/machinelearning_api_files.cmake
+    INCLUDE_DIRECTORIES
+        INTERFACE
+            Include
+    BUILD_DEPENDENCIES
+        INTERFACE
+           AZ::AzCore
+)
+
+# The ${gem_name}.Private.Object target is an internal target
+# It should not be used outside of this Gems CMakeLists.txt
+ly_add_target(
+    NAME ${gem_name}.Private.Object STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        scriptcanvas_autogen_files.cmake
+        machinelearning_private_files.cmake
+        ${pal_dir}/machinelearning_private_files.cmake
+    TARGET_PROPERTIES
+        O3DE_PRIVATE_TARGET TRUE
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Include
+            Source
+    BUILD_DEPENDENCIES
+        PUBLIC
+            AZ::AzCore
+            AZ::AzFramework
+            Gem::ScriptCanvas
+    AUTOGEN_RULES
+        *.ScriptCanvasNodeable.xml,ScriptCanvasNodeable_Header.jinja,$path/$fileprefix.generated.h
+        *.ScriptCanvasNodeable.xml,ScriptCanvasNodeable_Source.jinja,$path/$fileprefix.generated.cpp
+        *.ScriptCanvasNodeable.xml,ScriptCanvasNodeableRegistry_Header.jinja,AutoGenNodeableRegistry.generated.h
+        *.ScriptCanvasNodeable.xml,ScriptCanvasNodeableRegistry_Source.jinja,AutoGenNodeableRegistry.generated.cpp
+)
+
+# Here add ${gem_name} target, it depends on the Private Object library and Public API interface
+ly_add_target(
+    NAME ${gem_name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        machinelearning_shared_files.cmake
+        ${pal_dir}/machinelearning_shared_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+    BUILD_DEPENDENCIES
+        PUBLIC
+            Gem::${gem_name}.API
+        PRIVATE
+            Gem::${gem_name}.Private.Object
+)
+
+# By default, we will specify that the above target ${gem_name} would be used by
+# Client and Server type targets when this gem is enabled.  If you don't want it
+# active in Clients or Servers by default, delete one of both of the following lines:
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem TARGETS Gem::${gem_name} Gem::ScriptCanvas)
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem TARGETS Gem::${gem_name} Gem::ScriptCanvas)
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem TARGETS Gem::${gem_name} Gem::ScriptCanvas)
+
+# For the Client and Server variants of ${gem_name} Gem, an alias to the ${gem_name}.API target will be made
+ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
+ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
+ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
+
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Clients, Servers, Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
+
+# If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
+if(PAL_TRAIT_BUILD_HOST_TOOLS)
+    # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
+    ly_add_target(
+        NAME ${gem_name}.Editor.API INTERFACE
+        NAMESPACE Gem
+        FILES_CMAKE
+            machinelearning_editor_api_files.cmake
+            ${pal_dir}/machinelearning_editor_api_files.cmake
+        INCLUDE_DIRECTORIES
+            INTERFACE
+                Include
+        BUILD_DEPENDENCIES
+            INTERFACE
+                AZ::AzToolsFramework
+    )
+
+    # The ${gem_name}.Editor.Private.Object target is an internal target
+    # which is only to be used by this gems CMakeLists.txt and any subdirectories
+    # Other gems should not use this target
+    ly_add_target(
+        NAME ${gem_name}.Editor.Private.Object STATIC
+        NAMESPACE Gem
+        FILES_CMAKE
+            machinelearning_editor_private_files.cmake
+        TARGET_PROPERTIES
+            O3DE_PRIVATE_TARGET TRUE
+        INCLUDE_DIRECTORIES
+            PRIVATE
+                Include
+                Source
+        BUILD_DEPENDENCIES
+            PUBLIC
+                AZ::AzToolsFramework
+                $<TARGET_OBJECTS:Gem::${gem_name}.Private.Object>
+    )
+
+    ly_add_target(
+        NAME ${gem_name}.Editor GEM_MODULE
+        NAMESPACE Gem
+        AUTOMOC
+        FILES_CMAKE
+            machinelearning_editor_shared_files.cmake
+        INCLUDE_DIRECTORIES
+            PRIVATE
+                Source
+            PUBLIC
+                Include
+        BUILD_DEPENDENCIES
+            PUBLIC
+                Gem::${gem_name}.Editor.API
+            PRIVATE
+                Gem::${gem_name}.Editor.Private.Object
+    )
+
+    # By default, we will specify that the above target ${gem_name} would be used by
+    # Tool and Builder type targets when this gem is enabled.  If you don't want it
+    # active in Tools or Builders by default, delete one of both of the following lines:
+    ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem TARGETS Gem::${gem_name} Gem::ScriptCanvas.Editor)
+    ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name} Gem::ScriptCanvas.Editor)
+
+    # For the Tools and Builders variants of ${gem_name} Gem, an alias to the ${gem_name}.Editor API target will be made
+    ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
+    ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
+
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
+endif()
+
+################################################################################
+# Tests
+################################################################################
+# See if globally, tests are supported
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
+    # We globally support tests, see if we support tests on this platform for ${gem_name}.Tests
+    if(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED)
+        # We support ${gem_name}.Tests on this platform, add dependency on the Private Object target
+        ly_add_target(
+            NAME ${gem_name}.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+            NAMESPACE Gem
+            FILES_CMAKE
+                machinelearning_tests_files.cmake
+            INCLUDE_DIRECTORIES
+                PRIVATE
+                    Tests
+                    Source
+                    Include
+            BUILD_DEPENDENCIES
+                PRIVATE
+                    AZ::AzTest
+                    AZ::AzFramework
+                    Gem::${gem_name}.Private.Object
+        )
+
+        # Add ${gem_name}.Tests to googletest
+        ly_add_googletest(
+            NAME Gem::${gem_name}.Tests
+        )
+    endif()
+
+    # If we are a host platform we want to add tools test like editor tests here
+    if(PAL_TRAIT_BUILD_HOST_TOOLS)
+        # We are a host platform, see if Editor tests are supported on this platform
+        if(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED)
+            # We support ${gem_name}.Editor.Tests on this platform, add ${gem_name}.Editor.Tests target which depends on
+            # private ${gem_name}.Editor.Private.Object target
+            ly_add_target(
+                NAME ${gem_name}.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+                NAMESPACE Gem
+                FILES_CMAKE
+                    machinelearning_editor_tests_files.cmake
+                INCLUDE_DIRECTORIES
+                    PRIVATE
+                        Tests
+                        Source
+                        Include
+                BUILD_DEPENDENCIES
+                    PRIVATE
+                        AZ::AzTest
+                        Gem::${gem_name}.Editor.Private.Object
+            )
+
+            # Add ${gem_name}.Editor.Tests to googletest
+            ly_add_googletest(
+                NAME Gem::${gem_name}.Editor.Tests
+            )
+        endif()
+    endif()
+endif()

+ 40 - 0
Gems/MachineLearning/Code/Include/MachineLearning/INeuralNetwork.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Math/VectorN.h>
+
+namespace MachineLearning
+{
+    enum class CostFunctions
+    {
+        Quadratic
+    };
+
+    class INeuralNetwork
+    {
+    public:
+
+        AZ_TYPE_INFO(INeuralNetwork, "{64E5B5B1-4A7D-489D-9A29-D9510BB7E17A}");
+
+        virtual ~INeuralNetwork() = default;
+
+        //! Returns the total number of parameters in the neural network.
+        virtual AZStd::size_t GetParameterCount() const = 0;
+
+        //! Performs a basic feed-forward operation to compute the output from a set of activation values.
+        virtual const AZ::VectorN& FeedForward(const AZ::VectorN& activations) = 0;
+
+        //! Given a set of activations and an expected output, computes the cost of the 
+        virtual float ComputeCost(const AZ::VectorN& activations, const AZ::VectorN& expectedOutput, CostFunctions costFunction) = 0;
+    };
+
+    using INeuralNetworkPtr = AZStd::shared_ptr<INeuralNetwork>;
+    using HiddenLayerParams = AZStd::vector<AZStd::size_t>;
+}

+ 41 - 0
Gems/MachineLearning/Code/Include/MachineLearning/MachineLearningBus.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <MachineLearning/MachineLearningTypeIds.h>
+#include <MachineLearning/INeuralNetwork.h>
+
+#include <AzCore/EBus/EBus.h>
+#include <AzCore/Interface/Interface.h>
+
+namespace MachineLearning
+{
+    class MachineLearningRequests
+    {
+    public:
+        AZ_RTTI(MachineLearningRequests, MachineLearningRequestsTypeId);
+        virtual ~MachineLearningRequests() = default;
+        // Put your public methods here
+    };
+
+    class MachineLearningBusTraits
+        : public AZ::EBusTraits
+    {
+    public:
+        //////////////////////////////////////////////////////////////////////////
+        // EBusTraits overrides
+        static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
+        static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
+        //////////////////////////////////////////////////////////////////////////
+    };
+
+    using MachineLearningRequestBus = AZ::EBus<MachineLearningRequests, MachineLearningBusTraits>;
+    using MachineLearningInterface = AZ::Interface<MachineLearningRequests>;
+
+} // namespace MachineLearning

+ 26 - 0
Gems/MachineLearning/Code/Include/MachineLearning/MachineLearningTypeIds.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+namespace MachineLearning
+{
+    // System Component TypeIds
+    inline constexpr const char* MachineLearningSystemComponentTypeId = "{D1A87047-6088-42F6-9275-D6BCE2266322}";
+    inline constexpr const char* MachineLearningEditorSystemComponentTypeId = "{EE7AB2E3-9A4B-45B8-93FE-B5FC6ED0D6FF}";
+
+    // Module derived classes TypeIds
+    inline constexpr const char* MachineLearningModuleInterfaceTypeId = "{DC0A66D9-3EE9-41D7-BDA0-40BE1AFE60C3}";
+    inline constexpr const char* MachineLearningModuleTypeId = "{39CB5F37-F185-45F9-B0FA-20EB56797055}";
+    // The Editor Module by default is mutually exclusive with the Client Module
+    // so they use the Same TypeId
+    inline constexpr const char* MachineLearningEditorModuleTypeId = MachineLearningModuleTypeId;
+
+    // Interface TypeIds
+    inline constexpr const char* MachineLearningRequestsTypeId = "{B65151FE-3588-432A-A0EE-1DB5BF5147CA}";
+} // namespace MachineLearning

+ 4 - 0
Gems/MachineLearning/Code/Platform/Android/PAL_android.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_MACHINELEARNING_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Android/machinelearning_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Android/machinelearning_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Android
+# i.e. ../Source/Android/MachineLearningAndroid.cpp
+#      ../Source/Android/MachineLearningAndroid.h
+#      ../Include/Android/MachineLearningAndroid.h
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Android/machinelearning_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Android
+# i.e. ../Source/Android/MachineLearningAndroid.cpp
+#      ../Source/Android/MachineLearningAndroid.h
+#      ../Include/Android/MachineLearningAndroid.h
+
+set(FILES
+)

+ 4 - 0
Gems/MachineLearning/Code/Platform/Linux/PAL_linux.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_MACHINELEARNING_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Linux/machinelearning_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Linux/machinelearning_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Linux/machinelearning_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Linux
+# i.e. ../Source/Linux/MachineLearningLinux.cpp
+#      ../Source/Linux/MachineLearningLinux.h
+#      ../Include/Linux/MachineLearningLinux.h
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Linux/machinelearning_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Linux
+# i.e. ../Source/Linux/MachineLearningLinux.cpp
+#      ../Source/Linux/MachineLearningLinux.h
+#      ../Include/Linux/MachineLearningLinux.h
+
+set(FILES
+)

+ 4 - 0
Gems/MachineLearning/Code/Platform/Mac/PAL_mac.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_MACHINELEARNING_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Mac/machinelearning_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Mac/machinelearning_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Mac/machinelearning_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Mac
+# i.e. ../Source/Mac/MachineLearningMac.cpp
+#      ../Source/Mac/MachineLearningMac.h
+#      ../Include/Mac/MachineLearningMac.h
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Mac/machinelearning_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Mac
+# i.e. ../Source/Mac/MachineLearningMac.cpp
+#      ../Source/Mac/MachineLearningMac.h
+#      ../Include/Mac/MachineLearningMac.h
+
+set(FILES
+)

+ 4 - 0
Gems/MachineLearning/Code/Platform/Windows/PAL_windows.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_MACHINELEARNING_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Windows/machinelearning_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 3 - 0
Gems/MachineLearning/Code/Platform/Windows/machinelearning_editor_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Windows/machinelearning_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Windows
+# i.e. ../Source/Windows/MachineLearningWindows.cpp
+#      ../Source/Windows/MachineLearningWindows.h
+#      ../Include/Windows/MachineLearningWindows.h
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/Windows/machinelearning_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for Windows
+# i.e. ../Source/Windows/MachineLearningWindows.cpp
+#      ../Source/Windows/MachineLearningWindows.h
+#      ../Include/Windows/MachineLearningWindows.h
+
+set(FILES
+)

+ 4 - 0
Gems/MachineLearning/Code/Platform/iOS/PAL_ios.cmake

@@ -0,0 +1,4 @@
+
+set(PAL_TRAIT_MACHINELEARNING_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_MACHINELEARNING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 0
Gems/MachineLearning/Code/Platform/iOS/machinelearning_api_files.cmake

@@ -0,0 +1,3 @@
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/iOS/machinelearning_private_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for iOS
+# i.e. ../Source/iOS/MachineLearningiOS.cpp
+#      ../Source/iOS/MachineLearningiOS.h
+#      ../Include/iOS/MachineLearningiOS.h
+
+set(FILES
+)

+ 8 - 0
Gems/MachineLearning/Code/Platform/iOS/machinelearning_shared_files.cmake

@@ -0,0 +1,8 @@
+
+# Platform specific files for iOS
+# i.e. ../Source/iOS/MachineLearningiOS.cpp
+#      ../Source/iOS/MachineLearningiOS.h
+#      ../Include/iOS/MachineLearningiOS.h
+
+set(FILES
+)

+ 17 - 0
Gems/MachineLearning/Code/Source/MachineLearningModule.cpp

@@ -0,0 +1,17 @@
+
+#include <MachineLearning/MachineLearningTypeIds.h>
+#include <MachineLearningModuleInterface.h>
+#include "MachineLearningSystemComponent.h"
+
+namespace MachineLearning
+{
+    class MachineLearningModule
+        : public MachineLearningModuleInterface
+    {
+    public:
+        AZ_RTTI(MachineLearningModule, MachineLearningModuleTypeId, MachineLearningModuleInterface);
+        AZ_CLASS_ALLOCATOR(MachineLearningModule, AZ::SystemAllocator);
+    };
+}// namespace MachineLearning
+
+AZ_DECLARE_MODULE_CLASS(Gem_MachineLearning, MachineLearning::MachineLearningModule)

+ 40 - 0
Gems/MachineLearning/Code/Source/MachineLearningModuleInterface.cpp

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "MachineLearningModuleInterface.h"
+#include <AzCore/Memory/Memory.h>
+
+#include <MachineLearning/MachineLearningTypeIds.h>
+
+#include <MachineLearningSystemComponent.h>
+
+namespace MachineLearning
+{
+    AZ_TYPE_INFO_WITH_NAME_IMPL(MachineLearningModuleInterface,
+        "MachineLearningModuleInterface", MachineLearningModuleInterfaceTypeId);
+    AZ_RTTI_NO_TYPE_INFO_IMPL(MachineLearningModuleInterface, AZ::Module);
+    AZ_CLASS_ALLOCATOR_IMPL(MachineLearningModuleInterface, AZ::SystemAllocator);
+
+    MachineLearningModuleInterface::MachineLearningModuleInterface()
+    {
+        // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+        // Add ALL components descriptors associated with this gem to m_descriptors.
+        // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext.
+        // This happens through the [MyComponent]::Reflect() function.
+        m_descriptors.insert(m_descriptors.end(), {
+            MachineLearningSystemComponent::CreateDescriptor(),
+            });
+    }
+
+    AZ::ComponentTypeList MachineLearningModuleInterface::GetRequiredSystemComponents() const
+    {
+        return AZ::ComponentTypeList{
+            azrtti_typeid<MachineLearningSystemComponent>(),
+        };
+    }
+} // namespace MachineLearning

+ 31 - 0
Gems/MachineLearning/Code/Source/MachineLearningModuleInterface.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzCore/Memory/Memory_fwd.h>
+#include <AzCore/Module/Module.h>
+#include <AzCore/RTTI/RTTIMacros.h>
+#include <AzCore/RTTI/TypeInfoSimple.h>
+
+namespace MachineLearning
+{
+    class MachineLearningModuleInterface
+        : public AZ::Module
+    {
+    public:
+        AZ_TYPE_INFO_WITH_NAME_DECL(MachineLearningModuleInterface)
+        AZ_RTTI_NO_TYPE_INFO_DECL()
+        AZ_CLASS_ALLOCATOR_DECL
+
+        MachineLearningModuleInterface();
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override;
+    };
+}// namespace MachineLearning

+ 87 - 0
Gems/MachineLearning/Code/Source/MachineLearningSystemComponent.cpp

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "MachineLearningSystemComponent.h"
+#include <MachineLearning/MachineLearningTypeIds.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <Models/Layer.h>
+#include <Models/MultilayerPerceptron.h>
+#include <AutoGenNodeableRegistry.generated.h>
+
+static ScriptCanvas::MachineLearningPrivateObjectNodeableRegistry s_MachineLearningPrivateObjectNodeableRegistry;
+
+namespace MachineLearning
+{
+    AZ_COMPONENT_IMPL(MachineLearningSystemComponent, "MachineLearningSystemComponent", MachineLearningSystemComponentTypeId);
+
+    void MachineLearningSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<MachineLearningSystemComponent, AZ::Component>()->Version(0);
+            serializeContext->Class<Layer>()->Version(0);
+            serializeContext->Class<MultilayerPerceptron>()->Version(0);
+        }
+
+        if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
+        {
+            behaviorContext->Class<MachineLearningSystemComponent>();
+            behaviorContext->Class<Layer>();
+            behaviorContext->Class<MultilayerPerceptron>();
+        }
+    }
+
+    void MachineLearningSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("MachineLearningService"));
+    }
+
+    void MachineLearningSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("MachineLearningService"));
+    }
+
+    void MachineLearningSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+    }
+
+    void MachineLearningSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    MachineLearningSystemComponent::MachineLearningSystemComponent()
+    {
+        if (MachineLearningInterface::Get() == nullptr)
+        {
+            MachineLearningInterface::Register(this);
+        }
+    }
+
+    MachineLearningSystemComponent::~MachineLearningSystemComponent()
+    {
+        if (MachineLearningInterface::Get() == this)
+        {
+            MachineLearningInterface::Unregister(this);
+        }
+    }
+
+    void MachineLearningSystemComponent::Init()
+    {
+    }
+
+    void MachineLearningSystemComponent::Activate()
+    {
+        MachineLearningRequestBus::Handler::BusConnect();
+    }
+
+    void MachineLearningSystemComponent::Deactivate()
+    {
+        MachineLearningRequestBus::Handler::BusDisconnect();
+    }
+} // namespace MachineLearning

+ 47 - 0
Gems/MachineLearning/Code/Source/MachineLearningSystemComponent.h

@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <MachineLearning/MachineLearningBus.h>
+
+namespace MachineLearning
+{
+    class MachineLearningSystemComponent
+        : public AZ::Component
+        , protected MachineLearningRequestBus::Handler
+    {
+    public:
+        AZ_COMPONENT_DECL(MachineLearningSystemComponent);
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        MachineLearningSystemComponent();
+        ~MachineLearningSystemComponent();
+
+    protected:
+        ////////////////////////////////////////////////////////////////////////
+        // MachineLearningRequestBus interface implementation
+
+        ////////////////////////////////////////////////////////////////////////
+
+        ////////////////////////////////////////////////////////////////////////
+        // AZ::Component interface implementation
+        void Init() override;
+        void Activate() override;
+        void Deactivate() override;
+        ////////////////////////////////////////////////////////////////////////
+    };
+
+} // namespace MachineLearning

+ 74 - 0
Gems/MachineLearning/Code/Source/Models/Layer.cpp

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Models/MultilayerPerceptron.h>
+#include <AzCore/RTTI/RTTI.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/SerializeContext.h>
+
+namespace MachineLearning
+{
+    void Layer::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<Layer>()
+                ->Version(1)
+                ->Field("InputSize", &Layer::m_inputSize)
+                ->Field("OutputSize", &Layer::m_outputSize)
+                ->Field("Weights", &Layer::m_weights)
+                ->Field("Biases", &Layer::m_biases)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<Layer>("A single layer of a neural network", "")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &Layer::m_inputSize, "Input Size", "This value must match the output size of the previous layer, or the number of neurons in the activation layer if this is the first layer")
+                    ->Attribute(AZ::Edit::Attributes::ChangeNotify, &Layer::OnSizesChanged)
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &Layer::m_outputSize, "Output Size", "This value must match the input size of the next layer, if one exists")
+                    ->Attribute(AZ::Edit::Attributes::ChangeNotify, &Layer::OnSizesChanged)
+                    ;
+            }
+        }
+
+        auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
+        if (behaviorContext)
+        {
+            behaviorContext->Class<Layer>()->
+                Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)->
+                Attribute(AZ::Script::Attributes::Module, "machineLearning")->
+                Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)->
+                Constructor<AZStd::size_t, AZStd::size_t>()->
+                Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
+                ;
+        }
+    }
+
+    Layer::Layer(AZStd::size_t activationDimensionality, AZStd::size_t layerDimensionality)
+        : m_inputSize(activationDimensionality)
+        , m_outputSize(layerDimensionality)
+    {
+        OnSizesChanged();
+    }
+
+    const AZ::VectorN& Layer::ActivateLayer(const AZ::VectorN& activations)
+    {
+        m_output = m_biases;
+        AZ::VectorMatrixMultiply(m_weights, activations, m_output);
+        return m_output;
+    }
+
+    void Layer::OnSizesChanged()
+    {
+        m_weights = AZ::MatrixMxN::CreateRandom(m_outputSize, m_inputSize);
+        m_biases = AZ::VectorN::CreateRandom(m_outputSize);
+        m_output = AZ::VectorN::CreateZero(m_outputSize);
+    }
+}

+ 40 - 0
Gems/MachineLearning/Code/Source/Models/Layer.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Math/MatrixMxN.h>
+#include <MachineLearning/INeuralNetwork.h>
+
+namespace MachineLearning
+{
+    //! A class representing a single layer within a neural network.
+    class Layer
+    {
+    public:
+
+        AZ_TYPE_INFO(Layer, "{FB91E0A7-86C0-4431-83A8-04F8D8E1C9E2}");
+
+        //! AzCore Reflection.
+        //! @param context reflection context
+        static void Reflect(AZ::ReflectContext* context);
+
+        Layer() = default;
+        Layer(AZStd::size_t activationDimensionality, AZStd::size_t layerDimensionality);
+
+        const AZ::VectorN& ActivateLayer(const AZ::VectorN& activations);
+
+        void OnSizesChanged();
+
+        AZStd::size_t m_inputSize = 0;
+        AZStd::size_t m_outputSize = 0;
+        AZ::MatrixMxN m_weights;
+        AZ::VectorN m_biases;
+        AZ::VectorN m_output;
+    };
+}

+ 135 - 0
Gems/MachineLearning/Code/Source/Models/MultilayerPerceptron.cpp

@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Models/MultilayerPerceptron.h>
+#include <AzCore/RTTI/RTTI.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/SerializeContext.h>
+
+namespace MachineLearning
+{
+    void MultilayerPerceptron::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<MultilayerPerceptron>()
+                ->Version(1)
+                ->Field("ActivationCount", &MultilayerPerceptron::m_activationCount)
+                ->Field("Layers", &MultilayerPerceptron::m_layers)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<MultilayerPerceptron>("A basic multilayer perceptron class", "")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &MultilayerPerceptron::m_activationCount, "Activation Count", "The number of neurons in the activation layer")
+                    ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MultilayerPerceptron::OnActivationCountChanged)
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &MultilayerPerceptron::m_layers, "Layers", "The layers of the neural network")
+                    ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MultilayerPerceptron::OnActivationCountChanged)
+                    ;
+            }
+        }
+
+        auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
+        if (behaviorContext)
+        {
+            behaviorContext->Class<MultilayerPerceptron>()->
+                Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)->
+                Attribute(AZ::Script::Attributes::Module, "machineLearning")->
+                Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)->
+                Constructor<AZStd::size_t>()->
+                Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)->
+                Method("AddLayer", &MultilayerPerceptron::AddLayer)->
+                Method("GetLayerCount", &MultilayerPerceptron::GetLayerCount)->
+                Method("GetLayer", &MultilayerPerceptron::GetLayer)->
+                Method("FeedForward", &MultilayerPerceptron::FeedForward)->
+                Method("ComputeCost", &MultilayerPerceptron::ComputeCost)
+                ;
+        }
+    }
+
+    MultilayerPerceptron::MultilayerPerceptron(AZStd::size_t activationCount)
+        : m_activationCount(activationCount)
+    {
+    }
+
+    void MultilayerPerceptron::AddLayer(AZStd::size_t layerDimensionality)
+    {
+        AZStd::size_t lastLayerDimensionality = m_activationCount;
+        if (!m_layers.empty())
+        {
+            lastLayerDimensionality = m_layers.back().m_biases.GetDimensionality();
+        }
+        m_layers.push_back(AZStd::move(Layer(lastLayerDimensionality, layerDimensionality)));
+    }
+
+    AZStd::size_t MultilayerPerceptron::GetLayerCount() const
+    {
+        return m_layers.size();
+    }
+
+    Layer& MultilayerPerceptron::GetLayer(AZStd::size_t layerIndex)
+    {
+        return m_layers[layerIndex];
+    }
+
+    AZStd::size_t MultilayerPerceptron::GetParameterCount() const
+    {
+        AZStd::size_t parameterCount = 0;
+        for (const Layer& layer : m_layers)
+        {
+            parameterCount += layer.m_inputSize * layer.m_outputSize + layer.m_outputSize;
+        }
+        return parameterCount;
+    }
+
+    const AZ::VectorN& MultilayerPerceptron::FeedForward(const AZ::VectorN& activations)
+    {
+        const AZ::VectorN* lastLayerOutput = &activations;
+        for (Layer& layer : m_layers)
+        {
+            layer.ActivateLayer(*lastLayerOutput);
+            lastLayerOutput = &layer.m_output;
+        }
+        return *lastLayerOutput;
+    }
+
+    float MultilayerPerceptron::ComputeCost(const AZ::VectorN& activations, const AZ::VectorN& expectedOutput, CostFunctions costFunction)
+    {
+        switch (costFunction)
+        {
+        case CostFunctions::Quadratic:
+            return ComputeCost_Quadratic(activations, expectedOutput);
+        }
+        return 0.0f;
+    }
+
+    float MultilayerPerceptron::ComputeCost_Quadratic(const AZ::VectorN& activations, const AZ::VectorN& expectedOutput)
+    {
+        const AZ::VectorN& output = FeedForward(activations);
+        const AZ::VectorN squareDifference = (output - expectedOutput).GetSquare();
+        float summedCost = 0;
+        for (AZStd::size_t iter = 0; iter < squareDifference.GetDimensionality(); ++iter)
+        {
+            summedCost += squareDifference.GetElement(iter);
+        }
+        return summedCost;
+    }
+
+    void MultilayerPerceptron::OnActivationCountChanged()
+    {
+        AZStd::size_t lastLayerDimensionality = m_activationCount;
+        for (Layer& layer : m_layers)
+        {
+            layer.m_inputSize = lastLayerDimensionality;
+            layer.OnSizesChanged();
+            lastLayerDimensionality = layer.m_outputSize;
+        }
+    }
+}

+ 52 - 0
Gems/MachineLearning/Code/Source/Models/MultilayerPerceptron.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Math/MatrixMxN.h>
+#include <MachineLearning/INeuralNetwork.h>
+#include <Models/Layer.h>
+
+namespace MachineLearning
+{
+    //! This is a basic multilayer perceptron neural network capable of basic training and feed forward operations.
+    class MultilayerPerceptron
+        : public INeuralNetwork
+    {
+    public:
+
+        AZ_TYPE_INFO(MultilayerPerceptron, "{E12EF761-41A5-48C3-BF55-7179B280D45F}");
+
+        //! AzCore Reflection.
+        //! @param context reflection context
+        static void Reflect(AZ::ReflectContext* context);
+
+        MultilayerPerceptron() = default;
+        MultilayerPerceptron(AZStd::size_t activationCount);
+        virtual ~MultilayerPerceptron() = default;
+
+        void AddLayer(AZStd::size_t layerDimensionality);
+        AZStd::size_t GetLayerCount() const;
+        Layer& GetLayer(AZStd::size_t layerIndex);
+
+        AZStd::size_t GetParameterCount() const override;
+        const AZ::VectorN& FeedForward(const AZ::VectorN& activations) override;
+        float ComputeCost(const AZ::VectorN& activations, const AZ::VectorN& expectedOutput, CostFunctions costFunction) override;
+
+    private:
+
+        void OnActivationCountChanged();
+        float ComputeCost_Quadratic(const AZ::VectorN& activations, const AZ::VectorN& expectedOutput);
+
+        //! The number of neurons in the activation layer.
+        AZStd::size_t m_activationCount = 0;
+
+        //! The set of layers in the network.
+        AZStd::vector<Layer> m_layers;
+    };
+}

+ 17 - 0
Gems/MachineLearning/Code/Source/Nodes/ComputeCost.ScriptCanvasNodeable.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScriptCanvas Include="Nodes/ComputeCost.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Class Name="ComputeCost"
+           QualifiedName="MachineLearning::ComputeCost"
+           PreferredClassName="Compute cost gradient"
+           Category="MachineLearning"
+           Description="Calculates the cost gradient for a machine learning model against a set of activations and a set of expected outputs.">
+
+        <Input Name="In" DisplayGroup="In" Description="Parameters controlling cost gradient calculation">
+            <Parameter Name="Model" Type="MachineLearning::INeuralNetworkPtr" Description="The model to compute the cost gradient for."/>
+            <Parameter Name="Activations" Type="AZ::VectorN" Description="The set of activation values to apply to the model (must match the models input count)."/>
+            <Parameter Name="ExpectedOutput" Type="AZ::VectorN" Description="The expected outputs given the provided inputs (must match the models output count)."/>
+            <Return Name="Cost" Type="float" Shared="true"/>
+        </Input>
+    </Class>
+</ScriptCanvas>

+ 18 - 0
Gems/MachineLearning/Code/Source/Nodes/ComputeCost.cpp

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Nodes/ComputeCost.h>
+#include <Models/MultilayerPerceptron.h>
+
+namespace MachineLearning
+{
+    float ComputeCost::In(MachineLearning::INeuralNetworkPtr Model, AZ::VectorN Activations, AZ::VectorN ExpectedOutput)
+    {
+        return Model->ComputeCost(Activations, ExpectedOutput, CostFunctions::Quadratic);
+    }
+}

+ 24 - 0
Gems/MachineLearning/Code/Source/Nodes/ComputeCost.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
+#include <ScriptCanvas/Core/Nodeable.h>
+#include <ScriptCanvas/Core/NodeableNode.h>
+#include <MachineLearning/INeuralNetwork.h>
+#include <Source/Nodes/ComputeCost.generated.h>
+
+namespace MachineLearning
+{
+    class ComputeCost
+        : public ScriptCanvas::Nodeable
+    {
+        SCRIPTCANVAS_NODE_ComputeCost;
+    };
+}

+ 17 - 0
Gems/MachineLearning/Code/Source/Nodes/CreateModel.ScriptCanvasNodeable.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScriptCanvas Include="Nodes/CreateModel.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Class Name="CreateModel"
+           QualifiedName="MachineLearning::CreateModel"
+           PreferredClassName="Creates a new machine learning model"
+           Category="MachineLearning"
+           Description="Creates a new untrained machine learning model. All parameters will be initialized to random values.">
+
+        <Input Name="In" DisplayGroup="In" Description="Parameters controlling the new model">
+            <Parameter Name="Input neurons" Type="AZStd::size_t" Description="The number of input neurons for the model to have."/>
+            <Parameter Name="Output neurons" Type="AZStd::size_t" Description="The number of output neurons for the model to have."/>
+            <Parameter Name="Hidden layers" Type="MachineLearning::HiddenLayerParams" Description="The array of hidden layers to generate."/>
+            <Return Name="Model" Type="MachineLearning::INeuralNetworkPtr" Shared="true"/>
+        </Input>
+    </Class>
+</ScriptCanvas>

+ 25 - 0
Gems/MachineLearning/Code/Source/Nodes/CreateModel.cpp

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Nodes/CreateModel.h>
+#include <Models/MultilayerPerceptron.h>
+
+namespace MachineLearning
+{
+    INeuralNetworkPtr CreateModel::In(AZStd::size_t Inputneurons, AZStd::size_t Outputneurons, MachineLearning::HiddenLayerParams Hiddenlayers)
+    {
+        INeuralNetworkPtr result = AZStd::make_unique<MultilayerPerceptron>(Inputneurons);
+        MultilayerPerceptron* modelPtr = static_cast<MultilayerPerceptron*>(result.get());
+        for (AZStd::size_t layerSize : Hiddenlayers)
+        {
+            modelPtr->AddLayer(layerSize);
+        }
+        modelPtr->AddLayer(Outputneurons);
+        return result;
+    }
+}

+ 24 - 0
Gems/MachineLearning/Code/Source/Nodes/CreateModel.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
+#include <ScriptCanvas/Core/Nodeable.h>
+#include <ScriptCanvas/Core/NodeableNode.h>
+#include <MachineLearning/INeuralNetwork.h>
+#include <Source/Nodes/CreateModel.generated.h>
+
+namespace MachineLearning
+{
+    class CreateModel
+        : public ScriptCanvas::Nodeable
+    {
+        SCRIPTCANVAS_NODE_CreateModel;
+    };
+}

+ 16 - 0
Gems/MachineLearning/Code/Source/Nodes/FeedForward.ScriptCanvasNodeable.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ScriptCanvas Include="Nodes/FeedForward.h" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Class Name="FeedForward"
+           QualifiedName="MachineLearning::FeedForward"
+           PreferredClassName="Feed forward"
+           Category="MachineLearning"
+           Description="Performs a feed-forward operation on the model to obtain a set of outputs given an input.">
+
+        <Input Name="In" DisplayGroup="In" Description="Parameters controlling the feed forward operation">
+            <Parameter Name="Model" Type="MachineLearning::INeuralNetworkPtr" Description="The model to compute the cost gradient for."/>
+            <Parameter Name="Activations" Type="AZ::VectorN" Description="The set of activation values to apply to the model (must match the models input count)."/>
+            <Return Name="Output" Type="AZ::VectorN" Shared="true"/>
+        </Input>
+    </Class>
+</ScriptCanvas>

+ 19 - 0
Gems/MachineLearning/Code/Source/Nodes/FeedForward.cpp

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <Nodes/FeedForward.h>
+#include <Models/MultilayerPerceptron.h>
+
+namespace MachineLearning
+{
+    AZ::VectorN FeedForward::In(MachineLearning::INeuralNetworkPtr Model, AZ::VectorN Activations)
+    {
+        AZ::VectorN results = Model->FeedForward(Activations);
+        return results;
+    }
+}

+ 24 - 0
Gems/MachineLearning/Code/Source/Nodes/FeedForward.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
+#include <ScriptCanvas/Core/Nodeable.h>
+#include <ScriptCanvas/Core/NodeableNode.h>
+#include <MachineLearning/INeuralNetwork.h>
+#include <Source/Nodes/FeedForward.generated.h>
+
+namespace MachineLearning
+{
+    class FeedForward
+        : public ScriptCanvas::Nodeable
+    {
+        SCRIPTCANVAS_NODE_FeedForward;
+    };
+}

+ 39 - 0
Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorModule.cpp

@@ -0,0 +1,39 @@
+
+#include <MachineLearning/MachineLearningTypeIds.h>
+#include <MachineLearningModuleInterface.h>
+#include "MachineLearningEditorSystemComponent.h"
+
+namespace MachineLearning
+{
+    class MachineLearningEditorModule
+        : public MachineLearningModuleInterface
+    {
+    public:
+        AZ_RTTI(MachineLearningEditorModule, MachineLearningEditorModuleTypeId, MachineLearningModuleInterface);
+        AZ_CLASS_ALLOCATOR(MachineLearningEditorModule, AZ::SystemAllocator);
+
+        MachineLearningEditorModule()
+        {
+            // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+            // Add ALL components descriptors associated with this gem to m_descriptors.
+            // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and EditContext.
+            // This happens through the [MyComponent]::Reflect() function.
+            m_descriptors.insert(m_descriptors.end(), {
+                MachineLearningEditorSystemComponent::CreateDescriptor(),
+            });
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         * Non-SystemComponents should not be added here
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList {
+                azrtti_typeid<MachineLearningEditorSystemComponent>(),
+            };
+        }
+    };
+}// namespace MachineLearning
+
+AZ_DECLARE_MODULE_CLASS(Gem_MachineLearning, MachineLearning::MachineLearningEditorModule)

+ 59 - 0
Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorSystemComponent.cpp

@@ -0,0 +1,59 @@
+
+#include <AzCore/Serialization/SerializeContext.h>
+#include "MachineLearningEditorSystemComponent.h"
+
+#include <MachineLearning/MachineLearningTypeIds.h>
+
+namespace MachineLearning
+{
+    AZ_COMPONENT_IMPL(MachineLearningEditorSystemComponent, "MachineLearningEditorSystemComponent",
+        MachineLearningEditorSystemComponentTypeId, BaseSystemComponent);
+
+    void MachineLearningEditorSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<MachineLearningEditorSystemComponent, MachineLearningSystemComponent>()
+                ->Version(0);
+        }
+    }
+
+    MachineLearningEditorSystemComponent::MachineLearningEditorSystemComponent() = default;
+
+    MachineLearningEditorSystemComponent::~MachineLearningEditorSystemComponent() = default;
+
+    void MachineLearningEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        BaseSystemComponent::GetProvidedServices(provided);
+        provided.push_back(AZ_CRC_CE("MachineLearningEditorService"));
+    }
+
+    void MachineLearningEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        BaseSystemComponent::GetIncompatibleServices(incompatible);
+        incompatible.push_back(AZ_CRC_CE("MachineLearningEditorService"));
+    }
+
+    void MachineLearningEditorSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        BaseSystemComponent::GetRequiredServices(required);
+    }
+
+    void MachineLearningEditorSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+        BaseSystemComponent::GetDependentServices(dependent);
+    }
+
+    void MachineLearningEditorSystemComponent::Activate()
+    {
+        MachineLearningSystemComponent::Activate();
+        AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
+    }
+
+    void MachineLearningEditorSystemComponent::Deactivate()
+    {
+        AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
+        MachineLearningSystemComponent::Deactivate();
+    }
+
+} // namespace MachineLearning

+ 34 - 0
Gems/MachineLearning/Code/Source/Tools/MachineLearningEditorSystemComponent.h

@@ -0,0 +1,34 @@
+
+#pragma once
+
+#include <AzToolsFramework/API/ToolsApplicationAPI.h>
+
+#include <MachineLearningSystemComponent.h>
+
+namespace MachineLearning
+{
+    /// System component for MachineLearning editor
+    class MachineLearningEditorSystemComponent
+        : public MachineLearningSystemComponent
+        , protected AzToolsFramework::EditorEvents::Bus::Handler
+    {
+        using BaseSystemComponent = MachineLearningSystemComponent;
+    public:
+        AZ_COMPONENT_DECL(MachineLearningEditorSystemComponent);
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        MachineLearningEditorSystemComponent();
+        ~MachineLearningEditorSystemComponent();
+
+    private:
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        // AZ::Component
+        void Activate() override;
+        void Deactivate() override;
+    };
+} // namespace MachineLearning

+ 11 - 0
Gems/MachineLearning/Code/Tests/MachineLearningTests.cpp

@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzTest/AzTest.h>
+
+AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);

+ 31 - 0
Gems/MachineLearning/Code/Tests/Models/LayerTests.cpp

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzTest/AzTest.h>
+#include <AzCore/UnitTest/TestTypes.h>
+#include <Models/Layer.h>
+
+namespace UnitTest
+{
+    class MachineLearning_Layers
+        : public UnitTest::LeakDetectionFixture
+    {
+    };
+
+    TEST_F(MachineLearning_Layers, TestConstructor)
+    {
+        // Construct a layer that takes 8 inputs and generates 4 outputs
+        MachineLearning::Layer testLayer(8, 4);
+        EXPECT_EQ(testLayer.m_inputSize, 8);
+        EXPECT_EQ(testLayer.m_outputSize, 4);
+        EXPECT_EQ(testLayer.m_weights.GetColumnCount(), 8);
+        EXPECT_EQ(testLayer.m_weights.GetRowCount(), 4);
+        EXPECT_EQ(testLayer.m_biases.GetDimensionality(), 4);
+        EXPECT_EQ(testLayer.m_output.GetDimensionality(), 4);
+    }
+}

+ 14 - 0
Gems/MachineLearning/Code/Tests/Models/MultilayerPerceptronTests.cpp

@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzTest/AzTest.h>
+#include <Models/MultilayerPerceptron.h>
+
+namespace UnitTest
+{
+}

+ 4 - 0
Gems/MachineLearning/Code/Tests/Tools/MachineLearningEditorTest.cpp

@@ -0,0 +1,4 @@
+
+#include <AzTest/AzTest.h>
+
+AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);

+ 13 - 0
Gems/MachineLearning/Code/machinelearning_api_files.cmake

@@ -0,0 +1,13 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Include/MachineLearning/INeuralNetwork.h
+    Include/MachineLearning/MachineLearningBus.h
+    Include/MachineLearning/MachineLearningTypeIds.h
+)

+ 10 - 0
Gems/MachineLearning/Code/machinelearning_editor_api_files.cmake

@@ -0,0 +1,10 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+)

+ 12 - 0
Gems/MachineLearning/Code/machinelearning_editor_private_files.cmake

@@ -0,0 +1,12 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/Tools/MachineLearningEditorSystemComponent.cpp
+    Source/Tools/MachineLearningEditorSystemComponent.h
+)

+ 11 - 0
Gems/MachineLearning/Code/machinelearning_editor_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/Tools/MachineLearningEditorModule.cpp
+)

+ 4 - 0
Gems/MachineLearning/Code/machinelearning_editor_tests_files.cmake

@@ -0,0 +1,4 @@
+
+set(FILES
+    Tests/Tools/MachineLearningEditorTest.cpp
+)

+ 27 - 0
Gems/MachineLearning/Code/machinelearning_private_files.cmake

@@ -0,0 +1,27 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/MachineLearningModuleInterface.cpp
+    Source/MachineLearningModuleInterface.h
+    Source/MachineLearningSystemComponent.cpp
+    Source/MachineLearningSystemComponent.h
+	Source/Models/Layer.cpp
+	Source/Models/Layer.h
+	Source/Models/MultilayerPerceptron.cpp
+	Source/Models/MultilayerPerceptron.h
+    Source/Nodes/ComputeCost.ScriptCanvasNodeable.xml
+    Source/Nodes/ComputeCost.cpp
+    Source/Nodes/ComputeCost.h
+    Source/Nodes/CreateModel.ScriptCanvasNodeable.xml
+    Source/Nodes/CreateModel.cpp
+    Source/Nodes/CreateModel.h
+    Source/Nodes/FeedForward.ScriptCanvasNodeable.xml
+    Source/Nodes/FeedForward.cpp
+    Source/Nodes/FeedForward.h
+)

+ 11 - 0
Gems/MachineLearning/Code/machinelearning_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/MachineLearningModule.cpp
+)

+ 13 - 0
Gems/MachineLearning/Code/machinelearning_tests_files.cmake

@@ -0,0 +1,13 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Tests/Models/LayerTests.cpp
+    Tests/Models/MultilayerPerceptronTests.cpp
+    Tests/MachineLearningTests.cpp
+)

+ 16 - 0
Gems/MachineLearning/Code/scriptcanvas_autogen_files.cmake

@@ -0,0 +1,16 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+get_property(scriptcanvas_gem_root GLOBAL PROPERTY "@GEMROOT:ScriptCanvas@")
+
+set(FILES
+    ${scriptcanvas_gem_root}/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja
+    ${scriptcanvas_gem_root}/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja
+    ${scriptcanvas_gem_root}/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeableRegistry_Header.jinja
+    ${scriptcanvas_gem_root}/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeableRegistry_Source.jinja
+)

+ 18 - 0
Gems/MachineLearning/Registry/assetprocessor_settings.setreg

@@ -0,0 +1,18 @@
+{
+    "Amazon": {
+        "AssetProcessor": {
+            "Settings": {
+                "ScanFolder MachineLearning/Assets": {
+                    "watch": "@GEMROOT:MachineLearning@/Assets",
+                    "recursive": 1,
+                    "order": 101
+                },
+                "ScanFolder MachineLearning/Registry": {
+                    "watch": "@GEMROOT:MachineLearning@/Registry",
+                    "recursive": 1,
+                    "order": 102
+                }
+            }
+        }
+    }
+}

+ 28 - 0
Gems/MachineLearning/gem.json

@@ -0,0 +1,28 @@
+{
+    "gem_name": "MachineLearning",
+    "version": "1.0.0",
+    "display_name": "MachineLearning",
+    "license": "License used i.e. Apache-2.0 or MIT",
+    "license_url": "Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0",
+    "origin": "The name of the originator or creator",
+    "origin_url": "The website for this Gem",
+    "type": "Code",
+    "summary": "A short description of this Gem",
+    "canonical_tags": [
+        "Gem"
+    ],
+    "user_tags": [
+        "MachineLearning"
+    ],
+    "platforms": [
+        ""
+    ],
+    "icon_path": "preview.png",
+    "requirements": "Notice of any requirements for this Gem i.e. This requires X other gem",
+    "documentation_url": "Link to any documentation of your Gem",
+    "dependencies": [],
+    "repo_uri": "",
+    "compatible_engines": [],
+    "engine_api_dependencies": [],
+    "restricted": "MachineLearning"
+}

+ 3 - 0
Gems/MachineLearning/preview.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:248e3ffe1fc9ffc02afb2ba8914e222a5a5d13ac45a48b98c95ee062e959a94c
+size 4475