Home - xkqg/DeepSharp GitHub Wiki

DeepSharp

The best of three worlds: TensorFlow's way of describing a network, PyTorch's way of running it, and ML.NET's way of learning from a table.

DeepSharp is a C# library for building, training and serving neural networks. You describe how your data becomes rows a model can learn from, name the network those rows are for, and run it. The data path, the model and what it learned are kept as one file, which a program that has never seen your data reads back and serves.

In short

  • Write C#, not Python in C# syntax. Stack layers in Keras's words, or write the forward pass as code. Either way it is the same network, trained by the same loop and saved to the same file.
  • The data can't leak. Anything that learns from the data, such as a fill, a scale or an encoding, learns from the training rows alone and is replayed unchanged on validation, on test and on live rows. That idea is called PDD.
  • The engine is a choice. .NET's own vector maths runs out of the box. libtorch, on the processor or a graphics card, is one line away, and your model does not change.
  • Bring models from elsewhere. What PyTorch, Keras or an ONNX exporter saved is read into the same network.
  • Not only networks. A table that a tree learns better can go to an ML.NET trainer instead, measured by the same report on the same rows.

A first look

A day of bitcoin's price per row, a feature worked out, the rows split by time, a small network trained and saved:

using DeepSharp.Learners.Networks;
using DeepSharp.Networks;
using DeepSharp.Pipelines;

var pipeline = Pdd.Create()
    .ReadCsv("btceur-1d.csv")                                // declared, not opened
    .Declare(schema => schema
        .Timestamp("timestamp")
        .Number("close")
        .Optional("trades", ColumnKind.Number))              // a column that may have gaps
    .OrderBy("timestamp")
    .SettleGaps(gaps => gaps.Zero("trades"))                 // the gaps first: a quiet day traded nothing
    .AddFeature("turnover", "close", Arithmetic.Times, "trades") // then the features, worked out from settled columns
    .ScaleGiven(scale => scale                               // then the scaling, from bounds you know
        .Between("turnover", 0, 2_000_000_000))
    .SplitByTime("timestamp", train: 0.70, validation: 0.15, gap: 1) // then the split, just before what learns
    .Ahead("close", 1, AheadAs.Return)                       // the answer: tomorrow's return
    .Drop("timestamp")                                       // what no model reads
    .Normalise(scale => scale                                // below the split, only the training rows decide
        .Columns("close")
        .MaxAbs("trades"))
    .Report(report => report.Measure(Metric.Rmse).On(Part.Validation, Part.Test).As(Shown.Numbers))
    .WithTensorflow(network => network                       // the network these rows train
        .Dense(8).Relu().Dense(1)
        .Adam()
        .MeanSquaredError()
        .Run(seed: 42, epochs: 20))
    .Build();

var trained = pipeline.Train();                              // from the file to the trained model

var file = trained.ToJson();                                 // the network and its pipeline, one file

Read it top to bottom: everything above SplitByTime is the same for every row, whoever reads it. Everything below it learns from the training rows only. Getting Started walks the same course step by step on a real file.

Where to start

If you want to… Read
install it and train a first network Getting Started, then its ten steps
start from a ready list of steps and fill in the blanks Starting from a course
understand why the library is shaped this way PDD
look up a verb of the pipeline Pipeline
land prices from an exchange as a file Live sources
add a verb of your own Writing a step of your own
try many networks and keep the best Searching for a network
pick layers, losses, optimizers and the loop Networks
train a tree from ML.NET instead ML.NET learner
run on libtorch, on the processor or a graphics card TorchSharp backend
read a model saved by PyTorch, Keras or ONNX Importing a model
write the pipeline as a notebook Notebook
know the design decisions, and what was left out Architecture
know what has to be true before code is accepted Quality
report a vulnerability Security
see what is done and what is still to come Roadmap

What is in the box

Each package does one thing. Add the ones you use.

Package What it is for
DeepSharp Tensors, the engine seam (ITensorBackend), the light engine (CpuBackend), gradients (RecordingBackend), the layers, losses, optimizers and the training loop.
DeepSharp.Pipelines The data half: read, declare the columns, work out features, split, fill, scale, name the answer, report β€” saved as one file and replayed.
DeepSharp.Learners.Networks A network declared in the pipeline's chain and trained by pipeline.Train(), measured by its report and kept with it as one file.
DeepSharp.Learners.ML, .MLNet An ML.NET trainer behind the same seam: see ML.NET learner.
DeepSharp.Backends.TorchSharp The arithmetic on libtorch: TorchBackend.OnCpu() or TorchBackend.OnGpu(0). Your application brings libtorch.
DeepSharp.Import.PyTorch, .Keras, .Onnx A model trained elsewhere, read into the same network.
DeepSharp.Export.Onnx A trained network written as an ONNX graph, answered through by ONNX Runtime as the network answers: see Exporting a model.
DeepSharp.Charts The loss curve, confusion matrices, residuals, the measures and the reliability curve as SVG, and the report as HTML, drawn with MatPlotLibNet.
DeepSharp.Pipelines.Parquet, .Excel, .Json Read a Parquet file, an Excel sheet or a JSON file of records, as a comma-separated file is read.
DeepSharp.Pipelines.Images, .Sound Read a folder of pictures or of WAV recordings, a folder to a class, each file a row of a size the step says.
DeepSharp.Pipelines.DataFrame Anything that can fill Microsoft's DataFrame: a CSV, a database query, rows already in hand.
DeepSharp.Pipelines.Indicators Indicators over a series, from the published MatPlotLibNet packages.
DeepSharp.Pipelines.Binance Candles from Binance, fetched once over a closed window and landed as a file: see Live sources.
DeepSharp.Verso.Notebooks The pipeline as a Verso notebook, one block per step, with the data, a profile and a heatmap at any block.
DeepSharp.Verso.Api Host that notebook in an application of your own.
DeepSharp.Verso.Serve deepsharp-serve, a .NET tool that shows a notebook in your browser with nothing else to install.

Where this stands β€” version 0.14.0

What is here works and is tested. Each release added one layer, and every release that brought something to call has its own examples β€” what is new and what was improved, in code you can copy β€” on the Examples page:

Release What it added
0.1 Tensors and the engine seam.
0.2 The data half: the pipeline.
0.3 A strict data half, more than one answer, and a notebook β€” in Verso, in your own application or in the browser.
0.4 Learning: layers, losses, optimizers and a training loop, measured, drawn and kept with the pipeline as one file.
0.5 libtorch as a second engine; models read from PyTorch, Keras and ONNX; Parquet, Excel and JSON files.
0.6 The model in the pipeline: the whole course from a file to a validated model is one declaration.
0.7 A trainer from ML.NET behind the same seam; then a course to fill in.
0.8 A live source landed as a file; then AdamW, RMSprop, Nadam, clipping, warm-up and a study over many networks.
0.9 Everything a window can be: strides per axis, dilation, groups, depthwise and transposed convolutions, adaptive pooling.
0.10 Everything the parts can be told: no bias, initialisers, borders, penalties, held layers, and the optimizers' options.
0.11 Bins and periodic embeddings of a number, how alike the parts of a split are, a study that prunes and resumes, a running statistic per key; and the smooth activations, the group, instance and RMS normalisations, embeddings, new losses, and F1, AUC, MAPE and the Brier score.
0.12 A model watched after it ships: the training rows kept as counts, and windows of served rows measured against them β€” examples.
0.13 What a model is worth, and more ways to train it: folds and origins, an interval and a reason with every answer, networks that answer together, pictures, recordings and texts read as rows, and a rate of its own for a part of a network β€” examples.
0.14 The light engine faster by the same bits, and a network that is no longer a line: branches, an LSTM and a GRU, attention and an encoder block, readers that read them, and a trained network written as an ONNX graph β€” examples.

What is still to come, and what is left out on purpose, is on the Roadmap. The changelog records exactly what each release added and why anything was refused.

How this sits next to TorchSharp, TensorFlow.NET and ML.NET

TorchSharp and TensorFlow.NET are bindings. They give you PyTorch's or TensorFlow's own interface, written in C#, with the original engine underneath. DeepSharp is happy to use one: the libtorch engine runs through TorchSharp.

What a binding does not give you is a library that reads like C#, a way to pour your data in, a training loop you did not write yourself, or a picture of what happened. DeepSharp sits on top and provides those. Because your model talks to a backend rather than to an engine, the choice of engine stays a choice.

ML.NET is something else: Microsoft's machine-learning library, with ready trainers for tables β€” trees, linear models and more. Its own data pipeline is fitted on whatever rows it is handed, so keeping the rows a model is measured on out of that fit is left to you. DeepSharp's pipeline makes that mistake impossible, and an ML.NET trainer is one of the learners it hands its rows to: see ML.NET learner.

The small print on the engine. The default engine needs nothing installed and travels inside your application. libtorch for the processor is between 56.9 MB and 128.2 MB to download for each platform you ship to, and a graphics card's runs to gigabytes. You pick per project, not per library.

Also: Repository Β· Changelog Β· Contributing.