Skip to content

Commit

Permalink
add Upgrade_20201230_TensorFlow
Browse files Browse the repository at this point in the history
  • Loading branch information
olmobrutall committed Dec 30, 2020
1 parent f377362 commit 4f28e79
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions Signum.Upgrade/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ static void Main(string[] args)
new Upgrade_20201210_NavigatorView(),
new Upgrade_20201220_React17(),
new Upgrade_20201223_IndexErrorHandling(),
new Upgrade_20201230_TensorFlow(),
}.Run(uctx);
}
}
Expand Down
87 changes: 87 additions & 0 deletions Signum.Upgrade/Upgrades/Upgrade_20201230_TensorFlow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Signum.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace Signum.Upgrade.Upgrades
{
class Upgrade_20201230_TensorFlow : CodeUpgradeBase
{
public override string Description => "replace CNTK for TensorFlow";

public override void Execute(UpgradeContext uctx)
{
uctx.ChangeCodeFile(@".gitignore", file =>
{
file.InsertAfterLastLine(
a=>a.Contains("ts_out"),
@"/Southwind.React/TensorFlowModels/**");
});

uctx.ChangeCodeFile(@"Southwind.Logic/Southwind.Logic.csproj", file =>
{
file.Replace(
@"Signum.Engine.MachineLearning.CNTK\Signum.Engine.MachineLearning.CNTK.csproj",
@"Signum.Engine.MachineLearning.TensorFlow\Signum.Engine.MachineLearning.TensorFlow.csproj");
});

uctx.ChangeCodeFile(@"Southwind.React/Southwind.React.csproj", file =>
{
file.ReplaceLine(a => a.Contains("CNTK.CPUOnly"),
@"<PackageReference Include=""SciSharp.TensorFlow.Redist"" Version=""2.3.1"" />"
);
});

uctx.ChangeCodeFile(@"Southwind.Logic/Starter.cs", file =>
{
file.Replace(
@"using Signum.Engine.MachineLearning.CNTK;",
@"using Signum.Engine.MachineLearning.TensorFlow;");
file.Replace(
@"CNTKPredictorAlgorithm.NeuralNetwork, new CNTKNeuralNetworkPredictorAlgorithm()",
@"TensorFlowPredictorAlgorithm.NeuralNetworkGraph, new TensorFlowNeuralNetworkPredictor()");
});

uctx.ChangeCodeFile(@"Southwind.Terminal/SouthwindMigrations.cs", file =>
{
file.Replace(
@"CNTKPredictorAlgorithm.NeuralNetwork",
@"TensorFlowPredictorAlgorithm.NeuralNetworkGraph");
file.Replace(
@"Learner = NeuralNetworkLearner.MomentumSGD",
@"Optimizer = TensorFlowOptimizer.GradientDescentOptimizer");
file.Replace(
@"LossFunction = NeuralNetworkEvalFunction.SquaredError",
@"LossFunction = NeuralNetworkEvalFunction.MeanSquaredError");
file.ReplaceBetweenIncluded(
a => a.Contains("LearningRate = 0.1,"),
a => a.Contains("LearningUnitGain = false,"),
@"LearningRate = 0.0001,");
});

uctx.ChangeCodeFile(@"*.csproj", file =>
{
file.RemoveAllLines(a => a.Contains("<Platforms>"));
file.ReplaceBetweenIncluded(
a => a.Contains("<PropertyGroup Condition="),
a => a.Contains("</PropertyGroup>"),
"");
});

uctx.ChangeCodeFile(@"Southwind.sln", file =>
{
file.Replace("x64", "Any CPU");
});
}
}
}

3 comments on commit 4f28e79

@olmobrutall
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing CNTK with TensorFlow.NET and back to Any CPU

When Predictor was created 2+ years ago Tensorflow was already much more popular than CNTK, but there wasn't any .NET Bindings.

Since then, CNTK has been abandoned 👎 but there are [new .NET bindings for Tensorflow][https://github.com/SciSharp/TensorFlow.NET] 👍 so a migration is needed.

Python-like API

Tensorflow.NET API tries to be very similar to the python bindings (lowercase identifiers!), so very often you can use the official TensorFlow documentation.
Also, since most of the error messages are produced by the C++ code you can also google them and find solutions in StackOverflow.

Lightweight NuGet

CNTK had two NuGets:

  • CNTK.CPUOnly lightweight and simple
  • CNTK.GPU huge, requires CUDA, but potentially faster

While the APIs where identical, Signum.Extensions.MachineLearning.CNTK had to reference one or the other.

In Tensorflow.NET there are three NuGets:

  • TensorFlow.NET, TensorFlow.Keras lightweigh, contains the bindings (aka the API).
  • SciSharp.TensorFlow.Redist lightweight CPU binaries (aka CPU runtime)
  • SciSharp.TensorFlow.Redist-Windows-GPU huge GPU binaries that require CUDA (aka GPU runtime)

This means that the new Signum.Extensions.MachineLearning.TensorFlow can only reference the bindings (TensorFlow.Keras) and each application can decide whether to use the CPU or the GPU runtime.

This means faster NuGet restores (GPU binaries and the dependencies are in the range of 1GB!)

NOTE: There is another NuGet called TensorFlowSharp mantained by Migel de Icaza. Looks less complete and less maintained. We are using TensorFlow.NET, don't confuse it.

Compatible with Any CPU

Another problem of CNTK was that it only worked for x64, since Visual Studio is very insistent in using Any CPU by default, the solution was to remove Any CPU configuration altogether. This worked but made Signum apps somehow strange for an... exotic dependency.

This problem is gone with TensorFlow.NET, so we can go back to the standard Any CPU configuration.

Conclusion

I haven't used the new TensorFlow-powered Predictor much, but I hope this changes will make the experience of using Signum Framework more normal and intuitive whether you are using this extension or not.

How to Upgrade?

Just run:

  • Upgrade_20201230_TensorFlow to replace CNTK by TensorFlow.
  • Upgrade_20201231_AnyCPU to replace x64 by Any CPU

@MehdyKarimpour
Copy link
Contributor

@MehdyKarimpour MehdyKarimpour commented on 4f28e79 Dec 31, 2020 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@doganc
Copy link

@doganc doganc commented on 4f28e79 Dec 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect 👍

Please sign in to comment.