Skip to content

Commit 5acb362

Browse files
committed
Added the possibility to Save and Load networks (WeightedNetwork especially). Its being saved to a JSON-String
1 parent 1253d45 commit 5acb362

File tree

9 files changed

+129
-15
lines changed

9 files changed

+129
-15
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Newtonsoft.Json;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace NeuralBotMasterFramework.Helper
9+
{
10+
// Class taken from source:
11+
// https://blog.greatrexpectations.com/2012/08/30/deserializing-interface-properties-using-json-net
12+
public class ConcreteTypeConverter<TConcrete> : JsonConverter
13+
{
14+
public override bool CanConvert(Type objectType)
15+
{
16+
return true;
17+
}
18+
19+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
20+
{
21+
return serializer.Deserialize<TConcrete>(reader);
22+
}
23+
24+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
25+
{
26+
serializer.Serialize(writer, value);
27+
}
28+
}
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace NeuralBotMasterFramework.Interfaces
8+
{
9+
public interface ISaveableNetwork
10+
{
11+
string SaveNetwork();
12+
ISaveableNetwork LoadNetwork(string networkString);
13+
}
14+
}

NeuralBotMasterFramework/NeuralBotMasterFramework/Logic/Networks/WeightedNetwork.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,27 @@
55
using System.Threading.Tasks;
66
using NeuralBotMasterFramework.Interfaces;
77
using NeuralBotMasterFramework.Models;
8+
using Newtonsoft.Json;
9+
using NeuralBotMasterFramework.Helper;
810

911
namespace NeuralBotMasterFramework.Logic.Networks
1012
{
11-
public class WeightedNetwork : IWeightedNetwork
13+
public class WeightedNetwork : IWeightedNetwork, ISaveableNetwork
1214
{
15+
[JsonConverter(typeof(ConcreteTypeConverter<Layer>))]
1316
public ILayer InputLayer { get; set; }
17+
18+
[JsonConverter(typeof(ConcreteTypeConverter<WeightedLayer[]>))]
1419
public IWeightedLayer[] HiddenLayers { get; set; }
20+
21+
[JsonConverter(typeof(ConcreteTypeConverter<WeightedLayer>))]
1522
public IWeightedLayer OutputLayer { get; set; }
1623

1724
public int ID { get; set; }
1825

26+
// Required for JSON-Deserialization
27+
public WeightedNetwork() { }
28+
1929
public WeightedNetwork(int inputNodes, int hiddenLayers, int hiddenNodesPerLayer, int outputNodes)
2030
{
2131
InitializeInputNodes(inputNodes);
@@ -31,7 +41,7 @@ private void InitializeInputNodes(int inputNodes)
3141
private void InitializeHiddenNodes(int totalHiddenLayers, int totalHiddenNodesPerLayer, int previousNodes)
3242
{
3343
HiddenLayers = new IWeightedLayer[totalHiddenLayers];
34-
for(int i = 0; i < totalHiddenLayers; ++i)
44+
for (int i = 0; i < totalHiddenLayers; ++i)
3545
{
3646
HiddenLayers[i] = new WeightedLayer(totalHiddenNodesPerLayer, previousNodes);
3747
previousNodes = HiddenLayers[i].Nodes.Length;
@@ -56,12 +66,22 @@ public double[] GetOutput()
5666
public void Propagate()
5767
{
5868
double[] values = InputLayer.GetValues();
59-
for(int i = 0; i < HiddenLayers.Length; ++i)
69+
for (int i = 0; i < HiddenLayers.Length; ++i)
6070
{
6171
HiddenLayers[i].SetValues(values);
6272
values = HiddenLayers[i].GetValues();
6373
}
6474
OutputLayer.SetValues(values);
6575
}
76+
77+
public string SaveNetwork()
78+
{
79+
return JsonConvert.SerializeObject(this);
80+
}
81+
82+
public ISaveableNetwork LoadNetwork(string networkString)
83+
{
84+
return (ISaveableNetwork)JsonConvert.DeserializeObject(networkString, typeof(WeightedNetwork));
85+
}
6686
}
6787
}

NeuralBotMasterFramework/NeuralBotMasterFramework/Models/Layer.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
using System.Threading.Tasks;
66
using NeuralBotMasterFramework.Interfaces;
77
using NeuralBotMasterFramework.Models;
8+
using Newtonsoft.Json;
9+
using NeuralBotMasterFramework.Helper;
810

911
namespace NeuralBotMasterFramework.Models
1012
{
1113
public class Layer : ILayer
1214
{
15+
[JsonConverter(typeof(ConcreteTypeConverter<Node[]>))]
1316
public INode[] Nodes { get; set; }
1417

1518
public Layer() { }

NeuralBotMasterFramework/NeuralBotMasterFramework/Models/WeightedLayer.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
using System.Threading.Tasks;
66
using NeuralBotMasterFramework.Interfaces;
77
using NeuralBotMasterFramework.Models;
8+
using Newtonsoft.Json;
9+
using NeuralBotMasterFramework.Helper;
810

911
namespace NeuralBotMasterFramework.Models
1012
{
1113
public class WeightedLayer : IWeightedLayer
1214
{
15+
[JsonConverter(typeof(ConcreteTypeConverter<WeightedNode[]>))]
1316
public IWeightedNode[] Nodes { get; set; }
1417

1518
public WeightedLayer() { }

NeuralBotMasterFramework/NeuralBotMasterFramework/NeuralBotMasterFramework.csproj

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
<WarningLevel>4</WarningLevel>
3232
</PropertyGroup>
3333
<ItemGroup>
34+
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
35+
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
36+
</Reference>
3437
<Reference Include="System" />
3538
<Reference Include="System.Core" />
3639
<Reference Include="System.Xml.Linq" />
@@ -41,12 +44,14 @@
4144
<Reference Include="System.Xml" />
4245
</ItemGroup>
4346
<ItemGroup>
47+
<Compile Include="Helper\ConcreteTypeConverter.cs" />
4448
<Compile Include="Helper\RandomNumberGenerator.cs" />
4549
<Compile Include="Interfaces\IBaseLayer.cs" />
4650
<Compile Include="Interfaces\IBreedingPoolGenerator.cs" />
4751
<Compile Include="Interfaces\IGeneticAlgorithm.cs" />
4852
<Compile Include="Interfaces\ILayer.cs" />
4953
<Compile Include="Interfaces\INetwork.cs" />
54+
<Compile Include="Interfaces\ISaveableNetwork.cs" />
5055
<Compile Include="Interfaces\IWeightedLayer.cs" />
5156
<Compile Include="Interfaces\IWeightedNetwork.cs" />
5257
<Compile Include="Interfaces\IWeightedNode.cs" />
@@ -61,6 +66,8 @@
6166
<Compile Include="Models\WeightedNode.cs" />
6267
<Compile Include="Properties\AssemblyInfo.cs" />
6368
</ItemGroup>
64-
<ItemGroup />
69+
<ItemGroup>
70+
<None Include="packages.config" />
71+
</ItemGroup>
6572
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
6673
</Project>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net461" />
4+
</packages>

NeuralBotMasterFramework/NeuralBotMasterFrameworkTests/Logic/WeightedNetworkTests.cs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Microsoft.VisualStudio.TestTools.UnitTesting;
1+
using NeuralBotMasterFramework.Logic.Networks;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
23
using NeuralBotMasterFramework.Logic;
34
using System;
45
using System.Collections.Generic;
@@ -71,10 +72,43 @@ public void PropagateTest()
7172
network.SetInput(input);
7273
network.Propagate();
7374

74-
foreach(double result in network.GetOutput())
75+
foreach (double result in network.GetOutput())
7576
{
7677
Assert.AreNotEqual(0, result);
7778
}
7879
}
80+
81+
[TestMethod]
82+
public void SaveNetworkTest()
83+
{
84+
WeightedNetwork network = new WeightedNetwork(5, 3, 200, 9);
85+
string savedNetwork = network.SaveNetwork();
86+
87+
WeightedNetwork loadedNetwork = (WeightedNetwork)network.LoadNetwork(savedNetwork);
88+
Assert.AreEqual(network.InputLayer?.Nodes.Length, loadedNetwork.InputLayer?.Nodes.Length);
89+
Assert.AreEqual(network.HiddenLayers?.Length, loadedNetwork.HiddenLayers?.Length);
90+
Assert.AreEqual(network.OutputLayer?.Nodes.Length, loadedNetwork.OutputLayer?.Nodes.Length);
91+
92+
for (int hiddenLayerIndex = 0; hiddenLayerIndex < network.HiddenLayers.Length; hiddenLayerIndex++)
93+
{
94+
IWeightedLayer firstNetworkHiddenLayer = network.HiddenLayers[hiddenLayerIndex];
95+
IWeightedLayer loadedNetworkHiddenLayer = loadedNetwork.HiddenLayers[hiddenLayerIndex];
96+
Assert.AreEqual(firstNetworkHiddenLayer?.Nodes?.Length, loadedNetworkHiddenLayer?.Nodes.Length);
97+
98+
for (int hiddenlayerNodeIndex = 0; hiddenlayerNodeIndex < firstNetworkHiddenLayer.Nodes.Length; hiddenlayerNodeIndex++)
99+
{
100+
IWeightedNode firstNetworkHiddenNode = firstNetworkHiddenLayer.Nodes[hiddenlayerNodeIndex];
101+
IWeightedNode loadedNetworkHiddenNode = loadedNetworkHiddenLayer.Nodes[hiddenlayerNodeIndex];
102+
Assert.AreEqual(firstNetworkHiddenNode.Value, loadedNetworkHiddenNode.Value);
103+
104+
for(int networkHiddenNodeWeightIndex = 0; networkHiddenNodeWeightIndex < firstNetworkHiddenNode.Weights.Length; ++networkHiddenNodeWeightIndex)
105+
{
106+
double firstNetworkWeight = firstNetworkHiddenNode.Weights[networkHiddenNodeWeightIndex];
107+
double loadedNetworkWeight = loadedNetworkHiddenNode.Weights[networkHiddenNodeWeightIndex];
108+
Assert.AreEqual(firstNetworkWeight, loadedNetworkWeight);
109+
}
110+
}
111+
}
112+
}
79113
}
80114
}

NeuralBotMasterFramework/TestConsole/Program.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@ class Program
1414
private static double[][] inputData;
1515
private static double[][] expectedData;
1616

17-
private static int dataSetsPerPropagation = 1000;
17+
private static int dataSetsPerPropagation = 500;
1818
private static double[][] currentInputData;
1919
private static double[][] currentExpectedData;
2020

21-
const int TOTAL_BITS = 12;
21+
const int TOTAL_BITS = 2;
2222
private static int totalNumberLength = Math.Pow(2, TOTAL_BITS).ToString().Length;
2323

2424
static void Main(string[] args)
2525
{
26-
int totalNetworks = 1000;
26+
int totalNetworks = 10000;
2727
int inputNodes = TOTAL_BITS;
2828
int hiddenNodes = 10;
29-
int hiddenLayers = 2;
29+
int hiddenLayers = 5;
3030
int outputNodes = totalNumberLength;
3131

32-
int networksToKeep = 10;
33-
int totalRandomNetworks = 10;
34-
double mutationRate = 0.01;
35-
double mutationChance = 0.01;
32+
int networksToKeep = 100;
33+
int totalRandomNetworks = 1000;
34+
double mutationRate = 0.5;
35+
double mutationChance = 0.5;
3636

3737
SetupBinaryData();
3838

@@ -58,7 +58,7 @@ static void Main(string[] args)
5858
algorithm.PropagateAllNetworks();
5959
Console.WriteLine("Breeding");
6060
algorithm.BreedBestNetworks();
61-
if (generation % 20 == 0)
61+
if (generation % 10 == 0)
6262
{
6363
PrintData(algorithm);
6464
}

0 commit comments

Comments
 (0)