├── .gitattributes ├── .gitignore ├── .travis.yml ├── .vscode ├── launch.json └── tasks.json ├── ExampleProjects └── FraudDetection │ ├── .vscode │ ├── launch.json │ └── tasks.json │ ├── NeuralNetworks.Examples.FraudDetection.Services │ ├── Application │ │ ├── NeuralNetworkPredictionService.cs │ │ └── NeuralNetworkTrainingService.cs │ ├── Configuration │ │ ├── DataSourceConfiguration.cs │ │ └── NeuralNetworkTrainingConfiguration.cs │ ├── Domain │ │ ├── BankTransaction.cs │ │ ├── BankTransactionExtensions.cs │ │ ├── BankTransactionNormaliser.cs │ │ ├── CsvFileReader.cs │ │ ├── DataProvider.cs │ │ ├── NeuralNetworkAccessor.cs │ │ └── NeuralNetworkPredictionReport.cs │ ├── NeuralNetworks.Examples.FraudDetection.Services.csproj │ └── ServiceLayerConfiguration.cs │ ├── NeuralNetworks.Examples.FraudDetection.Web │ ├── .bowerrc │ ├── Extensions │ │ └── IServiceCollectionExtensions.cs │ ├── Models │ │ └── PredictionsReport.cs │ ├── NeuralNetworks.Examples.FraudDetection.Web.csproj │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ ├── Index.cshtml │ │ ├── Index.cshtml.cs │ │ ├── PerformPredictions.cshtml │ │ ├── PerformPredictions.cshtml.cs │ │ ├── PerformTraining.cshtml │ │ ├── PerformTraining.cshtml.cs │ │ ├── _Layout.cshtml │ │ ├── _ValidationScriptsPartial.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── Program.cs │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── bower.json │ ├── bundleconfig.json │ └── wwwroot │ │ ├── css │ │ ├── site.css │ │ └── site.min.css │ │ ├── favicon.ico │ │ ├── images │ │ ├── banner1.svg │ │ ├── banner2.svg │ │ ├── banner3.svg │ │ └── banner4.svg │ │ ├── js │ │ ├── site.js │ │ └── site.min.js │ │ └── lib │ │ ├── bootstrap │ │ ├── .bower.json │ │ ├── LICENSE │ │ └── dist │ │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ └── bootstrap.min.css.map │ │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ └── js │ │ │ ├── bootstrap.js │ │ │ └── npm.js │ │ ├── jquery-validation-unobtrusive │ │ ├── .bower.json │ │ ├── jquery.validate.unobtrusive.js │ │ └── jquery.validate.unobtrusive.min.js │ │ ├── jquery-validation │ │ ├── .bower.json │ │ ├── LICENSE.md │ │ └── dist │ │ │ ├── additional-methods.js │ │ │ └── jquery.validate.js │ │ └── jquery │ │ ├── .bower.json │ │ ├── LICENSE.txt │ │ └── dist │ │ ├── jquery.js │ │ └── jquery.min.map │ ├── NeuralNetworks.Examples.FraudDetection.sln │ └── README.md ├── NeuralNetworks.Console ├── NeuralNetworks.Console.csproj └── Program.cs ├── NeuralNetworks.Library ├── Components │ ├── Activation │ │ ├── ActivationType.cs │ │ ├── ActivationTypeExtensions.cs │ │ └── Functions │ │ │ ├── IProvideNeuronActivation.cs │ │ │ ├── SigmoidActivationFunction.cs │ │ │ └── TanHActivationFunction.cs │ ├── BiasNeuron.cs │ ├── Layer.cs │ ├── Neuron.cs │ └── Synapse.cs ├── Data │ └── TrainingDataSet.cs ├── Extensions │ ├── DoubleExtensions.cs │ ├── EnumerableExtensions.cs │ ├── ParallelOptionsExtensions.cs │ └── TrainingDataSetExtensions.cs ├── Logging │ ├── LoggerProvider.cs │ └── LoggingHelperExtensions.cs ├── NetworkInitialisation │ ├── IProvideRandomNumberGeneration.cs │ └── RandomNumberProvider.cs ├── NeuralNetwork.cs ├── NeuralNetworkBuilder.cs ├── NeuralNetworkContext.cs ├── NeuralNetworks.Library.csproj ├── Properties │ └── AssemblyInfo.cs ├── Training │ ├── BackPropagation │ │ ├── BackPropagation.cs │ │ ├── NeuronErrorGradientCalculator.cs │ │ └── SynapseWeightCalculator.cs │ ├── ITrainNeuralNetworks.cs │ ├── NeuralNetworkTrainer.cs │ └── TrainingController.cs └── Validation │ └── NullableValidators.cs ├── NeuralNetworks.Tests.IntegrationTests ├── Assertors │ └── AssertorPatternTest.cs ├── DatasetCaseStudies │ ├── IrisDataSetCaseStudy │ │ ├── IrisDataRow.cs │ │ ├── IrisDataRowNormaliser.cs │ │ ├── IrisDataSet.cs │ │ └── IrisDataSetCaseStudy.cs │ └── XorDatasetCaseStudy │ │ └── XorDatasetCaseStudy.cs ├── NetworkPredictions │ ├── NeuralNetworkFeedForwardTests.cs │ └── NeuralNetworkPredictionsTester.cs ├── NeuralNetworks.Tests.IntegrationTests.csproj └── Training │ └── BackPropagationTests │ ├── BackPropagationIntegrationTests.cs │ ├── BackPropagationTester.cs │ ├── ErrorRateCalculationTests │ ├── BackPropagationErrorRateCalculationTests.cs │ └── BackPropagationErrorRateTester.cs │ ├── SynapseWeightUpdateTests │ ├── BackPropagationSynapseWeightUpdateTester.cs │ ├── BackPropagationSynapseWeightUpdateTests.cs │ ├── BackPropagationSynapseWeightUpdateWithLearningRateTests.cs │ ├── BackPropagationSynapseWeightUpdateWithMomentumTests.cs │ └── BackPropagationSynapseWeightUpdateWithNoOptimisationTests.cs │ └── TrainingEpochTester.cs ├── NeuralNetworks.Tests.PerformanceTests ├── BackPropagationPerformanceTestContainer.cs ├── FeedForwardPerformanceTestContainer.cs ├── NeuralNetworks.Tests.PerformanceTests.csproj ├── Program.cs └── README.md ├── NeuralNetworks.Tests.Support ├── Assertors │ ├── EqualityAssertor.cs │ ├── FieldAssertor.cs │ ├── IAssert.cs │ ├── LayerAssertor.cs │ ├── NeuralNetworkAssertor.cs │ ├── NeuronAssertor.cs │ ├── OrderedListAssertor.cs │ ├── RoundedDoubleAssertor.cs │ ├── SynapseAssertor.cs │ └── UnorderedListAssertor.cs ├── Builders │ ├── ExplicitNeuralNetworkBuilder.cs │ ├── LayerBuilder.cs │ ├── NeuronBuilder.cs │ └── SynapseBuilder.cs ├── Helpers │ └── DoubleAssertionHelpers.cs ├── NeuralNetworkTest.cs ├── NeuralNetworkTester.cs ├── NeuralNetworks.Tests.Support.csproj └── PredictableRandomNumberGenerator.cs ├── NeuralNetworks.Tests.UnitTests ├── ActivationFunctionTests │ ├── SigmoidActivationFunctionTests.cs │ └── TanHActivationFunctionTests.cs └── NeuralNetworks.Tests.UnitTests.csproj ├── NeuralNetworks.sln └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | *.DS_Store 13 | 14 | # Build results 15 | [Dd]ebug/ 16 | [Dd]ebugPublic/ 17 | [Rr]elease/ 18 | [Rr]eleases/ 19 | x64/ 20 | x86/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | [Ll]og/ 25 | BenchmarkDotNet.Artifacts/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opendb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | *.VC.db 87 | *.VC.VC.opendb 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | *.sap 94 | 95 | # TFS 2012 Local Workspace 96 | $tf/ 97 | 98 | # Guidance Automation Toolkit 99 | *.gpState 100 | 101 | # ReSharper is a .NET coding add-in 102 | _ReSharper*/ 103 | *.[Rr]e[Ss]harper 104 | *.DotSettings.user 105 | 106 | # JustCode is a .NET coding add-in 107 | .JustCode 108 | 109 | # TeamCity is a build add-in 110 | _TeamCity* 111 | 112 | # DotCover is a Code Coverage Tool 113 | *.dotCover 114 | 115 | # NCrunch 116 | _NCrunch_* 117 | .*crunch*.local.xml 118 | nCrunchTemp_* 119 | 120 | # MightyMoose 121 | *.mm.* 122 | AutoTest.Net/ 123 | 124 | # Web workbench (sass) 125 | .sass-cache/ 126 | 127 | # Installshield output folder 128 | [Ee]xpress/ 129 | 130 | # DocProject is a documentation generator add-in 131 | DocProject/buildhelp/ 132 | DocProject/Help/*.HxT 133 | DocProject/Help/*.HxC 134 | DocProject/Help/*.hhc 135 | DocProject/Help/*.hhk 136 | DocProject/Help/*.hhp 137 | DocProject/Help/Html2 138 | DocProject/Help/html 139 | 140 | # Click-Once directory 141 | publish/ 142 | 143 | # Publish Web Output 144 | *.[Pp]ublish.xml 145 | *.azurePubxml 146 | # TODO: Comment the next line if you want to checkin your web deploy settings 147 | # but database connection strings (with potential passwords) will be unencrypted 148 | #*.pubxml 149 | *.publishproj 150 | 151 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 152 | # checkin your Azure Web App publish settings, but sensitive information contained 153 | # in these scripts will be unencrypted 154 | PublishScripts/ 155 | 156 | # NuGet Packages 157 | *.nupkg 158 | # The packages folder can be ignored because of Package Restore 159 | **/packages/* 160 | # except build/, which is used as an MSBuild target. 161 | !**/packages/build/ 162 | # Uncomment if necessary however generally it will be regenerated when needed 163 | #!**/packages/repositories.config 164 | # NuGet v3's project.json files produces more ignoreable files 165 | *.nuget.props 166 | *.nuget.targets 167 | 168 | # Microsoft Azure Build Output 169 | csx/ 170 | *.build.csdef 171 | 172 | # Microsoft Azure Emulator 173 | ecf/ 174 | rcf/ 175 | 176 | # Windows Store app package directories and files 177 | AppPackages/ 178 | BundleArtifacts/ 179 | Package.StoreAssociation.xml 180 | _pkginfo.txt 181 | 182 | # Visual Studio cache files 183 | # files ending in .cache can be ignored 184 | *.[Cc]ache 185 | # but keep track of directories ending in .cache 186 | !*.[Cc]ache/ 187 | 188 | # Others 189 | ClientBin/ 190 | ~$* 191 | *~ 192 | *.dbmdl 193 | *.dbproj.schemaview 194 | *.jfm 195 | *.pfx 196 | *.publishsettings 197 | node_modules/ 198 | orleans.codegen.cs 199 | 200 | # Since there are multiple workflows, uncomment next line to ignore bower_components 201 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 202 | #bower_components/ 203 | 204 | # RIA/Silverlight projects 205 | Generated_Code/ 206 | 207 | # Backup & report files from converting an old project file 208 | # to a newer Visual Studio version. Backup files are not needed, 209 | # because we have git ;-) 210 | _UpgradeReport_Files/ 211 | Backup*/ 212 | UpgradeLog*.XML 213 | UpgradeLog*.htm 214 | 215 | # SQL Server files 216 | *.mdf 217 | *.ldf 218 | 219 | # Business Intelligence projects 220 | *.rdl.data 221 | *.bim.layout 222 | *.bim_*.settings 223 | 224 | # Microsoft Fakes 225 | FakesAssemblies/ 226 | 227 | # GhostDoc plugin setting file 228 | *.GhostDoc.xml 229 | 230 | # Node.js Tools for Visual Studio 231 | .ntvs_analysis.dat 232 | 233 | # Visual Studio 6 build log 234 | *.plg 235 | 236 | # Visual Studio 6 workspace options file 237 | *.opt 238 | 239 | # Visual Studio LightSwitch build output 240 | **/*.HTMLClient/GeneratedArtifacts 241 | **/*.DesktopClient/GeneratedArtifacts 242 | **/*.DesktopClient/ModelManifest.xml 243 | **/*.Server/GeneratedArtifacts 244 | **/*.Server/ModelManifest.xml 245 | _Pvt_Extensions 246 | 247 | # Paket dependency manager 248 | .paket/paket.exe 249 | paket-files/ 250 | 251 | # FAKE - F# Make 252 | .fake/ 253 | 254 | # JetBrains Rider 255 | .idea/ 256 | *.sln.iml 257 | 258 | # CodeRush 259 | .cr/ 260 | 261 | # Python Tools for Visual Studio (PTVS) 262 | __pycache__/ 263 | *.pyc -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | mono: none 3 | dotnet: 2.0.0 4 | dist: trusty 5 | script: 6 | - dotnet restore 7 | - dotnet build -c Release 8 | - dotnet test ./NeuralNetworks.Tests.UnitTests/NeuralNetworks.Tests.UnitTests.csproj -c Release 9 | - dotnet test ./NeuralNetworks.Tests.IntegrationTests/NeuralNetworks.Tests.IntegrationTests.csproj -c Release -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch (console)", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "build", 9 | "program": "${workspaceRoot}/NeuralNetworks.Console/bin/Debug/netcoreapp1.1/NeuralNetworks.Console.dll", 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "stopAtEntry": false, 13 | "console": "internalConsole" 14 | }, 15 | { 16 | "name": ".NET Core Attach", 17 | "type": "coreclr", 18 | "request": "attach", 19 | "processId": "${command:pickProcess}" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "dotnet", 4 | "isShellCommand": true, 5 | "args": [], 6 | "options": { 7 | "cwd": "${workspaceRoot}/NeuralNetworks.Console/" 8 | }, 9 | "tasks": [ 10 | { 11 | "taskName": "build", 12 | "args": [ ], 13 | "isBuildCommand": true, 14 | "problemMatcher": "$msCompile" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceRoot}/NeuralNetworks.Examples.FraudDetection.Web/bin/Debug/netcoreapp2.0/NeuralNetworks.Examples.FraudDetection.Web.dll", 14 | "args": [], 15 | "cwd": "${workspaceRoot}/NeuralNetworks.Examples.FraudDetection.Web", 16 | "stopAtEntry": false, 17 | "internalConsoleOptions": "openOnSessionStart", 18 | "launchBrowser": { 19 | "enabled": true, 20 | "args": "${auto-detect-url}", 21 | "windows": { 22 | "command": "cmd.exe", 23 | "args": "/C start ${auto-detect-url}" 24 | }, 25 | "osx": { 26 | "command": "open" 27 | }, 28 | "linux": { 29 | "command": "xdg-open" 30 | } 31 | }, 32 | "env": { 33 | "ASPNETCORE_ENVIRONMENT": "Development" 34 | }, 35 | "sourceFileMap": { 36 | "/Views": "${workspaceRoot}/Views" 37 | } 38 | }, 39 | { 40 | "name": ".NET Core Attach", 41 | "type": "coreclr", 42 | "request": "attach", 43 | "processId": "${command:pickProcess}" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "dotnet", 4 | "isShellCommand": true, 5 | "args": [], 6 | "tasks": [ 7 | { 8 | "taskName": "build", 9 | "args": [ 10 | "${workspaceRoot}/NeuralNetworks.Examples.FraudDetection.Web/NeuralNetworks.Examples.FraudDetection.Web.csproj" 11 | ], 12 | "isBuildCommand": true, 13 | "problemMatcher": "$msCompile" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Application/NeuralNetworkPredictionService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using Microsoft.Extensions.Logging; 5 | using NeuralNetworks.Examples.FraudDetection.Services.Domain; 6 | using NeuralNetworks.Library.Extensions; 7 | 8 | namespace NeuralNetworks.Examples.FraudDetection.Services.Application 9 | { 10 | public sealed class NeuralNetworkPredictionService 11 | { 12 | private readonly ILogger logger; 13 | private readonly NeuralNetworkAccessor networkAccessor; 14 | private readonly DataProvider dataProvider; 15 | 16 | public NeuralNetworkPredictionService( 17 | ILogger logger, 18 | NeuralNetworkAccessor networkAccessor, 19 | DataProvider dataProvider) 20 | { 21 | this.logger = logger; 22 | this.networkAccessor = networkAccessor; 23 | this.dataProvider = dataProvider; 24 | } 25 | 26 | public NeuralNetworkPredictionsReport RunPredictions() 27 | { 28 | return dataProvider.TestingData 29 | .Aggregate(NeuralNetworkPredictionsReport.EmptyReport(), MakePredictionRecordingResult); 30 | } 31 | 32 | private NeuralNetworkPredictionsReport MakePredictionRecordingResult( 33 | NeuralNetworkPredictionsReport report, 34 | BankTransaction transaction) 35 | { 36 | logger.LogInformation($"Predicting new transaction. Current report: {report}"); 37 | 38 | var networkPrediction = networkAccessor.TargetNetwork 39 | .PredictionFor(transaction.ToNetworkInputData(), 40 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions); 41 | 42 | if(IsCorrectPrediction(networkPrediction, transaction.Class)) 43 | { 44 | return NeuralNetworkPredictionsReport.UpdateFor( 45 | report, 46 | transaction.Class, 47 | predictionWasCorrect: true); 48 | } 49 | 50 | return NeuralNetworkPredictionsReport.UpdateFor( 51 | report, 52 | transaction.Class, 53 | predictionWasCorrect: false); 54 | } 55 | 56 | private bool IsCorrectPrediction(double[] prediction, BankTransactionClass actualClass) 57 | { 58 | var predictedClass = Array.IndexOf(prediction, prediction.Max()); 59 | 60 | return (BankTransactionClass)predictedClass == actualClass ? true : false; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Application/NeuralNetworkTrainingService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using NeuralNetworks.Examples.FraudDetection.Services.Configuration; 6 | using NeuralNetworks.Examples.FraudDetection.Services.Domain; 7 | using NeuralNetworks.Library; 8 | using NeuralNetworks.Library.Data; 9 | using NeuralNetworks.Library.Extensions; 10 | using NeuralNetworks.Library.Training; 11 | using NeuralNetworks.Library.Training.BackPropagation; 12 | 13 | namespace NeuralNetworks.Examples.FraudDetection.Services.Application 14 | { 15 | public sealed class NeuralNetworkTrainingService 16 | { 17 | private readonly NeuralNetworkAccessor networkAccessor; 18 | private readonly DataProvider dataProvider; 19 | 20 | public NeuralNetworkTrainingService( 21 | NeuralNetworkAccessor networkAccessor, 22 | DataProvider dataProvider) 23 | { 24 | this.networkAccessor = networkAccessor; 25 | this.dataProvider = dataProvider; 26 | } 27 | 28 | public async Task TrainConfiguredNetworkForEpochs( 29 | int epochs, 30 | NeuralNetworkTrainingConfiguration trainingConfig) 31 | { 32 | var trainingData = dataProvider.TrainingData 33 | .Select(transaction => transaction.ToTrainingData()) 34 | .ToList(); 35 | 36 | await TrainingController.For(BackPropagation.WithConfiguration( 37 | networkAccessor.TargetNetwork, 38 | ParallelOptionsExtensions.MultiThreadedOptions(trainingConfig.ThreadCount), 39 | trainingConfig.LearningRate, 40 | trainingConfig.Momentum)) 41 | .TrainForEpochsOrErrorThresholdMet(trainingData, epochs, trainingConfig.MinimumErrorThreshold); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Configuration/DataSourceConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Examples.FraudDetection.Services.Configuration 2 | { 3 | public class DataSourceConfiguration 4 | { 5 | public string FileLocation { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Configuration/NeuralNetworkTrainingConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Examples.FraudDetection.Services.Configuration 2 | { 3 | public class NeuralNetworkTrainingConfiguration 4 | { 5 | public double LearningRate { get; set; } 6 | public double Momentum { get; set; } 7 | public int ThreadCount { get; set; } 8 | public double MinimumErrorThreshold { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/BankTransaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 5 | { 6 | public enum BankTransactionClass 7 | { 8 | Legitimate, 9 | Fraudulent 10 | } 11 | 12 | public class BankTransaction 13 | { 14 | public BankTransactionClass Class { get; internal set; } 15 | 16 | public int TimeOfTransaction { get; internal set; } 17 | public double Amount { get; internal set; } 18 | 19 | public double DataPoint1 { get; internal set; } 20 | public double DataPoint2 { get; internal set; } 21 | public double DataPoint3 { get; internal set; } 22 | public double DataPoint4 { get; internal set; } 23 | public double DataPoint5 { get; internal set; } 24 | public double DataPoint6 { get; internal set; } 25 | public double DataPoint7 { get; internal set; } 26 | public double DataPoint8 { get; internal set; } 27 | public double DataPoint9 { get; internal set; } 28 | public double DataPoint10 { get; internal set; } 29 | public double DataPoint11 { get; internal set; } 30 | public double DataPoint12 { get; internal set; } 31 | public double DataPoint13 { get; internal set; } 32 | public double DataPoint14 { get; internal set; } 33 | public double DataPoint15 { get; internal set; } 34 | public double DataPoint16 { get; internal set; } 35 | public double DataPoint17 { get; internal set; } 36 | public double DataPoint18 { get; internal set; } 37 | public double DataPoint19 { get; internal set; } 38 | public double DataPoint20 { get; internal set; } 39 | public double DataPoint21 { get; internal set; } 40 | public double DataPoint22 { get; internal set; } 41 | public double DataPoint23 { get; internal set; } 42 | public double DataPoint24 { get; internal set; } 43 | public double DataPoint25 { get; internal set; } 44 | public double DataPoint26 { get; internal set; } 45 | public double DataPoint27 { get; internal set; } 46 | public double DataPoint28 { get; internal set; } 47 | 48 | public override bool Equals(object obj) 49 | { 50 | var transaction = obj as BankTransaction; 51 | return transaction == null ? false : Equals(transaction); 52 | } 53 | 54 | private bool Equals(BankTransaction transaction) 55 | { 56 | if(transaction.Class != Class) return false; 57 | if(transaction.Amount != Amount) return false; 58 | if(transaction.TimeOfTransaction != TimeOfTransaction) return false; 59 | return true; 60 | } 61 | 62 | public override int GetHashCode() 63 | { 64 | var hashCode = 13; 65 | unchecked { 66 | hashCode = (hashCode * 397) ^ TimeOfTransaction; 67 | hashCode = (hashCode * 397) ^ (int)Class; 68 | hashCode = (hashCode * 397) ^ (int)Amount; 69 | } 70 | return hashCode; 71 | } 72 | 73 | public static BankTransaction For(string[] orderedValues) 74 | { 75 | ValidateOrderedValues(orderedValues); 76 | 77 | return new BankTransaction 78 | { 79 | TimeOfTransaction = Int32.Parse(orderedValues[0], NumberStyles.AllowExponent), 80 | DataPoint1 = Double.Parse(orderedValues[1]), 81 | DataPoint2 = Double.Parse(orderedValues[2]), 82 | DataPoint3 = Double.Parse(orderedValues[3]), 83 | DataPoint4 = Double.Parse(orderedValues[4]), 84 | DataPoint5 = Double.Parse(orderedValues[5]), 85 | DataPoint6 = Double.Parse(orderedValues[6]), 86 | DataPoint7 = Double.Parse(orderedValues[7]), 87 | DataPoint8 = Double.Parse(orderedValues[8]), 88 | DataPoint9 = Double.Parse(orderedValues[9]), 89 | DataPoint10 = Double.Parse(orderedValues[10]), 90 | DataPoint11 = Double.Parse(orderedValues[11]), 91 | DataPoint12 = Double.Parse(orderedValues[12]), 92 | DataPoint13 = Double.Parse(orderedValues[13]), 93 | DataPoint14 = Double.Parse(orderedValues[14]), 94 | DataPoint15 = Double.Parse(orderedValues[15]), 95 | DataPoint16 = Double.Parse(orderedValues[16]), 96 | DataPoint17 = Double.Parse(orderedValues[17]), 97 | DataPoint18 = Double.Parse(orderedValues[18]), 98 | DataPoint19 = Double.Parse(orderedValues[19]), 99 | DataPoint20 = Double.Parse(orderedValues[20]), 100 | DataPoint21 = Double.Parse(orderedValues[21]), 101 | DataPoint22 = Double.Parse(orderedValues[22]), 102 | DataPoint23 = Double.Parse(orderedValues[23]), 103 | DataPoint24 = Double.Parse(orderedValues[24]), 104 | DataPoint25 = Double.Parse(orderedValues[25]), 105 | DataPoint26 = Double.Parse(orderedValues[26]), 106 | DataPoint27 = Double.Parse(orderedValues[27]), 107 | DataPoint28 = Double.Parse(orderedValues[28]), 108 | Amount = Double.Parse(orderedValues[29]), 109 | Class = orderedValues[30].Contains("1") ? 110 | BankTransactionClass.Fraudulent : BankTransactionClass.Legitimate 111 | }; 112 | } 113 | 114 | private static void ValidateOrderedValues(string[] orderedValues) 115 | { 116 | if(orderedValues.Length != 31) 117 | { 118 | throw new ArgumentException("Each Bank Transaction should have 31 values"); 119 | } 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/BankTransactionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NeuralNetworks.Library.Data; 4 | 5 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 6 | { 7 | internal static class BankTransactionExtensions 8 | { 9 | public static TrainingDataSet ToTrainingData(this BankTransaction bankTransaction) 10 | { 11 | var inputs = bankTransaction.ToNetworkInputData(); 12 | 13 | var outputs = Enumerable.Repeat(0.0, 2).ToList(); 14 | outputs[Convert.ToInt32(bankTransaction.Class)] = 1; 15 | 16 | return TrainingDataSet.For(inputs.ToArray(), outputs.ToArray()); 17 | } 18 | 19 | public static double[] ToNetworkInputData(this BankTransaction bankTransaction) 20 | { 21 | return new [] { 22 | bankTransaction.Amount, 23 | bankTransaction.DataPoint1, 24 | bankTransaction.DataPoint2, 25 | bankTransaction.DataPoint3, 26 | bankTransaction.DataPoint4, 27 | bankTransaction.DataPoint5, 28 | bankTransaction.DataPoint6, 29 | bankTransaction.DataPoint7, 30 | bankTransaction.DataPoint8, 31 | bankTransaction.DataPoint9, 32 | bankTransaction.DataPoint10, 33 | bankTransaction.DataPoint11, 34 | bankTransaction.DataPoint12, 35 | bankTransaction.DataPoint13, 36 | bankTransaction.DataPoint14, 37 | bankTransaction.DataPoint15, 38 | bankTransaction.DataPoint16, 39 | bankTransaction.DataPoint17, 40 | bankTransaction.DataPoint18, 41 | bankTransaction.DataPoint19, 42 | bankTransaction.DataPoint20, 43 | bankTransaction.DataPoint21, 44 | bankTransaction.DataPoint22, 45 | bankTransaction.DataPoint23, 46 | bankTransaction.DataPoint24, 47 | bankTransaction.DataPoint25, 48 | bankTransaction.DataPoint26, 49 | bankTransaction.DataPoint27, 50 | bankTransaction.DataPoint28 51 | }; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/BankTransactionNormaliser.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 2 | { 3 | internal static class BankTransactionNormaliser 4 | { 5 | public static BankTransaction NormaliseTransactionAmount( 6 | BankTransaction bankTransaction, 7 | double min, 8 | double max) 9 | { 10 | return new BankTransaction() 11 | { 12 | TimeOfTransaction = bankTransaction.TimeOfTransaction, 13 | DataPoint1 = bankTransaction.DataPoint1, 14 | DataPoint2 = bankTransaction.DataPoint2, 15 | DataPoint3 = bankTransaction.DataPoint3, 16 | DataPoint4 = bankTransaction.DataPoint4, 17 | DataPoint5 = bankTransaction.DataPoint5, 18 | DataPoint6 = bankTransaction.DataPoint6, 19 | DataPoint7 = bankTransaction.DataPoint7, 20 | DataPoint8 = bankTransaction.DataPoint8, 21 | DataPoint9 = bankTransaction.DataPoint9, 22 | DataPoint10 = bankTransaction.DataPoint10, 23 | DataPoint11 = bankTransaction.DataPoint11, 24 | DataPoint12 = bankTransaction.DataPoint12, 25 | DataPoint13 = bankTransaction.DataPoint13, 26 | DataPoint14 = bankTransaction.DataPoint14, 27 | DataPoint15 = bankTransaction.DataPoint15, 28 | DataPoint16 = bankTransaction.DataPoint16, 29 | DataPoint17 = bankTransaction.DataPoint17, 30 | DataPoint18 = bankTransaction.DataPoint18, 31 | DataPoint19 = bankTransaction.DataPoint19, 32 | DataPoint20 = bankTransaction.DataPoint20, 33 | DataPoint21 = bankTransaction.DataPoint21, 34 | DataPoint22 = bankTransaction.DataPoint22, 35 | DataPoint23 = bankTransaction.DataPoint23, 36 | DataPoint24 = bankTransaction.DataPoint24, 37 | DataPoint25 = bankTransaction.DataPoint25, 38 | DataPoint26 = bankTransaction.DataPoint26, 39 | DataPoint27 = bankTransaction.DataPoint27, 40 | DataPoint28 = bankTransaction.DataPoint28, 41 | Amount = bankTransaction.Amount.NormaliseValue(min, max), 42 | Class = bankTransaction.Class 43 | }; 44 | } 45 | 46 | private static double NormaliseValue(this double value, double min, double max) 47 | { 48 | return (value - min) / (max - min); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/CsvFileReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 6 | { 7 | public static class CsvFileReader 8 | { 9 | public static IList ReadFromFile( 10 | string csvFilepath, 11 | Func rowToEntity, 12 | bool containsHeaders = true) 13 | { 14 | var readRowsAsEntity = new List(); 15 | 16 | using(var streamReader = File.OpenText(csvFilepath)) 17 | { 18 | if(containsHeaders) 19 | { 20 | ReadRowOfFileIfNotAtEnd(streamReader, out _); 21 | } 22 | 23 | while(!ReadRowOfFileIfNotAtEnd(streamReader, out var currentRow)) 24 | { 25 | readRowsAsEntity.Add(ProcessRowOfFile(currentRow, rowToEntity)); 26 | } 27 | } 28 | 29 | return readRowsAsEntity; 30 | } 31 | 32 | private static bool ReadRowOfFileIfNotAtEnd(StreamReader streamReader, out string currentRow) 33 | { 34 | currentRow = streamReader.ReadLine(); 35 | return currentRow == null ? true : false; 36 | } 37 | 38 | private static TEntity ProcessRowOfFile( 39 | string line, 40 | Func rowToEntity) 41 | { 42 | var dataColumns = line.Split(','); 43 | return rowToEntity.Invoke(dataColumns); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/DataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Microsoft.Extensions.Options; 6 | using NeuralNetworks.Examples.FraudDetection.Services.Configuration; 7 | using NeuralNetworks.Library.Data; 8 | 9 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 10 | { 11 | public class DataProvider 12 | { 13 | public List TrainingData => trainingData.Value; 14 | 15 | private readonly Lazy> trainingData; 16 | 17 | public List TestingData => testingData.Value; 18 | 19 | private readonly Lazy> testingData; 20 | 21 | private readonly Lazy> allDataRows; 22 | 23 | private List TrainingDataRowsForClass(BankTransactionClass targetClass) 24 | { 25 | var dataRowsInClass = allDataRows.Value 26 | .Where(transaction => transaction.Class == targetClass) 27 | .ToList(); 28 | 29 | return RandomSubsetOfDataSet(dataRowsInClass, rowCountOfSmallestTransactionCategory.Value / 2); 30 | } 31 | 32 | private List RandomSubsetOfDataSet(List dataSet, int subsetAmount) 33 | { 34 | var randomNumberGenerator = new Random(1); 35 | 36 | return Enumerable 37 | .Range(0, subsetAmount) 38 | .Select(_ => dataSet[randomNumberGenerator.Next(0, dataSet.Count)]) 39 | .ToList(); 40 | } 41 | 42 | private readonly Lazy bankTransactionAmountMin; 43 | private readonly Lazy bankTransactionAmountMax; 44 | private readonly Lazy rowCountOfSmallestTransactionCategory; 45 | 46 | public DataProvider(IOptions dataSource) 47 | { 48 | allDataRows = new Lazy>( 49 | () => CsvFileReader.ReadFromFile( 50 | dataSource.Value.FileLocation, 51 | BankTransaction.For)); 52 | 53 | bankTransactionAmountMin = new Lazy( 54 | () => allDataRows.Value 55 | .Select(r => r.Amount) 56 | .Min()); 57 | 58 | bankTransactionAmountMax = new Lazy( 59 | () => allDataRows.Value 60 | .Select(r => r.Amount) 61 | .Max()); 62 | 63 | rowCountOfSmallestTransactionCategory = new Lazy( 64 | () => allDataRows.Value 65 | .GroupBy(transaction => transaction.Class) 66 | .Select(g => g.Count()) 67 | .Min()); 68 | 69 | trainingData = new Lazy>( 70 | () => TrainingDataRowsForClass(BankTransactionClass.Fraudulent) 71 | .Concat(TrainingDataRowsForClass(BankTransactionClass.Legitimate)) 72 | .Select(transaction => BankTransactionNormaliser 73 | .NormaliseTransactionAmount( 74 | transaction, 75 | bankTransactionAmountMin.Value, 76 | bankTransactionAmountMax.Value)) 77 | .ToList() 78 | ); 79 | 80 | testingData = new Lazy>( 81 | () => allDataRows.Value 82 | .Select(transaction => BankTransactionNormaliser 83 | .NormaliseTransactionAmount( 84 | transaction, 85 | bankTransactionAmountMin.Value, 86 | bankTransactionAmountMax.Value)) 87 | .Except(TrainingData) 88 | .ToList() 89 | ); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/NeuralNetworkAccessor.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library; 2 | 3 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 4 | { 5 | public class NeuralNetworkAccessor 6 | { 7 | internal NeuralNetwork TargetNetwork { get; } 8 | 9 | public NeuralNetworkAccessor(NeuralNetwork targetNetwork) 10 | { 11 | TargetNetwork = targetNetwork; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/Domain/NeuralNetworkPredictionReport.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Examples.FraudDetection.Services.Domain 4 | { 5 | public sealed class NeuralNetworkPredictionsReport 6 | { 7 | public int TotalCorrectPredictions { get; } 8 | public int TotalIncorrectPredictions { get; } 9 | public int IncorrectFraudulentPredictions { get; } 10 | public int IncorrectLegitimatePredictions { get; } 11 | 12 | private NeuralNetworkPredictionsReport( 13 | int numberOfCorrectPredictions, 14 | int numberOfIncorrectPredictions, 15 | int incorrectFraudulentPredictions, 16 | int incorrectLegitimatePredictions) 17 | { 18 | TotalCorrectPredictions = numberOfCorrectPredictions; 19 | TotalIncorrectPredictions = numberOfIncorrectPredictions; 20 | IncorrectFraudulentPredictions = incorrectFraudulentPredictions; 21 | IncorrectLegitimatePredictions = incorrectLegitimatePredictions; 22 | } 23 | 24 | public override string ToString() 25 | { 26 | return $"Correct: {TotalCorrectPredictions}. Incorrect: {TotalIncorrectPredictions}"; 27 | } 28 | 29 | internal static NeuralNetworkPredictionsReport EmptyReport() 30 | => new NeuralNetworkPredictionsReport(0, 0, 0, 0); 31 | 32 | internal static NeuralNetworkPredictionsReport UpdateFor( 33 | NeuralNetworkPredictionsReport previousReport, 34 | BankTransactionClass predictionClass, 35 | bool predictionWasCorrect) 36 | { 37 | if(predictionWasCorrect) 38 | { 39 | return new NeuralNetworkPredictionsReport( 40 | previousReport.TotalCorrectPredictions + 1, 41 | previousReport.TotalIncorrectPredictions, 42 | previousReport.IncorrectFraudulentPredictions, 43 | previousReport.IncorrectLegitimatePredictions); 44 | } 45 | 46 | if(predictionClass == BankTransactionClass.Fraudulent) 47 | { 48 | return new NeuralNetworkPredictionsReport( 49 | previousReport.TotalCorrectPredictions, 50 | previousReport.TotalIncorrectPredictions + 1, 51 | previousReport.IncorrectFraudulentPredictions + 1, 52 | previousReport.IncorrectLegitimatePredictions); 53 | } 54 | 55 | if(predictionClass == BankTransactionClass.Legitimate) 56 | { 57 | return new NeuralNetworkPredictionsReport( 58 | previousReport.TotalCorrectPredictions, 59 | previousReport.TotalIncorrectPredictions + 1, 60 | previousReport.IncorrectFraudulentPredictions, 61 | previousReport.IncorrectLegitimatePredictions + 1); 62 | } 63 | 64 | throw new InvalidOperationException($"Transaction class {predictionClass} is not supported."); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/NeuralNetworks.Examples.FraudDetection.Services.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Services/ServiceLayerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Logging; 3 | using NeuralNetworks.Examples.FraudDetection.Services.Domain; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components.Activation; 6 | using NeuralNetworks.Library.Logging; 7 | using NeuralNetworks.Library.Training; 8 | 9 | namespace NeuralNetworks.Examples.FraudDetection.Services 10 | { 11 | public static class ServiceLayerConfiguration 12 | { 13 | public static IServiceCollection ConfigureServiceLayer(this IServiceCollection services) 14 | { 15 | return services 16 | .AddSingleton(new NeuralNetworkAccessor(NeuralNetwork)) 17 | .AddSingleton(typeof(DataProvider)); 18 | } 19 | 20 | private static NeuralNetwork NeuralNetwork => 21 | NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 22 | .WithInputLayer(neuronCount: 29, activationType: ActivationType.Sigmoid) 23 | .WithHiddenLayer(neuronCount: 18, activationType: ActivationType.TanH) 24 | .WithHiddenLayer(neuronCount: 27, activationType: ActivationType.TanH) 25 | .WithHiddenLayer(neuronCount: 40, activationType: ActivationType.TanH) 26 | .WithOutputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 27 | .Build(); 28 | 29 | public static ILoggerFactory ConfigureServiceLayerLogging(this ILoggerFactory loggerFactory) 30 | { 31 | return loggerFactory.InitialiseLoggingForNeuralNetworksLibrary(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "wwwroot/lib" 3 | } 4 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Extensions/IServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | namespace NeuralNetworks.Examples.FraudDetection.Web.Extensions 6 | { 7 | public static class IServiceCollectionExtensions 8 | { 9 | public static TSettings BindApplicationSettings( 10 | this IServiceCollection services, 11 | IConfigurationSection configuration) where TSettings : class, new() 12 | { 13 | if (services == null) throw new ArgumentNullException(nameof(services)); 14 | if (configuration == null) throw new ArgumentNullException(nameof(configuration)); 15 | 16 | var settings = new TSettings(); 17 | configuration.Bind(settings); 18 | services.AddSingleton(settings); 19 | return settings; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Models/PredictionsReport.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Examples.FraudDetection.Web.Models 4 | { 5 | public class PredictionsReport 6 | { 7 | public int TotalCorrectPredictions { get; set; } 8 | public int TotalIncorrectPredictions { get; set; } 9 | 10 | public string PercentageOfPredictionsCorrect 11 | { 12 | get { 13 | var total = TotalCorrectPredictions + TotalIncorrectPredictions; 14 | if(total == 0) return $"{0:00.00}%"; 15 | 16 | var percentage = (Convert.ToDouble(TotalCorrectPredictions) / Convert.ToDouble(total)) * 100; 17 | return $"{((percentage)):00.00}%"; 18 | } 19 | } 20 | 21 | public int IncorrectFraudulentPredictions { get; set; } 22 | public int IncorrectLegitimatePredictions { get; set; } 23 | 24 | public string PercentageOfIncorrectPredictionsFraudulent 25 | { 26 | get 27 | { 28 | var total = IncorrectFraudulentPredictions + IncorrectLegitimatePredictions; 29 | if(total == 0) return $"{0:00.00}%"; 30 | 31 | var percentage = (Convert.ToDouble(IncorrectFraudulentPredictions) / Convert.ToDouble(total)) * 100; 32 | return $"{((percentage)):00.00}%"; 33 | } 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/NeuralNetworks.Examples.FraudDetection.Web.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to Development environment will display more detailed information about the error that occurred. 20 |

21 |

22 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 23 |

24 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc.RazorPages; 7 | 8 | namespace NeuralNetworks.Examples.FraudDetection.Web.Pages 9 | { 10 | public class ErrorModel : PageModel 11 | { 12 | public string RequestId { get; set; } 13 | 14 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 15 | 16 | public void OnGet() 17 | { 18 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @{ 4 | ViewData["Title"] = "Home page"; 5 | } 6 | 7 |
8 |

Fraud Detection Example

9 |

10 | Welcome to the Fraud Detection Example showcasing the 11 | Neural Network Library. 12 |

13 |
-------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/Index.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.RazorPages; 7 | using NeuralNetworks.Examples.FraudDetection.Services; 8 | 9 | namespace NeuralNetworks.Examples.FraudDetection.Web.Pages 10 | { 11 | public class IndexModel : PageModel 12 | { 13 | public void OnGet() 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/PerformPredictions.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PerformPredictionsModel 3 | @{ 4 | ViewData["Title"] = "Prediction page"; 5 | } 6 | 7 |
8 |

Perform Network Predictions

9 |
10 | 11 |
12 | 13 | @if(@Model.PredictionsReport.TotalCorrectPredictions != 0 || @Model.PredictionsReport.TotalIncorrectPredictions != 0){ 14 |

Prediction Report

15 |

Correct Predictions: @Model.PredictionsReport.TotalCorrectPredictions

16 |

Incorrect Predictions: @Model.PredictionsReport.TotalIncorrectPredictions

17 |

Correct Percentage: @Model.PredictionsReport.PercentageOfPredictionsCorrect

18 |

Incorrect Predictions That Were Legitimate: @Model.PredictionsReport.IncorrectLegitimatePredictions

19 |

Incorrect Predictions That Were Fraudulent: @Model.PredictionsReport.IncorrectFraudulentPredictions

20 |

Incorrect Predictions Fraudulent Percentage: @Model.PredictionsReport.PercentageOfIncorrectPredictionsFraudulent

21 | } 22 |
-------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/PerformPredictions.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.RazorPages; 7 | using NeuralNetworks.Examples.FraudDetection.Services; 8 | using NeuralNetworks.Examples.FraudDetection.Services.Application; 9 | using NeuralNetworks.Examples.FraudDetection.Services.Domain; 10 | using NeuralNetworks.Examples.FraudDetection.Web.Models; 11 | 12 | namespace NeuralNetworks.Examples.FraudDetection.Web.Pages 13 | { 14 | public class PerformPredictionsModel : PageModel 15 | { 16 | private readonly NeuralNetworkPredictionService networkPredictionService; 17 | 18 | public PerformPredictionsModel(NeuralNetworkPredictionService networkPredictionService) 19 | { 20 | this.networkPredictionService = networkPredictionService; 21 | } 22 | 23 | public PredictionsReport PredictionsReport { get; set; } 24 | 25 | public void OnGet(PredictionsReport predictionsReport) 26 | { 27 | PredictionsReport = predictionsReport; 28 | } 29 | 30 | public IActionResult OnPostPredict() 31 | { 32 | var predictionsReport = networkPredictionService.RunPredictions(); 33 | return RedirectToPage(new PredictionsReport(){ 34 | TotalCorrectPredictions = predictionsReport.TotalCorrectPredictions, 35 | TotalIncorrectPredictions = predictionsReport.TotalIncorrectPredictions, 36 | IncorrectFraudulentPredictions = predictionsReport.IncorrectFraudulentPredictions, 37 | IncorrectLegitimatePredictions = predictionsReport.IncorrectLegitimatePredictions}); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/PerformTraining.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model PerformTrainingModel 3 | @{ 4 | ViewData["Title"] = "Training page"; 5 | } 6 | 7 |
8 |

Perform Network Training

9 |
10 | 11 | 12 |
13 |
-------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/PerformTraining.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.RazorPages; 7 | using Microsoft.Extensions.Options; 8 | using NeuralNetworks.Examples.FraudDetection.Services; 9 | using NeuralNetworks.Examples.FraudDetection.Services.Application; 10 | using NeuralNetworks.Examples.FraudDetection.Services.Configuration; 11 | 12 | namespace NeuralNetworks.Examples.FraudDetection.Web.Pages 13 | { 14 | public class PerformTrainingModel : PageModel 15 | { 16 | private readonly NeuralNetworkTrainingService networkTrainingService; 17 | private readonly NeuralNetworkTrainingConfiguration trainingConfiguration; 18 | 19 | public PerformTrainingModel( 20 | NeuralNetworkTrainingService networkTrainingService, 21 | IOptions trainingConfiguration) 22 | { 23 | this.networkTrainingService = networkTrainingService; 24 | this.trainingConfiguration = trainingConfiguration.Value; 25 | } 26 | 27 | public async Task OnPostTrainAsync(int epochAmount) 28 | { 29 | await networkTrainingService.TrainConfiguredNetworkForEpochs(epochAmount, trainingConfiguration); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - Fraud Detection Example 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 40 |
41 | @RenderBody() 42 |
43 |
44 |

© 2017 - GuardianDevelopment

45 |
46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 66 | 67 | 68 | 69 | @RenderSection("Scripts", required: false) 70 | 71 | 72 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using NeuralNetworks.Examples.FraudDetection.Web 2 | @namespace NeuralNetworks.Examples.FraudDetection.Web.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace NeuralNetworks.Examples.FraudDetection.Web 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | BuildWebHost(args).Run(); 18 | } 19 | 20 | public static IWebHost BuildWebHost(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup() 23 | .Build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using NeuralNetworks.Examples.FraudDetection.Web.Extensions; 10 | using NeuralNetworks.Examples.FraudDetection.Services.Application; 11 | using NeuralNetworks.Examples.FraudDetection.Services; 12 | using NeuralNetworks.Examples.FraudDetection.Services.Configuration; 13 | using Microsoft.Extensions.Logging; 14 | 15 | namespace NeuralNetworks.Examples.FraudDetection.Web 16 | { 17 | public class Startup 18 | { 19 | private const string DataSourceConfigurationSection = "DataSourceConfiguration"; 20 | private const string NeuralNetworkTrainingConfigurationSection = "NeuralNetworkTrainingConfiguration"; 21 | 22 | public Startup(IConfiguration configuration) 23 | { 24 | Configuration = configuration; 25 | } 26 | 27 | public IConfiguration Configuration { get; } 28 | 29 | public void ConfigureServices(IServiceCollection services) 30 | { 31 | services.AddMvc(); 32 | 33 | services.Configure(Configuration.GetSection(DataSourceConfigurationSection)) 34 | .Configure(Configuration.GetSection(NeuralNetworkTrainingConfigurationSection)) 35 | .ConfigureServiceLayer() 36 | .AddTransient(typeof(NeuralNetworkTrainingService)) 37 | .AddTransient(typeof(NeuralNetworkPredictionService)); 38 | } 39 | 40 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 41 | { 42 | loggerFactory.ConfigureServiceLayerLogging(); 43 | 44 | if (env.IsDevelopment()) 45 | { 46 | app.UseDeveloperExceptionPage(); 47 | } 48 | else 49 | { 50 | app.UseExceptionHandler("/Error"); 51 | } 52 | 53 | app.UseStaticFiles(); 54 | 55 | app.UseMvc(routes => 56 | { 57 | routes.MapRoute( 58 | name: "default", 59 | template: "{controller}/{action=Index}/{id?}"); 60 | }); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Information", 7 | "Microsoft": "Information", 8 | "Microsoft.Extensions.Logging.LoggerFactory": "Debug", 9 | "NeuralNetworks.Library" : "Debug" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Warning", 6 | "Microsoft.Extensions.Logging.LoggerFactory": "Debug", 7 | "NeuralNetworks.Library" : "Debug" 8 | } 9 | }, 10 | 11 | "DataSourceConfiguration": { 12 | "FileLocation" : "/Users/joehonour/Downloads/creditcard.csv" 13 | }, 14 | 15 | "NeuralNetworkTrainingConfiguration": { 16 | "LearningRate" : 1.4, 17 | "Momentum": 0.4, 18 | "ThreadCount" : 50, 19 | "MinimumErrorThreshold" : 0.01 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asp.net", 3 | "private": true, 4 | "dependencies": { 5 | "bootstrap": "3.3.7", 6 | "jquery": "2.2.0", 7 | "jquery-validation": "1.14.0", 8 | "jquery-validation-unobtrusive": "3.2.6" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/bundleconfig.json: -------------------------------------------------------------------------------- 1 | // Configure bundling and minification for the project. 2 | // More info at https://go.microsoft.com/fwlink/?LinkId=808241 3 | [ 4 | { 5 | "outputFileName": "wwwroot/css/site.min.css", 6 | // An array of relative input file paths. Globbing patterns supported 7 | "inputFiles": [ 8 | "wwwroot/css/site.css" 9 | ] 10 | }, 11 | { 12 | "outputFileName": "wwwroot/js/site.min.js", 13 | "inputFiles": [ 14 | "wwwroot/js/site.js" 15 | ], 16 | // Optionally specify minification options 17 | "minify": { 18 | "enabled": true, 19 | "renameLocals": true 20 | }, 21 | // Optionally generate .map file 22 | "sourceMap": false 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Wrapping element */ 7 | /* Set some basic padding to keep content from hitting the edges */ 8 | .body-content { 9 | padding-left: 15px; 10 | padding-right: 15px; 11 | } 12 | 13 | /* Carousel */ 14 | .carousel-caption p { 15 | font-size: 20px; 16 | line-height: 1.4; 17 | } 18 | 19 | /* Make .svg files in the carousel display properly in older browsers */ 20 | .carousel-inner .item img[src$=".svg"] { 21 | width: 100%; 22 | } 23 | 24 | /* QR code generator */ 25 | #qrCode { 26 | margin: 15px; 27 | } 28 | 29 | /* Hide/rearrange for smaller screens */ 30 | @media screen and (max-width: 767px) { 31 | /* Hide captions */ 32 | .carousel-caption { 33 | display: none; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. 2 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Guardian-Development/NeuralNetworksLibrary/9aec4971412fdfcef1e4176e1876757a40623285/ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "version": "3.2.6", 4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", 6 | "main": [ 7 | "jquery.validate.unobtrusive.js" 8 | ], 9 | "ignore": [ 10 | "**/.*", 11 | "*.json", 12 | "*.md", 13 | "*.txt", 14 | "gulpfile.js" 15 | ], 16 | "keywords": [ 17 | "jquery", 18 | "asp.net", 19 | "mvc", 20 | "validation", 21 | "unobtrusive" 22 | ], 23 | "authors": [ 24 | "Microsoft" 25 | ], 26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" 30 | }, 31 | "dependencies": { 32 | "jquery-validation": ">=1.8", 33 | "jquery": ">=1.8" 34 | }, 35 | "_release": "3.2.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.2.6", 39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" 40 | }, 41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", 42 | "_target": "3.2.6", 43 | "_originalSource": "jquery-validation-unobtrusive" 44 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | !function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery); -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "http://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jzaefferer/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.14.0", 31 | "_release": "1.14.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.14.0", 35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" 36 | }, 37 | "_source": "git://github.com/jzaefferer/jquery-validation.git", 38 | "_target": ">=1.8", 39 | "_originalSource": "jquery-validation" 40 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "2.2.0", 16 | "_release": "2.2.0", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "2.2.0", 20 | "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5" 21 | }, 22 | "_source": "git://github.com/jquery/jquery-dist.git", 23 | "_target": "2.2.0", 24 | "_originalSource": "jquery" 25 | } -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.Web/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/NeuralNetworks.Examples.FraudDetection.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Examples.FraudDetection.Web", "NeuralNetworks.Examples.FraudDetection.Web\NeuralNetworks.Examples.FraudDetection.Web.csproj", "{63781E3C-665E-45C4-8409-D716F82D67F0}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Examples.FraudDetection.Services", "NeuralNetworks.Examples.FraudDetection.Services\NeuralNetworks.Examples.FraudDetection.Services.csproj", "{E16F801D-C960-48BC-9086-11C6833C0A08}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|x64.ActiveCfg = Debug|x64 26 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|x64.Build.0 = Debug|x64 27 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|x86.ActiveCfg = Debug|x86 28 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Debug|x86.Build.0 = Debug|x86 29 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|x64.ActiveCfg = Release|x64 32 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|x64.Build.0 = Release|x64 33 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|x86.ActiveCfg = Release|x86 34 | {63781E3C-665E-45C4-8409-D716F82D67F0}.Release|x86.Build.0 = Release|x86 35 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|x64.ActiveCfg = Debug|x64 38 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|x64.Build.0 = Debug|x64 39 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|x86.ActiveCfg = Debug|x86 40 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Debug|x86.Build.0 = Debug|x86 41 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|x64.ActiveCfg = Release|x64 44 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|x64.Build.0 = Release|x64 45 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|x86.ActiveCfg = Release|x86 46 | {E16F801D-C960-48BC-9086-11C6833C0A08}.Release|x86.Build.0 = Release|x86 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /ExampleProjects/FraudDetection/README.md: -------------------------------------------------------------------------------- 1 | # Fraud Detection Neural Network Example 2 | The aim of this project is to show how the Neural Networks library can be integrated into a small, simple web application. 3 | 4 | ## Starting the Application 5 | 1. Download and unzip the Credit Card Transaction Data Set from: https://www.kaggle.com/dalpozz/creditcardfraud 6 | 7 | 2. Update the AppSettings.json file to have the correct location of the downloaded file 8 | 3. Run the web project : "dotnet run" from with the Web Project Directory 9 | 10 | ## How To Use 11 | 1. Navigate to the Train Tab. 12 | 2. From here you can enter the amount of epochs to train for. (1000 produces accurate results) 13 | 3. Once trained, go to the Predict Tab. 14 | 4. Click predict to get predictions for all data rows not used in training. You will also be presented with a report of how successful your trained Neural Network was. 15 | 16 | ## Adapting 17 | - To change the Learning rate, Momentum, Minimum Error Threshold and Thread Count when using the Neural Network edit the appsettings.json file. 18 | 19 | ## Notes 20 | This is a small application designed to show how a Neural Network can solve quite a complex problem. It has not been made with extensibility in mind and does not support more than one user. 21 | 22 | -------------------------------------------------------------------------------- /NeuralNetworks.Console/NeuralNetworks.Console.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /NeuralNetworks.Console/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Logging; 6 | using NeuralNetworks.Library; 7 | using NeuralNetworks.Library.Components.Activation; 8 | using NeuralNetworks.Library.Data; 9 | using NeuralNetworks.Library.Extensions; 10 | using NeuralNetworks.Library.Logging; 11 | using NeuralNetworks.Library.Training; 12 | using NeuralNetworks.Library.Training.BackPropagation; 13 | 14 | namespace NeuralNetworks.Console 15 | { 16 | public class Program 17 | { 18 | public static void Main(string[] args) 19 | { 20 | ConfigureLogging(); 21 | 22 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 23 | .WithInputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 24 | .WithHiddenLayer(neuronCount: 5, activationType: ActivationType.TanH) 25 | .WithOutputLayer(neuronCount: 1, activationType: ActivationType.Sigmoid) 26 | .Build(); 27 | 28 | TrainingController 29 | .For(BackPropagation.WithConfiguration( 30 | neuralNetwork, 31 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 32 | learningRate: 0.6, 33 | momentum: 0.9)) 34 | .TrainForEpochsOrErrorThresholdMet(GetXorTrainingData(), maximumEpochs: 5000, errorThreshold: 0.001) 35 | .GetAwaiter() 36 | .GetResult(); 37 | 38 | MakeExamplePredictions(neuralNetwork); 39 | } 40 | 41 | private static void ConfigureLogging() 42 | { 43 | var logger = new LoggerFactory(); 44 | 45 | logger 46 | .AddConsole(LogLevel.Information) 47 | .InitialiseLoggingForNeuralNetworksLibrary(); 48 | } 49 | 50 | private static void MakeExamplePredictions(NeuralNetwork neuralNetwork) 51 | { 52 | System.Console.WriteLine( 53 | $"PREDICTION (0, 1): {neuralNetwork.PredictionFor(new[] {0.0, 1.0}, ParallelOptionsExtensions.SingleThreadedOptions)[0]}, EXPECTED: 1"); 54 | System.Console.WriteLine( 55 | $"PREDICTION (1, 0): {neuralNetwork.PredictionFor(new[] {1.0, 0.0}, ParallelOptionsExtensions.SingleThreadedOptions)[0]}, EXPECTED: 1"); 56 | System.Console.WriteLine( 57 | $"PREDICTION (0, 0): {neuralNetwork.PredictionFor(new[] {0.0, 0.0}, ParallelOptionsExtensions.SingleThreadedOptions)[0]}, EXPECTED: 0"); 58 | System.Console.WriteLine( 59 | $"PREDICTION (1, 1): {neuralNetwork.PredictionFor(new[] {1.0, 1.0}, ParallelOptionsExtensions.SingleThreadedOptions)[0]}, EXPECTED: 0"); 60 | 61 | if (Debugger.IsAttached) System.Console.ReadLine(); 62 | } 63 | 64 | private static List GetXorTrainingData() 65 | { 66 | var inputs = new[] 67 | { 68 | new[] {0.0, 0.0}, new[] {0.0, 1.0}, new[] {1.0, 0.0}, new[] {1.0, 1.0} 69 | }; 70 | 71 | var outputs = new[] 72 | { 73 | new[] {0.0}, new[] {1.0}, new[] {1.0}, new[] {0.0} 74 | }; 75 | 76 | return inputs.Select((input, i) => TrainingDataSet.For(input, outputs[i])).ToList(); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Activation/ActivationType.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library.Components.Activation 2 | { 3 | public enum ActivationType 4 | { 5 | Sigmoid, 6 | TanH 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Activation/ActivationTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NeuralNetworks.Library.Components.Activation.Functions; 4 | 5 | namespace NeuralNetworks.Library.Components.Activation 6 | { 7 | public static class ActivationTypeExtensions 8 | { 9 | private static readonly IDictionary 10 | ActivationFunctions = new Dictionary 11 | { 12 | {ActivationType.Sigmoid, SigmoidActivationFunction.Create()}, 13 | {ActivationType.TanH, TanHActivationFunction.Create()} 14 | }; 15 | 16 | public static IProvideNeuronActivation ToNeuronActivationProvider( 17 | this ActivationType activationType) 18 | { 19 | ActivationFunctions.TryGetValue(activationType, out var activationFunction); 20 | if (activationFunction == null) 21 | { 22 | throw new NotSupportedException( 23 | $"The activaion type {nameof(activationType)} does not have a corresponding {nameof(IProvideNeuronActivation)} function."); 24 | } 25 | 26 | return activationFunction; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Activation/Functions/IProvideNeuronActivation.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library.Components.Activation.Functions 2 | { 3 | public interface IProvideNeuronActivation 4 | { 5 | double Activate(double x); 6 | double Derivative(double x); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Activation/Functions/SigmoidActivationFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Library.Components.Activation.Functions 4 | { 5 | public sealed class SigmoidActivationFunction : IProvideNeuronActivation 6 | { 7 | private SigmoidActivationFunction() {} 8 | 9 | public double Activate(double x) => 1.0 / (1.0 + Math.Exp(-x)); 10 | 11 | public double Derivative(double x) 12 | { 13 | var activationResult = Activate(x); 14 | return activationResult * (1 - activationResult); 15 | } 16 | 17 | public static SigmoidActivationFunction Create() 18 | => new SigmoidActivationFunction(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Activation/Functions/TanHActivationFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Library.Components.Activation.Functions 4 | { 5 | public sealed class TanHActivationFunction : IProvideNeuronActivation 6 | { 7 | private TanHActivationFunction() {} 8 | 9 | public double Activate(double x) => Math.Tanh(x); 10 | 11 | public double Derivative(double x) => 1 - Math.Pow(Math.Tanh(x), 2); 12 | 13 | public static TanHActivationFunction Create() => 14 | new TanHActivationFunction(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/BiasNeuron.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Components.Activation; 2 | using NeuralNetworks.Library.Components.Activation.Functions; 3 | 4 | namespace NeuralNetworks.Library.Components 5 | { 6 | public sealed class BiasNeuron : Neuron 7 | { 8 | public BiasNeuron( 9 | NeuralNetworkContext context, 10 | IProvideNeuronActivation activationFunction, 11 | double constantOutput) 12 | : base(context, activationFunction) 13 | { 14 | Output = constantOutput; 15 | } 16 | 17 | public override double CalculateOutput() => Output; 18 | 19 | public static BiasNeuron For( 20 | NeuralNetworkContext context, 21 | ActivationType activationType, 22 | double constantOutput) 23 | => new BiasNeuron(context, activationType.ToNeuronActivationProvider(), constantOutput); 24 | } 25 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Layer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Microsoft.Extensions.Logging; 6 | using NeuralNetworks.Library.Logging; 7 | 8 | namespace NeuralNetworks.Library.Components 9 | { 10 | public abstract class Layer: IEnumerable 11 | { 12 | private ILogger Log => LoggerProvider.For(GetType()); 13 | 14 | public List Neurons { get; } 15 | 16 | protected Layer(List neurons) 17 | { 18 | Neurons = neurons; 19 | } 20 | 21 | public IEnumerator GetEnumerator() 22 | { 23 | yield return this; 24 | } 25 | 26 | IEnumerator IEnumerable.GetEnumerator() 27 | { 28 | return GetEnumerator(); 29 | } 30 | } 31 | 32 | public sealed class InputLayer : Layer 33 | { 34 | private readonly List inputNeurons; 35 | 36 | private InputLayer(List inputNeurons, List neuronsIncludingBias) 37 | : base(neuronsIncludingBias) 38 | { 39 | this.inputNeurons = inputNeurons; 40 | } 41 | 42 | public void SetInputLayerOutputs(double[] inputs) 43 | { 44 | ValidateInputs(inputs.Length); 45 | 46 | int i = 0; 47 | inputNeurons.ForEach(a => a.Output = inputs[i++]); 48 | } 49 | 50 | private void ValidateInputs(int inputsLength) 51 | { 52 | if (inputsLength != inputNeurons.Count) 53 | { 54 | throw new ArgumentException( 55 | "Input length must be the same length as the Input Layer Neurons"); 56 | } 57 | } 58 | 59 | public static InputLayer For(List neurons) 60 | => new InputLayer(neurons, neurons); 61 | 62 | public static InputLayer For(List neurons, BiasNeuron biasNeuron) 63 | { 64 | var neuronsIncludingBias = neurons.Append(biasNeuron).ToList(); 65 | return new InputLayer(neurons, neuronsIncludingBias); 66 | } 67 | } 68 | 69 | public sealed class HiddenLayer : Layer 70 | { 71 | public HiddenLayer(List neuronsIncludingBias) 72 | : base(neuronsIncludingBias) 73 | {} 74 | 75 | public static HiddenLayer For(List neurons) 76 | => new HiddenLayer(neurons); 77 | 78 | public static HiddenLayer For(List neurons, BiasNeuron biasNeuron) 79 | { 80 | var neuronsIncludingBias = neurons.Append(biasNeuron).ToList(); 81 | return new HiddenLayer(neuronsIncludingBias); 82 | } 83 | } 84 | 85 | public sealed class OutputLayer : Layer 86 | { 87 | public OutputLayer(List neurons) 88 | : base(neurons) 89 | {} 90 | 91 | public static OutputLayer For(List neurons) 92 | => new OutputLayer(neurons); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Neuron.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NeuralNetworks.Library.Components.Activation; 4 | using NeuralNetworks.Library.Components.Activation.Functions; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Library.Extensions; 7 | 8 | namespace NeuralNetworks.Library.Components 9 | { 10 | public class Neuron 11 | { 12 | private static int currentNeuronId = 1; 13 | private static int NextNeuronId => currentNeuronId++; 14 | 15 | internal int Id { get; set; } = NextNeuronId; 16 | 17 | public IProvideNeuronActivation ActivationFunction { get; } 18 | public List InputSynapses { get; } = new List(); 19 | public List OutputSynapses { get; } = new List(); 20 | 21 | public double ErrorGradient 22 | { 23 | get => roundedErrorGradient; 24 | set => roundedErrorGradient = value.RoundToDecimalPlaces(context.ErrorGradientDecimalPlaces); 25 | } 26 | 27 | public double Output 28 | { 29 | get => roundedOutputValue; 30 | set => roundedOutputValue = value.RoundToDecimalPlaces(context.OutputDecimalPlaces); 31 | } 32 | 33 | public double LatestFedValueFromInputSynapses { get; private set; } 34 | 35 | private double roundedErrorGradient; 36 | private double roundedOutputValue; 37 | private readonly NeuralNetworkContext context; 38 | 39 | protected Neuron(NeuralNetworkContext context, IProvideNeuronActivation activationFunction) 40 | { 41 | this.context = context; 42 | ActivationFunction = activationFunction; 43 | } 44 | 45 | public virtual double CalculateOutput() 46 | { 47 | LatestFedValueFromInputSynapses = InputSynapses.Sum(a => a.Weight * a.InputNeuron.Output); 48 | Output = ActivationFunction.Activate(LatestFedValueFromInputSynapses); 49 | 50 | return Output; 51 | } 52 | 53 | public static Neuron For(NeuralNetworkContext context, ActivationType activationType) 54 | => new Neuron(context, activationType.ToNeuronActivationProvider()); 55 | 56 | public static Neuron For( 57 | NeuralNetworkContext context, 58 | ActivationType activationType, 59 | IProvideRandomNumberGeneration randomNumberGeneration, 60 | List inputNeurons) 61 | { 62 | var neuron = For(context, activationType); 63 | ConnectNeuronWithInputNeurons(context, randomNumberGeneration, inputNeurons, neuron); 64 | return neuron; 65 | } 66 | 67 | private static void ConnectNeuronWithInputNeurons( 68 | NeuralNetworkContext context, 69 | IProvideRandomNumberGeneration randomNumberGeneration, 70 | List inputNeurons, 71 | Neuron neuron) 72 | { 73 | foreach (var inputNeuron in inputNeurons) 74 | { 75 | var synapse = Synapse.For(context, inputNeuron, neuron, randomNumberGeneration); 76 | inputNeuron.OutputSynapses.Add(synapse); 77 | neuron.InputSynapses.Add(synapse); 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Components/Synapse.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.NetworkInitialisation; 2 | using NeuralNetworks.Library.Extensions; 3 | 4 | namespace NeuralNetworks.Library.Components 5 | { 6 | public sealed class Synapse 7 | { 8 | public Neuron InputNeuron { get; } 9 | public Neuron OutputNeuron { get; } 10 | 11 | public double Weight 12 | { 13 | get => roundedWeight; 14 | set => roundedWeight = value.RoundToDecimalPlaces(context.SynapseWeightDecimalPlaces); 15 | } 16 | 17 | public double WeightDelta { get; set; } 18 | 19 | private double roundedWeight; 20 | private readonly NeuralNetworkContext context; 21 | 22 | private Synapse(NeuralNetworkContext context, Neuron inputNeuron, Neuron outputNeuron, double weight) 23 | { 24 | this.context = context; 25 | InputNeuron = inputNeuron; 26 | OutputNeuron = outputNeuron; 27 | Weight = weight; 28 | } 29 | 30 | public static Synapse For( 31 | NeuralNetworkContext context, 32 | Neuron inputNeuron, 33 | Neuron outputNeuron, 34 | IProvideRandomNumberGeneration randomNumberGenerator) 35 | => new Synapse(context, inputNeuron, outputNeuron, randomNumberGenerator.GetNextRandomNumber()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Data/TrainingDataSet.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library.Data 2 | { 3 | public sealed class TrainingDataSet 4 | { 5 | public double[] Inputs { get; } 6 | public double[] Outputs { get; } 7 | 8 | private TrainingDataSet(double[] inputs, double[] outputs) 9 | { 10 | Inputs = inputs; 11 | Outputs = outputs; 12 | } 13 | 14 | public static TrainingDataSet For(double[] inputs, double[] outputs) 15 | => new TrainingDataSet(inputs, outputs); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Extensions/DoubleExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Library.Extensions 4 | { 5 | public static class DoubleExtensions 6 | { 7 | public static double RoundToDecimalPlaces(this double source, int decimalPlaces) 8 | { 9 | return Math.Round(source, decimalPlaces); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace NeuralNetworks.Library.Extensions 8 | { 9 | public static class EnumerableExtensions 10 | { 11 | public static void ApplyInReverse( 12 | this IList source, 13 | Action action) 14 | { 15 | var sourceCount = source.Count; 16 | for (var i = sourceCount - 1; i >= 0; i--) 17 | { 18 | action.Invoke(source[i]); 19 | } 20 | } 21 | 22 | public static void ParallelForEach( 23 | this IList source, 24 | Action action, 25 | ParallelOptions parallelOptions) 26 | { 27 | Parallel.For( 28 | fromInclusive: 0, 29 | toExclusive: source.Count, 30 | parallelOptions: parallelOptions, 31 | body: (index, loopState) => 32 | { 33 | var entity = source[index]; 34 | action.Invoke(entity, index); 35 | }); 36 | } 37 | 38 | public static void ParallelForEach( 39 | this IEnumerable source, 40 | Action action, 41 | ParallelOptions parallelOptions) 42 | { 43 | Parallel.ForEach( 44 | source, 45 | parallelOptions, 46 | action); 47 | } 48 | 49 | public static IEnumerable ParallelZip( 50 | this IList source, 51 | IList target, 52 | Func zipFunc, 53 | ParallelOptions parallelOptions) 54 | { 55 | var zippedList = new List(); 56 | var lockObject = new object(); 57 | 58 | Parallel.For( 59 | fromInclusive: 0, 60 | toExclusive: source.Count, 61 | parallelOptions: parallelOptions, 62 | body: (index, loopState) => { 63 | var zipResult = zipFunc(source[index], target[index]); 64 | lock(lockObject) { 65 | zippedList.Add(zipResult); 66 | } 67 | } 68 | ); 69 | 70 | return zippedList; 71 | } 72 | 73 | public static double ParallelSum( 74 | this IEnumerable source, 75 | ParallelOptions parallelOptions) 76 | { 77 | var sum = 0.0; 78 | var lockObject = new object(); 79 | 80 | Parallel.ForEach( 81 | source, 82 | () => 0.0, 83 | (input, loopState, partialResult) => input + partialResult, 84 | localPartialSum => { 85 | lock (lockObject) sum += localPartialSum; 86 | } 87 | ); 88 | 89 | return sum; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Extensions/ParallelOptionsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace NeuralNetworks.Library.Extensions 4 | { 5 | public static class ParallelOptionsExtensions 6 | { 7 | public static ParallelOptions SingleThreadedOptions => 8 | new ParallelOptions { 9 | MaxDegreeOfParallelism = 1 10 | }; 11 | 12 | public static ParallelOptions UnrestrictedMultiThreadedOptions => 13 | new ParallelOptions(); 14 | 15 | 16 | public static ParallelOptions MultiThreadedOptions(int maxNumberOfThreads) => 17 | new ParallelOptions { 18 | MaxDegreeOfParallelism = maxNumberOfThreads 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Extensions/TrainingDataSetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NeuralNetworks.Library.Data; 4 | 5 | namespace NeuralNetworks.Library.Extensions 6 | { 7 | public static class TrainingDataSetExtensions 8 | { 9 | public static IEnumerable BuildTrainingDataForAllInputs( 10 | IEnumerable inputs, 11 | IEnumerable outputs) 12 | { 13 | return inputs.Zip(outputs, (input, output) => TrainingDataSet.For(input, output)); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Logging/LoggerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Logging; 3 | 4 | namespace NeuralNetworks.Library.Logging 5 | { 6 | public static class LoggerProvider 7 | { 8 | private static ILogger Log => Logger.CreateLogger(typeof(LoggerFactory)); 9 | private static ILoggerFactory Logger { get; set; } = new LoggerFactory(); 10 | 11 | internal static ILogger For() => Logger.CreateLogger(); 12 | internal static ILogger For(Type type) => Logger.CreateLogger(type); 13 | 14 | public static ILoggerFactory InitialiseLoggingForNeuralNetworksLibrary(this ILoggerFactory factory) 15 | { 16 | Logger = factory; 17 | Log.LogDebug("Configured logging for the Neural Networks library"); 18 | return Logger; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Logging/LoggingHelperExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library.Logging 2 | { 3 | public static class LoggingHelperExtensions 4 | { 5 | internal static string LogArray(this TEntity[] entityArray) 6 | { 7 | return "[" + string.Join(",", entityArray) + "]"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/NetworkInitialisation/IProvideRandomNumberGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library.NetworkInitialisation 2 | { 3 | public interface IProvideRandomNumberGeneration 4 | { 5 | double GetNextRandomNumber(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/NetworkInitialisation/RandomNumberProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace NeuralNetworks.Library.NetworkInitialisation 4 | { 5 | public sealed class RandomNumberProvider : IProvideRandomNumberGeneration 6 | { 7 | private readonly Random randomNumberGenerator; 8 | 9 | private RandomNumberProvider(Random randomGenerator) 10 | { 11 | randomNumberGenerator = randomGenerator; 12 | } 13 | 14 | public double GetNextRandomNumber() => randomNumberGenerator.NextDouble(); 15 | 16 | public static RandomNumberProvider For(Random randomGenerator) => 17 | new RandomNumberProvider(randomGenerator); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/NeuralNetwork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using NeuralNetworks.Library.Components; 6 | using NeuralNetworks.Library.Extensions; 7 | using NeuralNetworks.Library.NetworkInitialisation; 8 | 9 | namespace NeuralNetworks.Library 10 | { 11 | public sealed class NeuralNetwork 12 | { 13 | public InputLayer InputLayer { get; private set; } 14 | public List HiddenLayers { get; private set; } 15 | public OutputLayer OutputLayer { get; private set; } 16 | 17 | public NeuralNetworkContext Context { get; } 18 | 19 | internal NeuralNetwork(NeuralNetworkContext context) 20 | { 21 | Context = context; 22 | } 23 | 24 | internal NeuralNetwork AddInputLayer(InputLayer inputLayer) 25 | { 26 | InputLayer = inputLayer; 27 | return this; 28 | } 29 | 30 | internal NeuralNetwork AddHiddenLayers(List hiddenLayers) 31 | { 32 | HiddenLayers = hiddenLayers; 33 | return this; 34 | } 35 | 36 | internal NeuralNetwork AddOutputLayer(OutputLayer outputLayer) 37 | { 38 | OutputLayer = outputLayer; 39 | return this; 40 | } 41 | 42 | public double[] PredictionFor(double[] inputs, ParallelOptions parallelOptions) 43 | { 44 | InputLayer.SetInputLayerOutputs(inputs); 45 | HiddenLayers.ForEach(layer => layer.Neurons.ParallelForEach(a => a.CalculateOutput(), parallelOptions)); 46 | return OutputLayer.Neurons.Select(a => a.CalculateOutput()).ToArray(); 47 | } 48 | 49 | public static NeuralNetworkBuilder For( 50 | NeuralNetworkContext context, 51 | IProvideRandomNumberGeneration randomNumberGenerater = null) 52 | { 53 | randomNumberGenerater = randomNumberGenerater ?? RandomNumberProvider.For(new Random(1)); 54 | return new NeuralNetworkBuilder(context, randomNumberGenerater); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/NeuralNetworkBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NeuralNetworks.Library.Components; 4 | using NeuralNetworks.Library.Components.Activation; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Library.Validation; 7 | 8 | namespace NeuralNetworks.Library 9 | { 10 | public sealed class NeuralNetworkBuilder 11 | { 12 | private InputLayer inputLayer; 13 | private readonly List hiddenLayers = new List(); 14 | private OutputLayer outputLayer; 15 | 16 | private Layer PreviousLayer => hiddenLayers.Any() ? (Layer)hiddenLayers.Last() : inputLayer; 17 | 18 | private readonly NeuralNetworkContext context; 19 | private readonly IProvideRandomNumberGeneration randomNumberGenerator; 20 | 21 | public NeuralNetworkBuilder(NeuralNetworkContext context, IProvideRandomNumberGeneration randomNumberGenerator) 22 | { 23 | this.context = context; 24 | this.randomNumberGenerator = randomNumberGenerator; 25 | } 26 | 27 | public NeuralNetworkBuilder WithInputLayer(int neuronCount, ActivationType activationType, double biasOutput = 1) 28 | { 29 | var neurons = new List(); 30 | 31 | for (var i = 0; i < neuronCount; i++) 32 | { 33 | neurons.Add(Neuron.For(context, activationType)); 34 | } 35 | 36 | inputLayer = InputLayer.For(neurons, BiasNeuron.For(context, activationType, biasOutput)); 37 | return this; 38 | } 39 | 40 | public NeuralNetworkBuilder WithHiddenLayer(int neuronCount, ActivationType activationType, double biasOutput = 1) 41 | { 42 | var neurons = new List(); 43 | 44 | for (var i = 0; i < neuronCount; i++) 45 | { 46 | neurons.Add(Neuron.For( 47 | context, 48 | activationType, 49 | randomNumberGenerator, 50 | PreviousLayer.Neurons)); 51 | } 52 | 53 | hiddenLayers.Add(HiddenLayer.For(neurons, BiasNeuron.For(context, activationType, biasOutput))); 54 | return this; 55 | } 56 | 57 | public NeuralNetworkBuilder WithOutputLayer(int neuronCount, ActivationType activationType) 58 | { 59 | var neurons = new List(); 60 | 61 | for (var i = 0; i < neuronCount; i++) 62 | { 63 | neurons.Add(Neuron.For( 64 | context, 65 | activationType, 66 | randomNumberGenerator, 67 | PreviousLayer.Neurons)); 68 | } 69 | 70 | outputLayer = OutputLayer.For(neurons); 71 | 72 | return this; 73 | } 74 | 75 | public NeuralNetwork Build() 76 | { 77 | ValidateSpecifiedConfiguration(); 78 | return BuildNetwork(); 79 | } 80 | 81 | private void ValidateSpecifiedConfiguration() 82 | { 83 | NullableValidators.ValidateNotNull(inputLayer); 84 | NullableValidators.ValidateNotNull(outputLayer); 85 | } 86 | 87 | private NeuralNetwork BuildNetwork() 88 | { 89 | return new NeuralNetwork(context) 90 | .AddInputLayer(inputLayer) 91 | .AddHiddenLayers(hiddenLayers) 92 | .AddOutputLayer(outputLayer); 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/NeuralNetworkContext.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Library 2 | { 3 | public sealed class NeuralNetworkContext 4 | { 5 | public int ErrorGradientDecimalPlaces { get; } 6 | public int OutputDecimalPlaces { get; } 7 | public int SynapseWeightDecimalPlaces { get; } 8 | 9 | public NeuralNetworkContext( 10 | int errorGradientDecimalPlaces = 15, 11 | int outputDecimalPlaces = 15, 12 | int synapseWeightDecimalPlaces = 15) 13 | { 14 | ErrorGradientDecimalPlaces = errorGradientDecimalPlaces; 15 | OutputDecimalPlaces = outputDecimalPlaces; 16 | SynapseWeightDecimalPlaces = synapseWeightDecimalPlaces; 17 | } 18 | 19 | public static NeuralNetworkContext MaximumPrecision => new NeuralNetworkContext(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/NeuralNetworks.Library.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | false 6 | GuardianDevelopment.NeuralNetworks.Library 7 | 2.0.0.0 8 | GuardianDevelopment 9 | GuardianDevelopment 10 | https://github.com/Guardian-Development/NeuralNetworksLibrary 11 | A Neural Networks Library for netstandard2.0 and dotnet core. 12 | Neural Networks Library 13 | A Neural Networks Library for netstandard2.0 and dotnet core. 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("NeuralNetworks.Tests.IntegrationTests")] 4 | [assembly: InternalsVisibleTo("NeuralNetworks.Tests.Support")] 5 | [assembly: InternalsVisibleTo("NeuralNetworks.Tests.UnitTests")] 6 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/BackPropagation/BackPropagation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NeuralNetworks.Library.Data; 4 | using NeuralNetworks.Library.Extensions; 5 | using NeuralNetworks.Library.Components; 6 | using System.Threading.Tasks; 7 | 8 | namespace NeuralNetworks.Library.Training.BackPropagation 9 | { 10 | public sealed class BackPropagation : NeuralNetworkTrainer 11 | { 12 | private readonly NeuralNetwork neuralNetwork; 13 | private readonly NeuronErrorGradientCalculator neuronErrorGradientCalculator; 14 | private readonly SynapseWeightCalculator synapseWeightCalculator; 15 | private readonly ParallelOptions parallelOptions; 16 | 17 | private BackPropagation( 18 | NeuralNetwork neuralNetwork, 19 | NeuronErrorGradientCalculator neuronErrorGradientCalculator, 20 | SynapseWeightCalculator synapseWeightCalculator, 21 | ParallelOptions parallelOptions) 22 | : base(neuralNetwork) 23 | { 24 | this.neuralNetwork = neuralNetwork; 25 | this.neuronErrorGradientCalculator = neuronErrorGradientCalculator; 26 | this.synapseWeightCalculator = synapseWeightCalculator; 27 | this.parallelOptions = parallelOptions; 28 | } 29 | 30 | public override double PerformSingleEpochProducingErrorRate(TrainingDataSet trainingDataSet) 31 | { 32 | neuralNetwork.PredictionFor(trainingDataSet.Inputs, parallelOptions); 33 | return BackPropagate(trainingDataSet.Outputs); 34 | } 35 | 36 | private double BackPropagate(params double[] targets) 37 | { 38 | SetNeuronErrorGradients(targets); 39 | PropagateResultOfNeuronErrors(); 40 | return CalculateError(targets); 41 | } 42 | 43 | private void SetNeuronErrorGradients(double[] targets) 44 | { 45 | neuralNetwork.OutputLayer.Neurons 46 | .ParallelForEach((neuron, i) => 47 | neuronErrorGradientCalculator.SetNeuronErrorGradient(neuron, targets[i]), 48 | parallelOptions); 49 | 50 | neuralNetwork.HiddenLayers 51 | .ApplyInReverse(layer => 52 | layer.Neurons.ParallelForEach( 53 | neuron => neuronErrorGradientCalculator.SetNeuronErrorGradient(neuron), 54 | parallelOptions)); 55 | } 56 | 57 | private void PropagateResultOfNeuronErrors() 58 | { 59 | neuralNetwork.OutputLayer.Neurons 60 | .Where(NeuronNotProducingCorrectResult) 61 | .ParallelForEach( 62 | neuron => synapseWeightCalculator.CalculateAndUpdateInputSynapseWeights(neuron, parallelOptions), 63 | parallelOptions); 64 | 65 | neuralNetwork.HiddenLayers 66 | .ParallelForEach(layer => 67 | layer.Neurons 68 | .Where(NeuronNotProducingCorrectResult) 69 | .ParallelForEach( 70 | neuron => synapseWeightCalculator.CalculateAndUpdateInputSynapseWeights(neuron, parallelOptions), 71 | parallelOptions), 72 | parallelOptions); 73 | } 74 | 75 | private bool NeuronNotProducingCorrectResult(Neuron neuron) 76 | => neuron.ErrorGradient != 0; 77 | 78 | private double CalculateError(params double[] targets) 79 | { 80 | return neuralNetwork.OutputLayer.Neurons 81 | .ParallelZip( 82 | targets, 83 | (neuron, target) => Math.Abs(neuronErrorGradientCalculator.CalculateErrorForOutputAgainstTarget(neuron, target)), 84 | parallelOptions) 85 | .ParallelSum(parallelOptions); 86 | } 87 | 88 | public static BackPropagation WithConfiguration( 89 | NeuralNetwork network, 90 | ParallelOptions parallelOptions, 91 | double learningRate = 1, 92 | double momentum = 0) 93 | { 94 | return new BackPropagation( 95 | network, 96 | NeuronErrorGradientCalculator.Create(), 97 | SynapseWeightCalculator.For(learningRate, momentum), 98 | parallelOptions 99 | ); 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/BackPropagation/NeuronErrorGradientCalculator.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NeuralNetworks.Library.Components; 3 | 4 | namespace NeuralNetworks.Library.Training.BackPropagation 5 | { 6 | public sealed class NeuronErrorGradientCalculator 7 | { 8 | private NeuronErrorGradientCalculator() 9 | {} 10 | 11 | public void SetNeuronErrorGradient(Neuron neuron, double target) 12 | { 13 | neuron.ErrorGradient = CalculateErrorForOutputAgainstTarget(neuron, target) * 14 | neuron.ActivationFunction.Derivative(neuron.LatestFedValueFromInputSynapses); 15 | } 16 | 17 | public void SetNeuronErrorGradient(Neuron neuron) 18 | { 19 | neuron.ErrorGradient = neuron.OutputSynapses.Sum(a => a.OutputNeuron.ErrorGradient * a.Weight) * 20 | neuron.ActivationFunction.Derivative(neuron.LatestFedValueFromInputSynapses); 21 | } 22 | 23 | public double CalculateErrorForOutputAgainstTarget(Neuron neuron, double target) 24 | => target - neuron.Output; 25 | 26 | public static NeuronErrorGradientCalculator Create() 27 | => new NeuronErrorGradientCalculator(); 28 | } 29 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/BackPropagation/SynapseWeightCalculator.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using NeuralNetworks.Library.Components; 3 | using NeuralNetworks.Library.Extensions; 4 | 5 | namespace NeuralNetworks.Library.Training.BackPropagation 6 | { 7 | public sealed class SynapseWeightCalculator 8 | { 9 | private readonly double learningRate; 10 | private readonly double momentum; 11 | 12 | private SynapseWeightCalculator(double learningRate, double momentum) 13 | { 14 | this.learningRate = learningRate; 15 | this.momentum = momentum; 16 | } 17 | 18 | public void CalculateAndUpdateInputSynapseWeights(Neuron neuron, ParallelOptions parallelOptions) 19 | => neuron.InputSynapses.ParallelForEach( 20 | synapse => UpdateSynapseWeight(synapse), 21 | parallelOptions); 22 | 23 | private void UpdateSynapseWeight(Synapse synapse) 24 | { 25 | var prevDelta = synapse.WeightDelta; 26 | synapse.WeightDelta = learningRate * (synapse.OutputNeuron.ErrorGradient * synapse.InputNeuron.Output); 27 | synapse.Weight = synapse.Weight + synapse.WeightDelta + (momentum * prevDelta); 28 | } 29 | 30 | public static SynapseWeightCalculator For(double learningRate, double momentum) 31 | => new SynapseWeightCalculator(learningRate, momentum); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/ITrainNeuralNetworks.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Data; 2 | 3 | namespace NeuralNetworks.Library.Training 4 | { 5 | public interface ITrainNeuralNetworks 6 | { 7 | double PerformSingleEpochProducingErrorRate(TrainingDataSet trainingDataSet); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/NeuralNetworkTrainer.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Data; 2 | 3 | namespace NeuralNetworks.Library.Training 4 | { 5 | public abstract class NeuralNetworkTrainer : ITrainNeuralNetworks 6 | { 7 | public NeuralNetwork NetworkUnderTraining { get; } 8 | 9 | protected NeuralNetworkTrainer(NeuralNetwork neuralNetworkUnderTraining) 10 | { 11 | NetworkUnderTraining = neuralNetworkUnderTraining; 12 | } 13 | 14 | public abstract double PerformSingleEpochProducingErrorRate(TrainingDataSet trainingDataSet); 15 | } 16 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Training/TrainingController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Logging; 6 | using NeuralNetworks.Library.Data; 7 | using NeuralNetworks.Library.Logging; 8 | 9 | namespace NeuralNetworks.Library.Training 10 | { 11 | public sealed class TrainingController 12 | where TNeuralNetworkTrainer : ITrainNeuralNetworks 13 | { 14 | private static ILogger Log => LoggerProvider.For>(); 15 | private readonly TNeuralNetworkTrainer neuralNetworkTrainer; 16 | 17 | internal TrainingController(TNeuralNetworkTrainer neuralNetworkTrainer) 18 | { 19 | this.neuralNetworkTrainer = neuralNetworkTrainer; 20 | } 21 | 22 | public async Task TrainForEpochsOrErrorThresholdMet( 23 | IList trainingDataSet, 24 | int maximumEpochs, 25 | double errorThreshold, 26 | CancellationToken cancellationToken = default(CancellationToken)) 27 | { 28 | await Task.Run(() => { 29 | var error = 1.0; 30 | var numEpochs = 0; 31 | 32 | while (error > errorThreshold && numEpochs < maximumEpochs) 33 | { 34 | var errors = trainingDataSet 35 | .Select(neuralNetworkTrainer.PerformSingleEpochProducingErrorRate) 36 | .ToList(); 37 | 38 | error = errors.Average(); 39 | Log.LogDebug($"Error Rate: {error}. Epoch: {numEpochs}"); 40 | 41 | numEpochs++; 42 | } 43 | }, cancellationToken); 44 | } 45 | 46 | public async Task TrainForEpochs( 47 | IList trainingDataSet, 48 | int maximumEpochs, 49 | CancellationToken cancellationToken = default(CancellationToken)) 50 | { 51 | await Task.Run(() => { 52 | var numEpochs = 0; 53 | 54 | while (numEpochs < maximumEpochs) 55 | { 56 | foreach (var dataSet in trainingDataSet) 57 | { 58 | neuralNetworkTrainer.PerformSingleEpochProducingErrorRate(dataSet); 59 | } 60 | 61 | Log.LogDebug($"Epochs performed: {numEpochs}"); 62 | 63 | numEpochs++; 64 | } 65 | }, cancellationToken); 66 | } 67 | 68 | public async Task TrainForErrorThreshold( 69 | IList trainingDataSet, 70 | double minimumErrorThreshold, 71 | CancellationToken cancellationToken = default(CancellationToken)) 72 | { 73 | await Task.Run(() => { 74 | var error = minimumErrorThreshold + 1; 75 | 76 | while (error > minimumErrorThreshold) 77 | { 78 | var errors = trainingDataSet 79 | .Select(neuralNetworkTrainer.PerformSingleEpochProducingErrorRate) 80 | .ToList(); 81 | 82 | error = errors.Average(); 83 | Log.LogDebug($"Current Error Rate: {error}"); 84 | } 85 | }, cancellationToken); 86 | } 87 | } 88 | 89 | public static class TrainingController 90 | { 91 | public static TrainingController For(TNeuralNetworkTrainer trainer) 92 | where TNeuralNetworkTrainer : ITrainNeuralNetworks 93 | { 94 | return new TrainingController(trainer); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /NeuralNetworks.Library/Validation/NullableValidators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace NeuralNetworks.Library.Validation 5 | { 6 | internal static class NullableValidators 7 | { 8 | internal static void ValidateNotNull(TEntity entity, [CallerMemberName] string callerName = null) 9 | { 10 | if (entity == null) 11 | { 12 | throw new InvalidOperationException( 13 | $"{typeof(TEntity).Name} must be set before calling {callerName}"); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/Assertors/AssertorPatternTest.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library; 2 | using NeuralNetworks.Library.Components.Activation; 3 | using NeuralNetworks.Tests.Support; 4 | using NeuralNetworks.Tests.Support.Assertors; 5 | using NeuralNetworks.Tests.Support.Builders; 6 | using Xunit; 7 | 8 | namespace NeuralNetworks.Tests.IntegrationTests.Assertors 9 | { 10 | public class AssertorPatternTest 11 | { 12 | [Fact] 13 | public void CanAssertNeuralNetworkSuccess() 14 | { 15 | var neuralNetwork = ExplicitNeuralNetworkBuilder 16 | .CreateForTest(NeuralNetworkContext.MaximumPrecision, PredictableRandomNumberGenerator.Create()) 17 | .InputLayer(l => l.Neurons( 18 | n => n.Id(1).ErrorGradient(1).Output(1).Activation(ActivationType.Sigmoid), 19 | n => n.Id(2).ErrorGradient(1).Output(1).Activation(ActivationType.Sigmoid))) 20 | .HiddenLayer(l => l.Neurons( 21 | n => n.Id(3).ErrorGradient(2).Output(2).Activation(ActivationType.Sigmoid), 22 | n => n.Id(4).ErrorGradient(2).Output(2).Activation(ActivationType.Sigmoid))) 23 | .OutputLayer(l => l.Neurons( 24 | n => n.Id(5).ErrorGradient(3).Output(3).Activation(ActivationType.Sigmoid), 25 | n => n.Id(6).ErrorGradient(3).Output(3).Activation(ActivationType.Sigmoid))) 26 | .Synapses( 27 | s => s.SynapseBetween(inputNeuronId: 1, outputNeuronId: 3, weight: 1), 28 | s => s.SynapseBetween(inputNeuronId: 1, outputNeuronId: 4, weight: 1), 29 | s => s.SynapseBetween(inputNeuronId: 2, outputNeuronId: 3, weight: 1), 30 | s => s.SynapseBetween(inputNeuronId: 2, outputNeuronId: 4, weight: 1), 31 | s => s.SynapseBetween(inputNeuronId: 3, outputNeuronId: 5, weight: 2), 32 | s => s.SynapseBetween(inputNeuronId: 3, outputNeuronId: 6, weight: 2), 33 | s => s.SynapseBetween(inputNeuronId: 4, outputNeuronId: 5, weight: 2), 34 | s => s.SynapseBetween(inputNeuronId: 4, outputNeuronId: 6, weight: 2)) 35 | .Build(); 36 | 37 | 38 | var neuralNetworkAssertor = new NeuralNetworkAssertor.Builder() 39 | .InputLayer(l => l.Neurons( 40 | n => n.Id(1).Output(1).ErrorGradient(1).OutputSynapses( 41 | s => s.OutputNeuronId(3).Weight(1), 42 | s => s.OutputNeuronId(4).Weight(1)), 43 | n => n.Id(2).Output(1).ErrorGradient(1).OutputSynapses( 44 | s => s.OutputNeuronId(3).Weight(1), 45 | s => s.OutputNeuronId(4).Weight(1)))) 46 | .HiddenLayers(l => l.Neurons( 47 | n => n 48 | .Id(3).Output(2).ErrorGradient(2) 49 | .InputSynapses( 50 | s => s.InputNeuronId(1).Weight(1), 51 | s => s.InputNeuronId(2).Weight(1)) 52 | .OutputSynapses( 53 | s => s.OutputNeuronId(5).Weight(2), 54 | s => s.OutputNeuronId(6).Weight(2)), 55 | n => n 56 | .Id(4).Output(2).ErrorGradient(2) 57 | .InputSynapses( 58 | s => s.InputNeuronId(1).Weight(1), 59 | s => s.InputNeuronId(2).Weight(1)) 60 | .OutputSynapses( 61 | s => s.OutputNeuronId(5).Weight(2), 62 | s => s.OutputNeuronId(6).Weight(2)))) 63 | .OutputLayer(l => l.Neurons( 64 | n => n.Id(5).Output(3).ErrorGradient(3).InputSynapses( 65 | s => s.InputNeuronId(3).Weight(2), 66 | s => s.InputNeuronId(4).Weight(2)), 67 | n => n.Id(6).Output(3).ErrorGradient(3).InputSynapses( 68 | s => s.InputNeuronId(3).Weight(2), 69 | s => s.InputNeuronId(4).Weight(2)))) 70 | .Build(); 71 | 72 | neuralNetworkAssertor.Assert(neuralNetwork); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/DatasetCaseStudies/IrisDataSetCaseStudy/IrisDataRow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NeuralNetworks.Library.Data; 5 | 6 | namespace NeuralNetworks.Tests.IntegrationTests.DatasetCaseStudies.IrisDatasetCaseStudy 7 | { 8 | public sealed class IrisDataRow 9 | { 10 | private IrisDataRow( 11 | int id, 12 | double sepalLengthCm, 13 | double sepalWithCm, 14 | double petalLengthCm, 15 | double petalWithCm, 16 | double species) 17 | { 18 | Id = id; 19 | SepalLengthCm = sepalLengthCm; 20 | SepalWidthCm = sepalWithCm; 21 | PetalLengthCm = petalLengthCm; 22 | PetalWidthCm = petalWithCm; 23 | Species = species; 24 | } 25 | 26 | public int Id { get; } 27 | public double SepalLengthCm { get; } 28 | public double SepalWidthCm { get; } 29 | public double PetalLengthCm { get; } 30 | public double PetalWidthCm { get; } 31 | public double Species { get; } 32 | 33 | public double[] PredictionDataPoints => 34 | new [] { SepalLengthCm, SepalWidthCm, PetalLengthCm, PetalWidthCm }; 35 | 36 | public override bool Equals(object obj) 37 | { 38 | var objAsIrisDataRow = obj as IrisDataRow; 39 | if(objAsIrisDataRow == null) 40 | { 41 | return false; 42 | } 43 | 44 | return Equals(objAsIrisDataRow); 45 | } 46 | 47 | public bool Equals(IrisDataRow row) 48 | { 49 | return this.Id == row.Id; 50 | } 51 | 52 | public override int GetHashCode() 53 | { 54 | return Id; 55 | } 56 | 57 | public static TrainingDataSet TrainingDataFromRow(IrisDataRow row) 58 | { 59 | var species = Enumerable.Repeat(0.0, 3).ToArray(); 60 | species[Convert.ToInt32(row.Species) - 1] = 1.0; 61 | 62 | return TrainingDataSet.For( 63 | row.PredictionDataPoints, 64 | species.ToArray()); 65 | } 66 | 67 | public static IrisDataRow For( 68 | int id, 69 | double sepalLengthCm, 70 | double sepalWithCm, 71 | double petalLengthCm, 72 | double petalWithCm, 73 | double species) 74 | { 75 | return new IrisDataRow(id, sepalLengthCm, sepalWithCm, petalLengthCm, petalWithCm, species); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/DatasetCaseStudies/IrisDataSetCaseStudy/IrisDataRowNormaliser.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace NeuralNetworks.Tests.IntegrationTests.DatasetCaseStudies.IrisDatasetCaseStudy 4 | { 5 | public static class IrisDataRowNormaliser 6 | { 7 | private static double MinSepalLengthCm => 8 | IrisDataSet.AllRows 9 | .Select(row => row.SepalLengthCm) 10 | .Min(); 11 | 12 | private static double MaxSepalLengthCm => 13 | IrisDataSet.AllRows 14 | .Select(row => row.SepalLengthCm) 15 | .Max(); 16 | 17 | private static double MinSepalWidthCm => 18 | IrisDataSet.AllRows 19 | .Select(row => row.SepalWidthCm) 20 | .Min(); 21 | 22 | private static double MaxSepalWidthCm => 23 | IrisDataSet.AllRows 24 | .Select(row => row.SepalWidthCm) 25 | .Max(); 26 | 27 | private static double MinPetalLengthCm => 28 | IrisDataSet.AllRows 29 | .Select(row => row.PetalLengthCm) 30 | .Min(); 31 | 32 | private static double MaxPetalLengthCm => 33 | IrisDataSet.AllRows 34 | .Select(row => row.PetalLengthCm) 35 | .Max(); 36 | 37 | private static double MinPetalWidthCm => 38 | IrisDataSet.AllRows 39 | .Select(row => row.PetalWidthCm) 40 | .Min(); 41 | 42 | private static double MaxPetalWidthCm => 43 | IrisDataSet.AllRows 44 | .Select(row => row.PetalWidthCm) 45 | .Max(); 46 | 47 | 48 | public static IrisDataRow NormaliseDataRow(IrisDataRow row) 49 | { 50 | return IrisDataRow.For( 51 | row.Id, 52 | row.SepalLengthCm.NormaliseValue(MinSepalLengthCm, MaxSepalLengthCm), 53 | row.SepalWidthCm.NormaliseValue(MinSepalWidthCm, MaxSepalWidthCm), 54 | row.PetalLengthCm.NormaliseValue(MinPetalLengthCm, MaxPetalLengthCm), 55 | row.PetalWidthCm.NormaliseValue(MinPetalWidthCm, MaxPetalWidthCm), 56 | row.Species); 57 | } 58 | 59 | private static double NormaliseValue(this double value, double min, double max) 60 | { 61 | return (value - min) / (max - min); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/DatasetCaseStudies/IrisDataSetCaseStudy/IrisDataSetCaseStudy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components.Activation; 6 | using NeuralNetworks.Library.Extensions; 7 | using NeuralNetworks.Library.Training; 8 | using NeuralNetworks.Library.Training.BackPropagation; 9 | using NeuralNetworks.Tests.Support; 10 | using Xunit; 11 | using static System.FormattableString; 12 | 13 | namespace NeuralNetworks.Tests.IntegrationTests.DatasetCaseStudies.IrisDatasetCaseStudy 14 | { 15 | public sealed class IrisDatasetCaseStudy : NeuralNetworkTest 16 | { 17 | [Fact] 18 | public async void CanSuccessfullySolveIrisProblemTrainingForEpochsOrErrorThresholdMet() 19 | { 20 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 21 | .WithInputLayer(neuronCount: 4, activationType: ActivationType.Sigmoid) 22 | .WithHiddenLayer(neuronCount: 8, activationType: ActivationType.Sigmoid) 23 | .WithHiddenLayer(neuronCount: 5, activationType: ActivationType.Sigmoid) 24 | .WithOutputLayer(neuronCount: 3, activationType: ActivationType.TanH) 25 | .Build(); 26 | 27 | await TrainingController 28 | .For(BackPropagation.WithConfiguration( 29 | neuralNetwork, 30 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 31 | learningRate: 1.15, 32 | momentum: 0.4)) 33 | .TrainForEpochsOrErrorThresholdMet(IrisDataSet.TrainingData, maximumEpochs: 1500, errorThreshold: 0.01); 34 | 35 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 36 | } 37 | 38 | [Fact] 39 | public async void CanSuccessfullySolveIrisProblemTrainingForEpochs() 40 | { 41 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 42 | .WithInputLayer(neuronCount: 4, activationType: ActivationType.Sigmoid) 43 | .WithHiddenLayer(neuronCount: 8, activationType: ActivationType.Sigmoid) 44 | .WithHiddenLayer(neuronCount: 5, activationType: ActivationType.Sigmoid) 45 | .WithOutputLayer(neuronCount: 3, activationType: ActivationType.TanH) 46 | .Build(); 47 | 48 | await TrainingController 49 | .For(BackPropagation.WithConfiguration( 50 | neuralNetwork, 51 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 52 | learningRate: 1.15, 53 | momentum: 0.4)) 54 | .TrainForEpochs(IrisDataSet.TrainingData, maximumEpochs: 1000); 55 | 56 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 57 | } 58 | 59 | [Fact] 60 | public async void CanSuccessfullySolveXorProblemTrainingForErrorThreshold() 61 | { 62 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 63 | .WithInputLayer(neuronCount: 4, activationType: ActivationType.Sigmoid) 64 | .WithHiddenLayer(neuronCount: 8, activationType: ActivationType.Sigmoid) 65 | .WithHiddenLayer(neuronCount: 5, activationType: ActivationType.Sigmoid) 66 | .WithOutputLayer(neuronCount: 3, activationType: ActivationType.TanH) 67 | .Build(); 68 | 69 | await TrainingController 70 | .For(BackPropagation.WithConfiguration( 71 | neuralNetwork, 72 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 73 | learningRate: 1.15, 74 | momentum: 0.4)) 75 | .TrainForErrorThreshold(IrisDataSet.TrainingData, minimumErrorThreshold: 0.08); 76 | 77 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 78 | } 79 | 80 | private void AssertPredictionsForTrainedNeuralNetwork(NeuralNetwork neuralNetwork) 81 | { 82 | var predictedCorrectly = new List(); 83 | var predictedIncorrectly = new List(); 84 | 85 | IrisDataSet.RowsToBeUsedForPredictions.ForEach(row => 86 | { 87 | var predictions = neuralNetwork.PredictionFor( 88 | row.PredictionDataPoints, 89 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions); 90 | 91 | var prediction = Array.IndexOf(predictions, predictions.Max()) + 1; 92 | 93 | if(prediction == row.Species) 94 | { 95 | predictedCorrectly.Add(row); 96 | } 97 | else 98 | { 99 | predictedIncorrectly.Add(row); 100 | } 101 | }); 102 | 103 | Assert.True(predictedIncorrectly.Count == 0, 104 | Invariant($"Predicted Incorrectly Count: {predictedIncorrectly.Count}. Predicted Correctly Count: {predictedCorrectly.Count}")); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/DatasetCaseStudies/XorDatasetCaseStudy/XorDatasetCaseStudy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components.Activation; 6 | using NeuralNetworks.Library.Data; 7 | using NeuralNetworks.Library.Extensions; 8 | using NeuralNetworks.Library.Training; 9 | using NeuralNetworks.Library.Training.BackPropagation; 10 | using NeuralNetworks.Tests.Support; 11 | using Xunit; 12 | 13 | namespace NeuralNetworks.Tests.IntegrationTests.DatasetCaseStudies.XorDatasetCaseStudy 14 | { 15 | public sealed class XorDatasetCaseStudy : NeuralNetworkTest 16 | { 17 | 18 | [Fact] 19 | public async void CanSuccessfullySolveXorProblemTrainingForEpochsOrErrorThresholdMet() 20 | { 21 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 22 | .WithInputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 23 | .WithHiddenLayer(neuronCount: 2, activationType: ActivationType.TanH) 24 | .WithOutputLayer(neuronCount: 1, activationType: ActivationType.Sigmoid) 25 | .Build(); 26 | 27 | await TrainingController 28 | .For(BackPropagation.WithConfiguration( 29 | neuralNetwork, 30 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 31 | learningRate: 0.4, 32 | momentum: 0.9)) 33 | .TrainForEpochsOrErrorThresholdMet(XorTrainingData(), maximumEpochs: 3000, errorThreshold: 0.01); 34 | 35 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 36 | } 37 | 38 | [Fact] 39 | public async void CanSuccessfullySolveXorProblemTrainingForEpochs() 40 | { 41 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 42 | .WithInputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 43 | .WithHiddenLayer(neuronCount: 2, activationType: ActivationType.TanH) 44 | .WithOutputLayer(neuronCount: 1, activationType: ActivationType.Sigmoid) 45 | .Build(); 46 | 47 | await TrainingController 48 | .For(BackPropagation.WithConfiguration( 49 | neuralNetwork, 50 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 51 | learningRate: 0.4, 52 | momentum: 0.9)) 53 | .TrainForEpochs(XorTrainingData(), maximumEpochs: 5000); 54 | 55 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 56 | } 57 | 58 | [Fact] 59 | public async void CanSuccessfullySolveXorProblemTrainingForErrorThreshold() 60 | { 61 | var neuralNetwork = NeuralNetwork.For(NeuralNetworkContext.MaximumPrecision) 62 | .WithInputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 63 | .WithHiddenLayer(neuronCount: 2, activationType: ActivationType.TanH) 64 | .WithOutputLayer(neuronCount: 1, activationType: ActivationType.Sigmoid) 65 | .Build(); 66 | 67 | await TrainingController 68 | .For(BackPropagation.WithConfiguration( 69 | neuralNetwork, 70 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions, 71 | learningRate: 0.4, 72 | momentum: 0.9)) 73 | .TrainForErrorThreshold(XorTrainingData(), minimumErrorThreshold: 0.01); 74 | 75 | AssertPredictionsForTrainedNeuralNetwork(neuralNetwork); 76 | } 77 | 78 | private void AssertPredictionsForTrainedNeuralNetwork(NeuralNetwork neuralNetwork) 79 | { 80 | Assert.True(neuralNetwork.PredictionFor(new [] { 0.0, 1.0 }, 81 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions)[0] >= 0.5, 82 | "Prediction incorrect for (0, 1)"); 83 | Assert.True(neuralNetwork.PredictionFor(new [] { 1.0, 0.0 }, 84 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions)[0] >= 0.5, 85 | "Prediction incorrect for (1, 0)"); 86 | Assert.True(neuralNetwork.PredictionFor(new[] { 0.0, 0.0 }, 87 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions)[0] < 0.5, 88 | "Prediction incorrect for (0, 0)"); 89 | Assert.True(neuralNetwork.PredictionFor(new[] { 1.0, 1.0 }, 90 | ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions)[0] < 0.5, 91 | "Prediction incorrect for (1, 1)"); 92 | } 93 | 94 | private static List XorTrainingData() 95 | { 96 | var inputs = new[] 97 | { 98 | new[] {0.0, 0.0}, new[] {0.0, 1.0}, new[] {1.0, 0.0}, new[] {1.0, 1.0} 99 | }; 100 | 101 | var outputs = new[] 102 | { 103 | new[] {0.0}, new[] {1.0}, new[] {1.0}, new[] {0.0} 104 | }; 105 | 106 | return TrainingDataSetExtensions.BuildTrainingDataForAllInputs(inputs, outputs).ToList(); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/NetworkPredictions/NeuralNetworkPredictionsTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Tests.Support; 7 | using NeuralNetworks.Tests.Support.Assertors; 8 | using NeuralNetworks.Tests.Support.Builders; 9 | 10 | namespace NeuralNetworks.Tests.IntegrationTests.NetworkPredictions 11 | { 12 | public sealed class NeuralNetworkPredictionsTester : NeuralNetworkTester 13 | { 14 | private NeuralNetworkPredictionsTester() 15 | {} 16 | 17 | public NeuralNetworkPredictionsTester InputAndExpectOutput( 18 | double[] inputs, 19 | double[] expectedOutput, 20 | ParallelOptions parallelOptions) 21 | { 22 | var expectedOutputAssertor = ExpectedOutputAssertorFor(expectedOutput); 23 | var networkOutput = targetNeuralNetwork.PredictionFor(inputs, parallelOptions); 24 | expectedOutputAssertor.Assert(networkOutput); 25 | 26 | return this; 27 | } 28 | 29 | private IAssert ExpectedOutputAssertorFor(double[] expectedOutput) 30 | { 31 | var expectedOutputAssertor = new OrderedListAssertor(); 32 | foreach (var output in expectedOutput) 33 | { 34 | var assertor = new EqualityAssertor(output); 35 | expectedOutputAssertor.Assertors.Add(assertor); 36 | } 37 | return expectedOutputAssertor; 38 | } 39 | 40 | public static NeuralNetworkPredictionsTester Create() 41 | => new NeuralNetworkPredictionsTester(); 42 | } 43 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/NeuralNetworks.Tests.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/Training/BackPropagationTests/BackPropagationTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Library.Training.BackPropagation; 7 | using NeuralNetworks.Tests.Support; 8 | using NeuralNetworks.Tests.Support.Builders; 9 | 10 | namespace NeuralNetworks.Tests.IntegrationTests.Training.BackPropagationTests 11 | { 12 | public sealed class BackPropagationTester : NeuralNetworkTester 13 | { 14 | private readonly double learningRate; 15 | private readonly double momentum; 16 | 17 | private readonly List> trainingStates 18 | = new List>(); 19 | 20 | private BackPropagationTester(double learningRate, double momentum) 21 | { 22 | this.momentum = momentum; 23 | this.learningRate = learningRate; 24 | } 25 | 26 | public BackPropagationTester QueueTrainingEpoch( 27 | Action> action, 28 | ParallelOptions parallelOptions) 29 | { 30 | var backPropagationTrainer = BackPropagation.WithConfiguration(targetNeuralNetwork, parallelOptions, learningRate, momentum); 31 | var epochTester = TrainingEpochTester.For(backPropagationTrainer); 32 | action.Invoke(epochTester); 33 | 34 | trainingStates.Add(epochTester); 35 | return this; 36 | } 37 | 38 | public void PerformAllEpochs() 39 | { 40 | trainingStates.ForEach(state => state.PerformEpochAndAssert()); 41 | } 42 | 43 | public static BackPropagationTester For(double learningRate,double momentum) 44 | => new BackPropagationTester(learningRate, momentum); 45 | } 46 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/Training/BackPropagationTests/ErrorRateCalculationTests/BackPropagationErrorRateTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NeuralNetworks.Library; 4 | using NeuralNetworks.Library.Components; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Library.Training.BackPropagation; 7 | using NeuralNetworks.Tests.Support; 8 | using NeuralNetworks.Tests.Support.Assertors; 9 | using NeuralNetworks.Tests.Support.Builders; 10 | using Xunit; 11 | 12 | namespace NeuralNetworks.Tests.IntegrationTests.Training.BackPropagationTests.ErrorGradientCalculationsTests 13 | { 14 | public sealed class BackPropagationErrorGradientTester : NeuralNetworkTester 15 | { 16 | 17 | private BackPropagationErrorGradientTester() 18 | {} 19 | 20 | public BackPropagationErrorGradientTester ActivateNeuronWithId(int neuronId) 21 | { 22 | var targetNeuron = FindNeuronWithId(neuronId); 23 | targetNeuron.CalculateOutput(); 24 | return this; 25 | } 26 | 27 | public void CalculateErrorGradientForHiddenLayerNeuron(int neuronId, double errorGradient) 28 | { 29 | PerformErrorGradientCalculation( 30 | neuronId, 31 | errorGradient, 32 | (neuron, calculator) => calculator.SetNeuronErrorGradient(neuron)); 33 | } 34 | 35 | public void CalculateErrorGradientForOutputLayerNeuron(int neuronId, double expectedOutput, double errorGradient) 36 | { 37 | PerformErrorGradientCalculation( 38 | neuronId, 39 | errorGradient, 40 | (neuron, calculator) => calculator.SetNeuronErrorGradient(neuron, expectedOutput)); 41 | } 42 | 43 | private void PerformErrorGradientCalculation( 44 | int neuronId, 45 | double errorGradient, 46 | Action errorGradientCalculation) 47 | { 48 | var expectedErrorGradientAssertor = new EqualityAssertor(errorGradient); 49 | var errorCalculator = NeuronErrorGradientCalculator.Create(); 50 | var targetNeuron = FindNeuronWithId(neuronId); 51 | 52 | errorGradientCalculation(targetNeuron, errorCalculator); 53 | expectedErrorGradientAssertor.Assert(targetNeuron.ErrorGradient); 54 | } 55 | 56 | public static BackPropagationErrorGradientTester Create() 57 | => new BackPropagationErrorGradientTester(); 58 | } 59 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/Training/BackPropagationTests/SynapseWeightUpdateTests/BackPropagationSynapseWeightUpdateTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components; 6 | using NeuralNetworks.Library.NetworkInitialisation; 7 | using NeuralNetworks.Library.Training.BackPropagation; 8 | using NeuralNetworks.Tests.Support; 9 | using NeuralNetworks.Tests.Support.Assertors; 10 | using NeuralNetworks.Tests.Support.Builders; 11 | using NeuralNetworks.Tests.Support.Helpers; 12 | using Xunit; 13 | 14 | namespace NeuralNetworks.Tests.IntegrationTests.Training.BackPropagationTests.SynapseWeightUpdateTests 15 | { 16 | public sealed class BackPropagationSynapseWeightUpdateTester : NeuralNetworkTester 17 | { 18 | private static ParallelOptions UnrestrictedThreading = new ParallelOptions(); 19 | private readonly SynapseWeightCalculator synapseWeightCalculator; 20 | 21 | private BackPropagationSynapseWeightUpdateTester(double learningRate, double momentum) 22 | { 23 | synapseWeightCalculator = SynapseWeightCalculator.For(learningRate, momentum); 24 | } 25 | 26 | public void UpdateSynapseExpectingWeight( 27 | int synapseInputNeuronId, 28 | int synapseOutputNeuronId, 29 | double expectedWeightDelta, 30 | double expectedWeight) 31 | { 32 | var neuron = FindNeuronWithId(synapseOutputNeuronId); 33 | var synapse = FindSynapseFor(neuron, synapseInputNeuronId); 34 | synapseWeightCalculator.CalculateAndUpdateInputSynapseWeights(neuron, UnrestrictedThreading); 35 | 36 | var synapseAssertor = new SynapseAssertor.Builder() 37 | .InputNeuronId(synapseInputNeuronId) 38 | .OutputNeuronId(synapseOutputNeuronId) 39 | .Weight(expectedWeight) 40 | .WeightDelta( 41 | expectedWeightDelta, 42 | precisionToAssertTo: targetNeuralNetwork.Context.SynapseWeightDecimalPlaces) 43 | .Build(); 44 | 45 | synapseAssertor.Assert(synapse); 46 | } 47 | 48 | private Synapse FindSynapseFor(Neuron neuron, int synapseInputNeuronId) 49 | { 50 | var synapse = neuron.InputSynapses.First(s => s.InputNeuron.Id == synapseInputNeuronId); 51 | Assert.NotNull(synapse); 52 | return synapse; 53 | } 54 | 55 | public static BackPropagationSynapseWeightUpdateTester Create(double learningRate, double momentum) 56 | => new BackPropagationSynapseWeightUpdateTester(learningRate, momentum); 57 | } 58 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.IntegrationTests/Training/BackPropagationTests/TrainingEpochTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NeuralNetworks.Library; 3 | using NeuralNetworks.Library.Data; 4 | using NeuralNetworks.Library.NetworkInitialisation; 5 | using NeuralNetworks.Library.Training; 6 | using NeuralNetworks.Tests.Support.Assertors; 7 | 8 | namespace NeuralNetworks.Tests.IntegrationTests.Training.BackPropagationTests 9 | { 10 | public sealed class TrainingEpochTester 11 | where TTrainingMethod : NeuralNetworkTrainer 12 | { 13 | private double[] inputs; 14 | private double[] outputs; 15 | private double errorRate; 16 | private IAssert neuralNetworkAssertor; 17 | private readonly TTrainingMethod trainingMethod; 18 | 19 | private TrainingEpochTester(TTrainingMethod trainingMethod) 20 | { 21 | this.trainingMethod = trainingMethod; 22 | } 23 | 24 | public TrainingEpochTester Inputs(params double[] inputs) 25 | { 26 | this.inputs = inputs; 27 | return this; 28 | } 29 | 30 | public TrainingEpochTester ExpectedOutputs(params double[] outputs) 31 | { 32 | this.outputs = outputs; 33 | return this; 34 | } 35 | 36 | public TrainingEpochTester ErrorRate(double errorRate) 37 | { 38 | this.errorRate = errorRate; 39 | return this; 40 | } 41 | 42 | public TrainingEpochTester ExpectNeuralNetworkState(Action action) 43 | { 44 | var builder = new NeuralNetworkAssertor.Builder(); 45 | action.Invoke(builder); 46 | neuralNetworkAssertor = builder.Build(); 47 | return this; 48 | } 49 | 50 | public void PerformEpochAndAssert() 51 | { 52 | var trainingData = TrainingDataSet.For(inputs, outputs); 53 | var errorRate = trainingMethod.PerformSingleEpochProducingErrorRate(trainingData); 54 | AssertResultOfTrainingEpoch(errorRate); 55 | } 56 | 57 | private void AssertResultOfTrainingEpoch(double actualErrorRate) 58 | { 59 | neuralNetworkAssertor.Assert(trainingMethod.NetworkUnderTraining); 60 | 61 | var doubleAssertor = new RoundedDoubleAssertor( 62 | errorRate, 63 | trainingMethod.NetworkUnderTraining.Context.ErrorGradientDecimalPlaces); 64 | 65 | doubleAssertor.Assert(actualErrorRate); 66 | } 67 | 68 | public static TrainingEpochTester For(TTrainingMethod trainingMethod) 69 | => new TrainingEpochTester(trainingMethod); 70 | } 71 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.PerformanceTests/BackPropagationPerformanceTestContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using BenchmarkDotNet.Attributes; 4 | using BenchmarkDotNet.Attributes.Exporters; 5 | using BenchmarkDotNet.Attributes.Jobs; 6 | using BenchmarkDotNet.Engines; 7 | using NeuralNetworks.Library; 8 | using NeuralNetworks.Library.Components.Activation; 9 | using NeuralNetworks.Library.Data; 10 | using NeuralNetworks.Library.Extensions; 11 | using NeuralNetworks.Library.Training; 12 | using NeuralNetworks.Library.Training.BackPropagation; 13 | 14 | namespace NeuralNetworks.Tests.PerformanceTests 15 | { 16 | [MarkdownExporter] 17 | [SimpleJob(RunStrategy.Monitoring, launchCount: 10, warmupCount: 5, targetCount: 20)] 18 | public class BackPropagationPerformanceComparisonContainer 19 | { 20 | private readonly TrainingController singleThreadedController; 21 | private readonly TrainingController multiThreadedController; 22 | private readonly IList trainingData; 23 | 24 | public BackPropagationPerformanceComparisonContainer() 25 | { 26 | var neuralNetworkUnderTest = 27 | NeuralNetwork 28 | .For(NeuralNetworkContext.MaximumPrecision) 29 | .WithInputLayer(neuronCount: 5, activationType: ActivationType.Sigmoid) 30 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.Sigmoid) 31 | .WithHiddenLayer(neuronCount: 70, activationType: ActivationType.TanH) 32 | .WithHiddenLayer(neuronCount: 40, activationType: ActivationType.TanH) 33 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.Sigmoid) 34 | .WithOutputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 35 | .Build(); 36 | 37 | trainingData = new[] { 38 | TrainingDataSet.For(new [] {0.78, 0.99, 0.67, 0.72, 0.22}, new [] { 0.12, 0.14 })}; 39 | 40 | multiThreadedController = TrainingController.For( 41 | BackPropagation 42 | .WithConfiguration(neuralNetworkUnderTest, ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions)); 43 | 44 | singleThreadedController = TrainingController.For( 45 | BackPropagation 46 | .WithConfiguration(neuralNetworkUnderTest, ParallelOptionsExtensions.SingleThreadedOptions)); 47 | } 48 | 49 | [Benchmark] 50 | public void BackPropagationTrainingMultiThreadedFiveThousandEpochs() 51 | => multiThreadedController.TrainForEpochs(trainingData, maximumEpochs: 5000).GetAwaiter().GetResult(); 52 | 53 | [Benchmark] 54 | public void BackPropagationTrainingSingleThreadedFiveThousandEpochs() 55 | => singleThreadedController.TrainForEpochs(trainingData, maximumEpochs: 5000).GetAwaiter().GetResult(); 56 | } 57 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.PerformanceTests/FeedForwardPerformanceTestContainer.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Attributes.Exporters; 3 | using BenchmarkDotNet.Attributes.Jobs; 4 | using BenchmarkDotNet.Engines; 5 | using NeuralNetworks.Library; 6 | using NeuralNetworks.Library.Components.Activation; 7 | using NeuralNetworks.Library.Extensions; 8 | 9 | namespace NeuralNetworks.Tests.PerformanceTests 10 | { 11 | [MarkdownExporter] 12 | [SimpleJob(RunStrategy.Monitoring, launchCount: 10, warmupCount: 5, targetCount: 20)] 13 | public class FeedForwardPerformanceComparisonContainer 14 | { 15 | private readonly NeuralNetwork neuralNetworkUnderTest; 16 | 17 | public FeedForwardPerformanceComparisonContainer() 18 | { 19 | neuralNetworkUnderTest = 20 | NeuralNetwork 21 | .For(NeuralNetworkContext.MaximumPrecision) 22 | .WithInputLayer(neuronCount: 5, activationType: ActivationType.Sigmoid) 23 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.Sigmoid) 24 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.TanH) 25 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.TanH) 26 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.Sigmoid) 27 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.TanH) 28 | .WithHiddenLayer(neuronCount: 100, activationType: ActivationType.Sigmoid) 29 | .WithOutputLayer(neuronCount: 2, activationType: ActivationType.Sigmoid) 30 | .Build(); 31 | } 32 | 33 | private double[] InputValues => new [] { 0.98, 0.23, 0.44, 0.44, 0.12 }; 34 | 35 | [Benchmark] 36 | public double[] FeedForwardPredictionSingleThreaded() => 37 | neuralNetworkUnderTest.PredictionFor(InputValues, ParallelOptionsExtensions.SingleThreadedOptions); 38 | 39 | [Benchmark] 40 | public double[] FeedForwardPredictionMultiThreaded() => 41 | neuralNetworkUnderTest.PredictionFor(InputValues, ParallelOptionsExtensions.UnrestrictedMultiThreadedOptions); 42 | } 43 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.PerformanceTests/NeuralNetworks.Tests.PerformanceTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.PerformanceTests/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BenchmarkDotNet.Attributes; 3 | using BenchmarkDotNet.Running; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components.Activation; 6 | using NeuralNetworks.Library.Extensions; 7 | 8 | namespace NeuralNetworks.Tests.PerformanceTests 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | BenchmarkRunner.Run(typeof(FeedForwardPerformanceComparisonContainer)); 15 | BenchmarkRunner.Run(typeof(BackPropagationPerformanceComparisonContainer)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.PerformanceTests/README.md: -------------------------------------------------------------------------------- 1 | # Latest Performance Benchmarks 2 | 3 | ``` ini 4 | 5 | BenchmarkDotNet=v0.10.9, OS=Mac OS X 10.12 6 | Processor=Intel Core i5-4278U CPU 2.60GHz (Haswell), ProcessorCount=4 7 | .NET Core SDK=2.0.0 8 | [Host] : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT 9 | DefaultJob : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT 10 | 11 | 12 | ``` 13 | | Method | Mean | Error | StdDev | Median | 14 | |-------------------------------------------------------- |--------:|---------:|---------:|--------:| 15 | | BackPropagationTrainingMultiThreadedFiveThousandEpochs | 2.982 s | 0.0590 s | 0.1522 s | 2.913 s | 16 | | BackPropagationTrainingSingleThreadedFiveThousandEpochs | 3.037 s | 0.0028 s | 0.0026 s | 3.037 s | 17 | 18 | 19 | ``` ini 20 | 21 | BenchmarkDotNet=v0.10.9, OS=Mac OS X 10.12 22 | Processor=Intel Core i5-4278U CPU 2.60GHz (Haswell), ProcessorCount=4 23 | .NET Core SDK=2.0.0 24 | [Host] : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT 25 | Job-JYVQDG : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT 26 | 27 | LaunchCount=10 RunStrategy=Monitoring TargetCount=20 28 | WarmupCount=5 29 | 30 | ``` 31 | | Method | Mean | Error | StdDev | Median | 32 | |------------------------------------ |---------:|----------:|----------:|---------:| 33 | | FeedForwardPredictionSingleThreaded | 1.697 ms | 0.1621 ms | 0.6863 ms | 1.393 ms | 34 | | FeedForwardPredictionMultiThreaded | 1.335 ms | 0.1795 ms | 0.7600 ms | 1.146 ms | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/EqualityAssertor.cs: -------------------------------------------------------------------------------- 1 | using static System.FormattableString; 2 | 3 | namespace NeuralNetworks.Tests.Support.Assertors 4 | { 5 | public class EqualityAssertor : IAssert 6 | { 7 | private readonly T expectedResult; 8 | 9 | public EqualityAssertor(T expectedResult) 10 | { 11 | this.expectedResult = expectedResult; 12 | } 13 | 14 | public void Assert(T actualItem) 15 | { 16 | Xunit.Assert.True( 17 | expectedResult.Equals(actualItem), 18 | Invariant($"Expected: {expectedResult} but Received: {actualItem}")); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/FieldAssertor.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Tests.Support.Assertors 2 | { 3 | public class FieldAssertor : IAssert 4 | { 5 | public static FieldAssertor NoAssert => new FieldAssertor(); 6 | 7 | private readonly IAssert assertor; 8 | 9 | public FieldAssertor(IAssert assertor) 10 | { 11 | this.assertor = assertor; 12 | } 13 | 14 | public FieldAssertor() 15 | {} 16 | 17 | public void Assert(T actualItem) 18 | { 19 | assertor?.Assert(actualItem); 20 | } 21 | 22 | public static FieldAssertor Create(IAssert assertor) 23 | => new FieldAssertor(assertor); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/IAssert.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Tests.Support.Assertors 2 | { 3 | public interface IAssert 4 | { 5 | void Assert(T actualItem); 6 | } 7 | 8 | public interface IAssertBuilder 9 | { 10 | IAssert Build(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/LayerAssertor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NeuralNetworks.Library.Components; 4 | 5 | namespace NeuralNetworks.Tests.Support.Assertors 6 | { 7 | public class LayerAssertor : IAssert 8 | where TLayer : Layer 9 | { 10 | public List NeuronIds = new List(); 11 | 12 | public IAssert> NeuronAssertors { get; set; } 13 | = FieldAssertor>.NoAssert; 14 | 15 | public void Assert(TLayer actualItem) 16 | { 17 | NeuronAssertors.Assert(actualItem.Neurons); 18 | } 19 | 20 | public class Builder : IAssertBuilder 21 | { 22 | private readonly LayerAssertor assertor = new LayerAssertor(); 23 | 24 | public Builder Neurons(params Action[] neuronAssertors) 25 | { 26 | var listAssertor = ListAssertorFor(neuronAssertors); 27 | assertor.NeuronAssertors = listAssertor; 28 | return this; 29 | } 30 | 31 | public IAssert Build() => assertor; 32 | 33 | private UnorderedListAssertor ListAssertorFor( 34 | Action[] neuronAssertors) 35 | { 36 | var listAssertor = new UnorderedListAssertor(GetKeyForAssertor); 37 | PopulateListAssertor(neuronAssertors, listAssertor); 38 | return listAssertor; 39 | } 40 | 41 | private static int GetKeyForAssertor(Neuron neuronToAssert) 42 | => neuronToAssert.Id; 43 | 44 | private void PopulateListAssertor( 45 | Action[] neuronAssertors, 46 | UnorderedListAssertor listAssertor) 47 | { 48 | foreach (var produceAssertor in neuronAssertors) 49 | { 50 | var builder = new NeuronAssertor.Builder(); 51 | produceAssertor(builder); 52 | 53 | var neuronAssertor = builder.Build() as NeuronAssertor; 54 | assertor.NeuronIds.Add(neuronAssertor.NeuronId); 55 | 56 | listAssertor.Assertors.Add(neuronAssertor.NeuronId, neuronAssertor); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/NeuralNetworkAssertor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NeuralNetworks.Library; 4 | using NeuralNetworks.Library.Components; 5 | using System.Linq; 6 | 7 | namespace NeuralNetworks.Tests.Support.Assertors 8 | { 9 | public class NeuralNetworkAssertor : IAssert 10 | { 11 | public IAssert InputLayerAssertor { get; set; } 12 | = FieldAssertor.NoAssert; 13 | 14 | public IAssert> HiddenLayersAssertor { get; set; } 15 | = FieldAssertor>.NoAssert; 16 | 17 | public IAssert OutputLayerAssertor { get; set; } 18 | = FieldAssertor.NoAssert; 19 | 20 | public void Assert(NeuralNetwork actualItem) 21 | { 22 | InputLayerAssertor.Assert(actualItem.InputLayer); 23 | HiddenLayersAssertor.Assert(actualItem.HiddenLayers); 24 | OutputLayerAssertor.Assert(actualItem.OutputLayer); 25 | } 26 | 27 | public class Builder : IAssertBuilder 28 | { 29 | private readonly NeuralNetworkAssertor assertor = new NeuralNetworkAssertor(); 30 | 31 | public Builder InputLayer(Action.Builder> actions) 32 | { 33 | var layerAssertor = new LayerAssertor.Builder(); 34 | actions.Invoke(layerAssertor); 35 | assertor.InputLayerAssertor = layerAssertor.Build(); 36 | return this; 37 | } 38 | 39 | public Builder HiddenLayers(params Action.Builder>[] actions) 40 | { 41 | var listAssertor = ListAssertorFor(actions); 42 | assertor.HiddenLayersAssertor = listAssertor; 43 | return this; 44 | } 45 | 46 | public Builder OutputLayer(Action.Builder> actions) 47 | { 48 | var layerAssertor = new LayerAssertor.Builder(); 49 | actions.Invoke(layerAssertor); 50 | assertor.OutputLayerAssertor = layerAssertor.Build(); 51 | return this; 52 | } 53 | 54 | public IAssert Build() => assertor; 55 | 56 | private static UnorderedListAssertor ListAssertorFor( 57 | Action.Builder>[] synapseAssertors) 58 | { 59 | var listAssertor = new UnorderedListAssertor(GetKeyForAssertor); 60 | PopulateListAssertor(synapseAssertors, listAssertor); 61 | return listAssertor; 62 | } 63 | 64 | private static string GetKeyForAssertor(HiddenLayer layerToAssert) 65 | => CreateSynapseKey(layerToAssert.Neurons.Select(l => l.Id).ToArray()); 66 | 67 | private static string CreateSynapseKey(int[] neuronIds) 68 | => string.Join(",", neuronIds); 69 | 70 | private static void PopulateListAssertor( 71 | Action.Builder>[] synapseAssertors, 72 | UnorderedListAssertor listAssertor) 73 | { 74 | foreach (var produceAssertor in synapseAssertors) 75 | { 76 | var builder = new LayerAssertor.Builder(); 77 | produceAssertor(builder); 78 | 79 | var layerAssertor = builder.Build() as LayerAssertor; 80 | 81 | listAssertor.Assertors.Add( 82 | CreateSynapseKey(layerAssertor.NeuronIds.ToArray()), 83 | layerAssertor); 84 | } 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/NeuronAssertor.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Components; 2 | using NeuralNetworks.Library.Components.Activation.Functions; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | namespace NeuralNetworks.Tests.Support.Assertors 7 | { 8 | public class NeuronAssertor : IAssert 9 | { 10 | public int NeuronId { get; private set; } 11 | 12 | public IAssert NeuronIdAssertor { get; set; } 13 | = FieldAssertor.NoAssert; 14 | 15 | public IAssert ActivationFunctionAssertor { get; set; } 16 | = FieldAssertor.NoAssert; 17 | 18 | public IAssert> InputSynapsesAssertor { get; set; } 19 | = FieldAssertor>.NoAssert; 20 | 21 | public IAssert> OutputSynapsesAssertor { get; set; } 22 | = FieldAssertor>.NoAssert; 23 | 24 | public IAssert ErrorGradientAssertor { get; set; } 25 | = FieldAssertor.NoAssert; 26 | 27 | public IAssert OutputAssertor { get; set; } 28 | = FieldAssertor.NoAssert; 29 | 30 | public void Assert(Neuron actualItem) 31 | { 32 | NeuronIdAssertor.Assert(actualItem.Id); 33 | 34 | ActivationFunctionAssertor.Assert(actualItem.ActivationFunction); 35 | ErrorGradientAssertor.Assert(actualItem.ErrorGradient); 36 | OutputAssertor.Assert(actualItem.Output); 37 | 38 | InputSynapsesAssertor.Assert(actualItem.InputSynapses); 39 | OutputSynapsesAssertor.Assert(actualItem.OutputSynapses); 40 | } 41 | 42 | public class Builder : IAssertBuilder 43 | { 44 | private readonly NeuronAssertor assertor = new NeuronAssertor(); 45 | 46 | public Builder Id(int id) 47 | { 48 | assertor.NeuronIdAssertor = new EqualityAssertor(id); 49 | assertor.NeuronId = id; 50 | 51 | return this; 52 | } 53 | 54 | public Builder InputSynapses(params Action[] synapseAssertors) 55 | { 56 | var listAssertor = ListAssertorFor(synapseAssertors); 57 | assertor.InputSynapsesAssertor = listAssertor; 58 | return this; 59 | } 60 | 61 | public Builder OutputSynapses(params Action[] synapseAssertors) 62 | { 63 | var listAssertor = ListAssertorFor(synapseAssertors); 64 | assertor.OutputSynapsesAssertor = listAssertor; 65 | return this; 66 | } 67 | 68 | public Builder ErrorGradient(double errorGradient) 69 | { 70 | assertor.ErrorGradientAssertor = new EqualityAssertor(errorGradient); 71 | return this; 72 | } 73 | 74 | public Builder Output(double output) 75 | { 76 | assertor.OutputAssertor = new EqualityAssertor(output); 77 | return this; 78 | } 79 | 80 | public IAssert Build() => assertor; 81 | 82 | private UnorderedListAssertor ListAssertorFor( 83 | Action[] synapseAssertors) 84 | { 85 | var listAssertor = new UnorderedListAssertor(GetKeyForAssertor); 86 | PopulateListAssertor(synapseAssertors, listAssertor); 87 | return listAssertor; 88 | } 89 | 90 | private static string GetKeyForAssertor(Synapse synapseToAssert) 91 | => CreateSynapseKey(synapseToAssert.InputNeuron.Id, synapseToAssert.OutputNeuron.Id); 92 | 93 | private static string CreateSynapseKey(int inputNeuronId, int outputNeuronId) 94 | => $"{inputNeuronId}:{outputNeuronId}"; 95 | 96 | private void PopulateListAssertor( 97 | Action[] synapseAssertors, 98 | UnorderedListAssertor listAssertor) 99 | { 100 | foreach (var produceAssertor in synapseAssertors) 101 | { 102 | var builder = new SynapseAssertor.Builder(); 103 | produceAssertor(builder); 104 | 105 | var synapseAssertor = builder.Build() as SynapseAssertor; 106 | 107 | var inputNeuronId = synapseAssertor.InputNeuronId.HasValue ? 108 | synapseAssertor.InputNeuronId.Value : assertor.NeuronId; 109 | 110 | var outputNeuronId = synapseAssertor.OutputNeuronId.HasValue ? 111 | synapseAssertor.OutputNeuronId.Value : assertor.NeuronId; 112 | 113 | listAssertor.Assertors.Add( 114 | CreateSynapseKey(inputNeuronId, outputNeuronId), 115 | synapseAssertor); 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/OrderedListAssertor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace NeuralNetworks.Tests.Support.Assertors 6 | { 7 | public class OrderedListAssertor : IAssert> 8 | { 9 | public IList> Assertors { get; } = new List>(); 10 | 11 | public OrderedListAssertor() 12 | {} 13 | 14 | public void Assert(IEnumerable actualItem) 15 | { 16 | var actualItemList= actualItem.ToList(); 17 | 18 | for(int i = 0; i < actualItemList.Count; i++) 19 | { 20 | var assertor = Assertors[i]; 21 | var item = actualItemList[i]; 22 | assertor.Assert(item); 23 | } 24 | 25 | Xunit.Assert.True( 26 | Assertors.Count == actualItem.Count(), 27 | $"Expected: {Assertors.Count} Recevied: {actualItem.Count()}"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/RoundedDoubleAssertor.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Tests.Support.Helpers; 2 | 3 | namespace NeuralNetworks.Tests.Support.Assertors 4 | { 5 | public class RoundedDoubleAssertor : IAssert 6 | { 7 | private readonly double expectedResult; 8 | private readonly int precisionToAssertTo; 9 | 10 | public RoundedDoubleAssertor(double expectedResult, int precisionToAssertTo) 11 | { 12 | this.expectedResult = expectedResult; 13 | this.precisionToAssertTo = precisionToAssertTo; 14 | } 15 | 16 | public void Assert(double actualItem) 17 | { 18 | DoubleAssertionHelpers.AssertWithPrecision( 19 | expectedResult, 20 | actualItem, 21 | precisionToAssertTo); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/SynapseAssertor.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Components; 2 | 3 | namespace NeuralNetworks.Tests.Support.Assertors 4 | { 5 | public class SynapseAssertor : IAssert 6 | { 7 | public int? InputNeuronId { get; private set; } 8 | public int? OutputNeuronId { get; private set; } 9 | 10 | public IAssert InputNeuronIdAssertor{ get; set; } 11 | = FieldAssertor.NoAssert; 12 | 13 | public IAssert OutputNeuronIdAssertor { get; set; } 14 | = FieldAssertor.NoAssert; 15 | 16 | public IAssert WeightAssertor { get; set; } 17 | = FieldAssertor.NoAssert; 18 | 19 | public IAssert WeightDeltaAssertor { get; set; } 20 | = FieldAssertor.NoAssert; 21 | 22 | public void Assert(Synapse actualItem) 23 | { 24 | InputNeuronIdAssertor.Assert(actualItem.InputNeuron.Id); 25 | OutputNeuronIdAssertor.Assert(actualItem.OutputNeuron.Id); 26 | 27 | WeightAssertor.Assert(actualItem.Weight); 28 | WeightDeltaAssertor.Assert(actualItem.WeightDelta); 29 | } 30 | 31 | public class Builder : IAssertBuilder 32 | { 33 | private readonly SynapseAssertor assertor = new SynapseAssertor(); 34 | 35 | public Builder InputNeuronId(int id) 36 | { 37 | assertor.InputNeuronIdAssertor = new EqualityAssertor(id); 38 | assertor.InputNeuronId = id; 39 | return this; 40 | } 41 | 42 | public Builder OutputNeuronId(int id) 43 | { 44 | assertor.OutputNeuronIdAssertor = new EqualityAssertor(id); 45 | assertor.OutputNeuronId = id; 46 | return this; 47 | } 48 | 49 | public Builder Weight(double expectedWeight) 50 | { 51 | assertor.WeightAssertor = new EqualityAssertor(expectedWeight); 52 | return this; 53 | } 54 | 55 | public Builder WeightDelta(double expectedWeightDelta, int precisionToAssertTo) 56 | { 57 | assertor.WeightDeltaAssertor = new RoundedDoubleAssertor(expectedWeightDelta, precisionToAssertTo); 58 | return this; 59 | } 60 | 61 | public IAssert Build() => assertor; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Assertors/UnorderedListAssertor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace NeuralNetworks.Tests.Support.Assertors 6 | { 7 | public class UnorderedListAssertor : IAssert> 8 | { 9 | public IDictionary> Assertors { get; } 10 | = new Dictionary>(); 11 | 12 | private readonly Func getKeyForAssertor; 13 | 14 | public UnorderedListAssertor(Func getKeyForAssertor) 15 | { 16 | this.getKeyForAssertor = getKeyForAssertor; 17 | } 18 | 19 | public void Assert(IEnumerable actualItem) 20 | { 21 | actualItem = actualItem.ToList(); 22 | foreach(var item in actualItem) 23 | { 24 | var assertor = AssertorFor(item); 25 | assertor.Assert(item); 26 | } 27 | 28 | Xunit.Assert.True( 29 | Assertors.Count == actualItem.Count(), 30 | $"Expected: {Assertors.Count} Recevied: {actualItem.Count()}"); 31 | } 32 | 33 | private IAssert AssertorFor(T itemToAssert) 34 | { 35 | var keyForAssertor = getKeyForAssertor(itemToAssert); 36 | if(Assertors.TryGetValue(keyForAssertor, out var assertor)) 37 | { 38 | return assertor; 39 | } 40 | 41 | throw new InvalidOperationException( 42 | $"No assertor registered under key : {keyForAssertor} for value: {itemToAssert}"); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Builders/ExplicitNeuralNetworkBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NeuralNetworks.Library; 4 | using NeuralNetworks.Library.Components; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | 7 | namespace NeuralNetworks.Tests.Support.Builders 8 | { 9 | public class ExplicitNeuralNetworkBuilder 10 | { 11 | private readonly IDictionary allNeuronsInNetwork = new Dictionary(); 12 | 13 | private InputLayer inputLayer; 14 | private readonly List hiddenLayers = new List(); 15 | private OutputLayer outputLayer; 16 | 17 | private readonly NeuralNetworkContext context; 18 | private readonly IProvideRandomNumberGeneration randomNumberGenerator; 19 | 20 | private ExplicitNeuralNetworkBuilder( 21 | NeuralNetworkContext context, 22 | IProvideRandomNumberGeneration randomNumberGenerator) 23 | { 24 | this.randomNumberGenerator = randomNumberGenerator; 25 | this.context = context; 26 | } 27 | 28 | public ExplicitNeuralNetworkBuilder InputLayer(Action action) 29 | { 30 | var builder = new InputlayerBuilder(allNeuronsInNetwork, context); 31 | action.Invoke(builder); 32 | 33 | inputLayer = builder.Build(); 34 | return this; 35 | } 36 | 37 | public ExplicitNeuralNetworkBuilder HiddenLayer(Action action) 38 | { 39 | var builder = new HiddenLayerBuilder(allNeuronsInNetwork, context); 40 | action.Invoke(builder); 41 | 42 | hiddenLayers.Add(builder.Build()); 43 | return this; 44 | } 45 | 46 | public ExplicitNeuralNetworkBuilder OutputLayer(Action action) 47 | { 48 | var builder = new OutputLayerBuilder(allNeuronsInNetwork, context); 49 | action.Invoke(builder); 50 | 51 | outputLayer = builder.Build(); 52 | return this; 53 | } 54 | 55 | public ExplicitNeuralNetworkBuilder Synapses(params Action[] actions) 56 | { 57 | foreach(var action in actions) 58 | { 59 | var synapseBuilder = new SynapseBuilder(context, allNeuronsInNetwork, randomNumberGenerator); 60 | action.Invoke(synapseBuilder); 61 | synapseBuilder.Build(); 62 | } 63 | 64 | return this; 65 | } 66 | 67 | public NeuralNetwork Build() 68 | { 69 | return new NeuralNetwork(context) 70 | .AddInputLayer(inputLayer) 71 | .AddHiddenLayers(hiddenLayers) 72 | .AddOutputLayer(outputLayer); 73 | } 74 | 75 | public static ExplicitNeuralNetworkBuilder CreateForTest( 76 | NeuralNetworkContext context, 77 | IProvideRandomNumberGeneration randomNumberGenerator) 78 | => new ExplicitNeuralNetworkBuilder(context, randomNumberGenerator); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Builders/LayerBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using NeuralNetworks.Library; 5 | using NeuralNetworks.Library.Components; 6 | 7 | namespace NeuralNetworks.Tests.Support.Builders 8 | { 9 | public class LayerBuilder 10 | where TLayer : LayerBuilder 11 | { 12 | protected readonly IDictionary AllNeuronsInNetwork; 13 | protected readonly NeuralNetworkContext Context; 14 | 15 | protected IList NeuronsInLayer = new List(); 16 | 17 | public LayerBuilder(IDictionary allNeuronsInNetwork, NeuralNetworkContext context) 18 | { 19 | AllNeuronsInNetwork = allNeuronsInNetwork; 20 | Context = context; 21 | } 22 | 23 | public TLayer Neurons(params Action[] actions) 24 | { 25 | foreach(var action in actions) 26 | { 27 | var neuronBuilder = new NeuronBuilder(Context); 28 | action.Invoke(neuronBuilder); 29 | 30 | var neuron = neuronBuilder.Build(); 31 | 32 | NeuronsInLayer.Add(neuron); 33 | AllNeuronsInNetwork.Add(neuron.Id, neuron); 34 | } 35 | 36 | return (TLayer)this; 37 | } 38 | } 39 | 40 | public sealed class InputlayerBuilder : LayerBuilder 41 | { 42 | private BiasNeuron biasNeuron; 43 | 44 | public InputlayerBuilder(IDictionary allNeuronsInNetwork, NeuralNetworkContext context) 45 | : base(allNeuronsInNetwork, context) 46 | {} 47 | 48 | public InputlayerBuilder Bias(Action action) 49 | { 50 | var neuronBuilder = new BiasNeuronBuilder(Context); 51 | action.Invoke(neuronBuilder); 52 | biasNeuron = neuronBuilder.Build(); 53 | 54 | NeuronsInLayer.Add(biasNeuron); 55 | AllNeuronsInNetwork.Add(biasNeuron.Id, biasNeuron); 56 | 57 | return this; 58 | } 59 | 60 | public InputLayer Build() 61 | { 62 | return biasNeuron == null ? 63 | InputLayer.For(NeuronsInLayer.ToList()) : 64 | InputLayer.For(NeuronsInLayer.ToList(), biasNeuron); 65 | } 66 | } 67 | 68 | public sealed class HiddenLayerBuilder : LayerBuilder 69 | { 70 | private BiasNeuron biasNeuron; 71 | 72 | public HiddenLayerBuilder(IDictionary allNeuronsInNetwork, NeuralNetworkContext context) 73 | : base(allNeuronsInNetwork, context) 74 | {} 75 | 76 | public HiddenLayerBuilder Bias(Action action) 77 | { 78 | var neuronBuilder = new BiasNeuronBuilder(Context); 79 | action.Invoke(neuronBuilder); 80 | biasNeuron = neuronBuilder.Build(); 81 | 82 | NeuronsInLayer.Add(biasNeuron); 83 | AllNeuronsInNetwork.Add(biasNeuron.Id, biasNeuron); 84 | 85 | return this; 86 | } 87 | 88 | public HiddenLayer Build() 89 | { 90 | return biasNeuron == null ? 91 | HiddenLayer.For(NeuronsInLayer.ToList()) : 92 | HiddenLayer.For(NeuronsInLayer.ToList(), biasNeuron); 93 | } 94 | } 95 | 96 | public sealed class OutputLayerBuilder : LayerBuilder 97 | { 98 | public OutputLayerBuilder(IDictionary allNeuronsInNetwork, NeuralNetworkContext context) 99 | : base(allNeuronsInNetwork, context) 100 | {} 101 | 102 | public OutputLayer Build() 103 | => OutputLayer.For(NeuronsInLayer.ToList()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Builders/NeuronBuilder.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library; 2 | using NeuralNetworks.Library.Components; 3 | using NeuralNetworks.Library.Components.Activation; 4 | 5 | namespace NeuralNetworks.Tests.Support.Builders 6 | { 7 | public abstract class AbstractNeuronBuilder 8 | where TBuilder : AbstractNeuronBuilder 9 | where TNeuron : Neuron 10 | { 11 | protected int id; 12 | protected double errorGradient; 13 | protected double output; 14 | protected ActivationType activationType; 15 | 16 | protected readonly NeuralNetworkContext Context; 17 | 18 | protected AbstractNeuronBuilder(NeuralNetworkContext context) 19 | { 20 | Context = context; 21 | } 22 | 23 | public TBuilder Id(int id) 24 | { 25 | this.id = id; 26 | return (TBuilder)this; 27 | } 28 | 29 | public TBuilder ErrorGradient(double errorGradient) 30 | { 31 | this.errorGradient = errorGradient; 32 | return (TBuilder)this; 33 | } 34 | 35 | public TBuilder Output(double output) 36 | { 37 | this.output = output; 38 | return (TBuilder)this; 39 | } 40 | 41 | public TBuilder Activation(ActivationType activationType) 42 | { 43 | this.activationType = activationType; 44 | return (TBuilder)this; 45 | } 46 | 47 | public abstract TNeuron Build(); 48 | } 49 | 50 | public sealed class NeuronBuilder : AbstractNeuronBuilder 51 | { 52 | public NeuronBuilder(NeuralNetworkContext context) 53 | : base(context) 54 | {} 55 | 56 | public override Neuron Build() 57 | { 58 | var neuron = Neuron.For(Context, activationType); 59 | neuron.Id = id; 60 | neuron.Output = output; 61 | neuron.ErrorGradient = errorGradient; 62 | return neuron; 63 | } 64 | } 65 | 66 | public sealed class BiasNeuronBuilder : AbstractNeuronBuilder 67 | { 68 | public BiasNeuronBuilder(NeuralNetworkContext context) 69 | : base(context) 70 | {} 71 | 72 | public override BiasNeuron Build() 73 | { 74 | var neuron = BiasNeuron.For(Context, activationType, output); 75 | neuron.Id = id; 76 | neuron.ErrorGradient = errorGradient; 77 | return neuron; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Builders/SynapseBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NeuralNetworks.Library; 4 | using NeuralNetworks.Library.Components; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | 7 | namespace NeuralNetworks.Tests.Support.Builders 8 | { 9 | public class SynapseBuilder 10 | { 11 | private int inputNeuronId; 12 | private int outputNeuronId; 13 | private double weight; 14 | private double weightDelta; 15 | 16 | private readonly IDictionary allNeuronsInNetwork; 17 | private readonly IProvideRandomNumberGeneration randomGenerator; 18 | private readonly NeuralNetworkContext context; 19 | 20 | public SynapseBuilder( 21 | NeuralNetworkContext context, 22 | IDictionary allNeuronsInNetwork, 23 | IProvideRandomNumberGeneration randomGenerator) 24 | { 25 | this.context = context; 26 | this.randomGenerator = randomGenerator; 27 | this.allNeuronsInNetwork = allNeuronsInNetwork; 28 | } 29 | 30 | public SynapseBuilder SynapseBetween(int inputNeuronId, int outputNeuronId, double weight) 31 | { 32 | this.inputNeuronId = inputNeuronId; 33 | this.outputNeuronId = outputNeuronId; 34 | this.weight = weight; 35 | return this; 36 | } 37 | 38 | public SynapseBuilder WithWeightDelta(double weightDelta) 39 | { 40 | this.weightDelta = weightDelta; 41 | return this; 42 | } 43 | 44 | public Synapse Build() 45 | { 46 | GetNeuronsById(out var inputNeuron, out var outputNeuron); 47 | var synapse = Synapse.For(context, inputNeuron, outputNeuron, randomGenerator); 48 | ConnectNeuronsInSynapse(synapse); 49 | synapse.Weight = weight; 50 | synapse.WeightDelta = weightDelta; 51 | 52 | return synapse; 53 | } 54 | 55 | private void GetNeuronsById(out Neuron inputNeuron, out Neuron outputNeuron) 56 | { 57 | inputNeuron = GetNeuronById(inputNeuronId); 58 | outputNeuron = GetNeuronById(outputNeuronId); 59 | } 60 | 61 | private Neuron GetNeuronById(int id) 62 | { 63 | if(allNeuronsInNetwork.TryGetValue(id, out var neuron)) 64 | { 65 | return neuron; 66 | } 67 | 68 | throw new ArgumentException($"No Neuron exists with id: {id}"); 69 | } 70 | 71 | private void ConnectNeuronsInSynapse(Synapse synapse) 72 | { 73 | synapse.InputNeuron.OutputSynapses.Add(synapse); 74 | synapse.OutputNeuron.InputSynapses.Add(synapse); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/Helpers/DoubleAssertionHelpers.cs: -------------------------------------------------------------------------------- 1 | namespace NeuralNetworks.Tests.Support.Helpers 2 | { 3 | public static class DoubleAssertionHelpers 4 | { 5 | public static void AssertWithPrecision(double expected, double actual, int decimalPlaces) 6 | { 7 | Xunit.Assert.Equal(expected, actual, decimalPlaces); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/NeuralNetworkTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.Logging; 3 | using NeuralNetworks.Library.Logging; 4 | using NeuralNetworks.Library.NetworkInitialisation; 5 | 6 | namespace NeuralNetworks.Tests.Support 7 | { 8 | public class NeuralNetworkTest 9 | { 10 | private LoggerFactory Logger { get; } = new LoggerFactory(); 11 | 12 | protected ILogger LogFor(Type type) => Logger.CreateLogger(type); 13 | 14 | protected IProvideRandomNumberGeneration PredictableGenerator => 15 | PredictableRandomNumberGenerator.Create(); 16 | 17 | protected NeuralNetworkTest() 18 | { 19 | ConfigureLoggingForTest(); 20 | } 21 | 22 | private void ConfigureLoggingForTest() 23 | { 24 | Logger 25 | .AddConsole(LogLevel.Debug) 26 | .InitialiseLoggingForNeuralNetworksLibrary(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/NeuralNetworkTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using NeuralNetworks.Library; 4 | using NeuralNetworks.Library.Components; 5 | using NeuralNetworks.Library.NetworkInitialisation; 6 | using NeuralNetworks.Tests.Support.Builders; 7 | using Xunit; 8 | 9 | namespace NeuralNetworks.Tests.Support 10 | { 11 | public abstract class NeuralNetworkTester 12 | where TTester : NeuralNetworkTester 13 | { 14 | private NeuralNetworkContext context; 15 | private IProvideRandomNumberGeneration randomGenerator; 16 | protected NeuralNetwork targetNeuralNetwork; 17 | 18 | public TTester NeuralNetworkEnvironment( 19 | NeuralNetworkContext context, 20 | IProvideRandomNumberGeneration randomGenerator) 21 | { 22 | this.context = context; 23 | this.randomGenerator = randomGenerator; 24 | return (TTester)this; 25 | } 26 | 27 | public TTester TargetNeuralNetwork(Action action) 28 | { 29 | var neuralNetworkBuilder = ExplicitNeuralNetworkBuilder.CreateForTest(context, randomGenerator); 30 | action.Invoke(neuralNetworkBuilder); 31 | targetNeuralNetwork = neuralNetworkBuilder.Build(); 32 | return (TTester)this; 33 | } 34 | 35 | protected Neuron FindNeuronWithId(int neuronId) 36 | { 37 | var inputlayerNeurons = targetNeuralNetwork.InputLayer.Neurons; 38 | var hiddenLayerNeurons = targetNeuralNetwork.HiddenLayers.SelectMany(l => l.Neurons); 39 | var outputLayerNeurons = targetNeuralNetwork.OutputLayer.Neurons; 40 | 41 | var allNeurons = inputlayerNeurons.Concat(hiddenLayerNeurons).Concat(outputLayerNeurons); 42 | var targetNeuron = allNeurons.Where(n => n.Id == neuronId).First(); 43 | 44 | Assert.NotNull(targetNeuron); 45 | return targetNeuron; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/NeuralNetworks.Tests.Support.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.Support/PredictableRandomNumberGenerator.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.NetworkInitialisation; 2 | 3 | namespace NeuralNetworks.Tests.Support 4 | { 5 | public sealed class PredictableRandomNumberGenerator : IProvideRandomNumberGeneration 6 | { 7 | private PredictableRandomNumberGenerator() 8 | {} 9 | 10 | public double GetNextRandomNumber() => 1.0; 11 | 12 | public static IProvideRandomNumberGeneration Create() 13 | => new PredictableRandomNumberGenerator(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.UnitTests/ActivationFunctionTests/SigmoidActivationFunctionTests.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Components.Activation.Functions; 2 | using NeuralNetworks.Tests.Support.Helpers; 3 | using Xunit; 4 | 5 | namespace NeuralNetworks.Tests.UnitTests.ActivationFunctionTests 6 | { 7 | public sealed class SigmoidActivationFunctionTests 8 | { 9 | [Theory] 10 | [InlineData(0.3775, 0.5932699921)] 11 | public void ActivateProducesCorrectResultPositiveValue(double activationValue, double expectedResult) 12 | { 13 | var activationFunction = SigmoidActivationFunction.Create(); 14 | var activationResult = activationFunction.Activate(activationValue); 15 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, activationResult, 10); 16 | } 17 | 18 | [Theory] 19 | [InlineData(-0.1, 0.4750208125)] 20 | public void ActivateProducesCorrectResultNegativeValue(double activationValue, double expectedResult) 21 | { 22 | var activationFunction = SigmoidActivationFunction.Create(); 23 | var activationResult = activationFunction.Activate(activationValue); 24 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, activationResult, 10); 25 | } 26 | 27 | [Theory] 28 | [InlineData(0.59, 0.229446435)] 29 | public void DerivativeProducesCorrectResultPositiveValue(double inputValue, double expectedResult) 30 | { 31 | var activationFunction = SigmoidActivationFunction.Create(); 32 | var derivativeResult = activationFunction.Derivative(inputValue); 33 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, derivativeResult, 10); 34 | } 35 | 36 | [Theory] 37 | [InlineData(-0.78, 0.2155228953)] 38 | public void DerviativeProducesCorrectResultNegativeValue(double inputValue, double expectedResult) 39 | { 40 | var activationFunction = SigmoidActivationFunction.Create(); 41 | var derivativeResult = activationFunction.Derivative(inputValue); 42 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, derivativeResult, 10); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /NeuralNetworks.Tests.UnitTests/ActivationFunctionTests/TanHActivationFunctionTests.cs: -------------------------------------------------------------------------------- 1 | using NeuralNetworks.Library.Components.Activation.Functions; 2 | using NeuralNetworks.Tests.Support.Helpers; 3 | using Xunit; 4 | 5 | namespace NeuralNetworks.Tests.UnitTests.ActivationFunctionTests 6 | { 7 | public sealed class TanHActivationFunctionTests 8 | { 9 | [Theory] 10 | [InlineData(0.3775, 0.3605343934)] 11 | public void ActivateProducesCorrectResultPositiveValue(double activationValue, double expectedResult) 12 | { 13 | var activationFunction = TanHActivationFunction.Create(); 14 | var activationResult = activationFunction.Activate(activationValue); 15 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, activationResult, 10); 16 | } 17 | 18 | [Theory] 19 | [InlineData(-0.1, -0.0996679946)] 20 | public void ActivateProducesCorrectResultNegativeValue(double activationValue, double expectedResult) 21 | { 22 | var activationFunction = TanHActivationFunction.Create(); 23 | var activationResult = activationFunction.Activate(activationValue); 24 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, activationResult, 10); 25 | } 26 | 27 | [Theory] 28 | [InlineData(0.36, 0.8808272706)] 29 | public void DerivativeProducesCorrectResultPositiveValue(double inputValue, double expectedResult) 30 | { 31 | var activationFunction = TanHActivationFunction.Create(); 32 | var derivativeResult = activationFunction.Derivative(inputValue); 33 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, derivativeResult, 10); 34 | } 35 | 36 | [Theory] 37 | [InlineData(-0.41, 0.8490889767)] 38 | public void DerviativeProducesCorrectResultNegativeValue(double inputValue, double expectedResult) 39 | { 40 | var activationFunction = TanHActivationFunction.Create(); 41 | var derivativeResult = activationFunction.Derivative(inputValue); 42 | DoubleAssertionHelpers.AssertWithPrecision(expectedResult, derivativeResult, 10); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /NeuralNetworks.Tests.UnitTests/NeuralNetworks.Tests.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /NeuralNetworks.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.6 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Console", "NeuralNetworks.Console\NeuralNetworks.Console.csproj", "{6B2CBBD2-5CAB-48E1-99F6-15FF23035CBA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Library", "NeuralNetworks.Library\NeuralNetworks.Library.csproj", "{A21A69D7-546E-4F8E-BB2E-361E0DE5F995}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{391E7C6F-23B7-41B8-8A59-ED9C78EF5806}" 11 | ProjectSection(SolutionItems) = preProject 12 | .gitattributes = .gitattributes 13 | .gitignore = .gitignore 14 | README.md = README.md 15 | EndProjectSection 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Tests.IntegrationTests", "NeuralNetworks.Tests.IntegrationTests\NeuralNetworks.Tests.IntegrationTests.csproj", "{F3FFF6B9-C615-4BD1-B0EC-C20625E275E8}" 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Tests.Support", "NeuralNetworks.Tests.Support\NeuralNetworks.Tests.Support.csproj", "{E6CB89B0-0C6F-464C-A66B-D51ECF5979B2}" 20 | EndProject 21 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Tests.UnitTests", "NeuralNetworks.Tests.UnitTests\NeuralNetworks.Tests.UnitTests.csproj", "{E5E9362B-75E4-46F3-BD3D-0B9303DE9FBC}" 22 | EndProject 23 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NeuralNetworks.Tests.PerformanceTests", "NeuralNetworks.Tests.PerformanceTests\NeuralNetworks.Tests.PerformanceTests.csproj", "{D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}" 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|Any CPU = Debug|Any CPU 28 | Release|Any CPU = Release|Any CPU 29 | Debug|x64 = Debug|x64 30 | Debug|x86 = Debug|x86 31 | Release|x64 = Release|x64 32 | Release|x86 = Release|x86 33 | EndGlobalSection 34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 35 | {6B2CBBD2-5CAB-48E1-99F6-15FF23035CBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {6B2CBBD2-5CAB-48E1-99F6-15FF23035CBA}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {6B2CBBD2-5CAB-48E1-99F6-15FF23035CBA}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {6B2CBBD2-5CAB-48E1-99F6-15FF23035CBA}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {A21A69D7-546E-4F8E-BB2E-361E0DE5F995}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {A21A69D7-546E-4F8E-BB2E-361E0DE5F995}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {A21A69D7-546E-4F8E-BB2E-361E0DE5F995}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {A21A69D7-546E-4F8E-BB2E-361E0DE5F995}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {F3FFF6B9-C615-4BD1-B0EC-C20625E275E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {F3FFF6B9-C615-4BD1-B0EC-C20625E275E8}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {F3FFF6B9-C615-4BD1-B0EC-C20625E275E8}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {F3FFF6B9-C615-4BD1-B0EC-C20625E275E8}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {E6CB89B0-0C6F-464C-A66B-D51ECF5979B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {E6CB89B0-0C6F-464C-A66B-D51ECF5979B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {E6CB89B0-0C6F-464C-A66B-D51ECF5979B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {E6CB89B0-0C6F-464C-A66B-D51ECF5979B2}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {E5E9362B-75E4-46F3-BD3D-0B9303DE9FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {E5E9362B-75E4-46F3-BD3D-0B9303DE9FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {E5E9362B-75E4-46F3-BD3D-0B9303DE9FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {E5E9362B-75E4-46F3-BD3D-0B9303DE9FBC}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|x64.ActiveCfg = Debug|x64 58 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|x64.Build.0 = Debug|x64 59 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|x86.ActiveCfg = Debug|x86 60 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Debug|x86.Build.0 = Debug|x86 61 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|Any CPU.Build.0 = Release|Any CPU 63 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|x64.ActiveCfg = Release|x64 64 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|x64.Build.0 = Release|x64 65 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|x86.ActiveCfg = Release|x86 66 | {D996F6A4-CE86-44C7-A34A-2F4AE6BF9104}.Release|x86.Build.0 = Release|x86 67 | EndGlobalSection 68 | GlobalSection(SolutionProperties) = preSolution 69 | HideSolutionNode = FALSE 70 | EndGlobalSection 71 | EndGlobal 72 | --------------------------------------------------------------------------------