private TyresMachine([NotNull] NeuralTyresEntry[] tyres, [NotNull] NeuralTyresOptions options) { if (tyres == null) { throw new ArgumentNullException(nameof(tyres)); } if (tyres.Length == 0) { throw new ArgumentException("Value cannot be an empty collection.", nameof(tyres)); } _options = options ?? throw new ArgumentNullException(nameof(options)); // Some details to identify Machine later if needed _tyresSources = tyres.Cast <NeuralTyresSource>().ToArray(); // Tyres version TyresVersion = tyres[0].Version; if (tyres.Any(x => x.Version != TyresVersion)) { throw new ArgumentException("Inconsistent versions"); } // LUTs, just in case _luts = tyres.Select(x => x.Luts).ToArray(); // Input normalizations and values _inputNormalized = new double[tyres.Length][]; for (var i = 0; i < tyres.Length; i++) { _inputNormalized[i] = new double[3]; } _inputNormalizations = new Normalization[options.InputKeys.Length]; for (var i = 0; i < _inputNormalizations.Length; i++) { var limits = _options.NormalizationLimits.GetLimits(options.InputKeys[i]) ?? Tuple.Create(double.NegativeInfinity, double.PositiveInfinity); _inputNormalizations[i] = Normalization.BuildNormalization(tyres, options.InputKeys[i], options.ValuePadding, out var normalized, limits.Item1, limits.Item2); for (var j = 0; j < normalized.Length; j++) { _inputNormalized[j][i] = normalized[j]; } } // Output normalizations and values _outputKeys = tyres[0].Keys.Where(x => Array.IndexOf(options.IgnoredKeys, x) == -1 && (options.OverrideOutputKeys == null || Array.IndexOf(options.OverrideOutputKeys, x) != -1)).ToArray(); _outputNormalizations = new Normalization[_outputKeys.Length]; _outputNormalized = new double[_outputKeys.Length][]; for (var i = 0; i < _outputKeys.Length; i++) { var limits = _options.NormalizationLimits.GetLimits(_outputKeys[i]) ?? Tuple.Create(double.NegativeInfinity, double.PositiveInfinity); _outputNormalizations[i] = Normalization.BuildNormalization(tyres, _outputKeys[i], options.ValuePadding, out _outputNormalized[i], limits.Item1, limits.Item2); } }
public void Main() { var carsFromWebApp = new[] { /*"lotus_exige_s", "lotus_exige_s", "lotus_evora_gte", "lotus_elise_sc", "alfa_mito_qv", * "abarth500", "lotus_elise_sc", "alfa_romeo_giulietta_qv", "bmw_m3_e30", "audi_sport_quattro", * "audi_a1s1", "nissan_skyline_r34", "ford_mustang_2015", "bmw_1m", "bmw_m4", "bmw_m4", * "porsche_991_carrera_s", "porsche_718_boxster_s", "porsche_718_boxster_s", "corvette_c7_stingray", * "porsche_991_carrera_s"*/ "ks_abarth_595ss_s2", "ks_audi_r8_plus" }; var tyres = Directory.GetDirectories(@"D:\Games\Assetto Corsa\content\cars", "*") .Where(x => carsFromWebApp.ArrayContains(Path.GetFileName(x))) .Select(DataWrapper.FromCarDirectory).SelectMany(NeuralTyresEntry.Get) .Where(x => x.Version == 10).ToList(); var filteredTyres = tyres.Where(x => x.Name == "Street").ToList(); // filteredTyres.OrderBy(x => x.Values.GetDouble("RADIUS", 0d)).Select(x => $"{x.Values.GetDouble("RADIUS", 0d)}={x.Values.GetDouble(TestKey, 0d)}").JoinToString("; ").Dump(); var options = new NeuralTyresOptions { OverrideOutputKeys = new[] { "ANGULAR_INERTIA" } }; var checksum = (filteredTyres.GetEnumerableHashCode() * 397) ^ options.GetHashCode(); var cacheFilename = Path.Combine("U:\\nt-cache", BitConverter.GetBytes(checksum).ToHexString().ToLowerInvariant() + ".zip"); Console.WriteLine(checksum); TyresMachine neural; if (File.Exists(cacheFilename)) { neural = TyresMachine.LoadFrom(cacheFilename, null); } else { neural = TyresMachine.CreateAsync(filteredTyres, options).Result; FileUtils.EnsureFileDirectoryExists(cacheFilename); // neural?.Save(cacheFilename, null); } if (neural == null) { return; } var width = neural.GetNormalization(NeuralTyresOptions.InputWidth); var radius = neural.GetNormalization(NeuralTyresOptions.InputRadius); var profile = neural.GetNormalization(NeuralTyresOptions.InputProfile); var testKey = "ANGULAR_INERTIA"; try { BuildChart(Enumerable.Range(0, 7).Select(x => { return((Action <Series>)(s => { for (var i = 0d; i <= 1d; i += 0.01) { var w = width.Denormalize(x / 6d); var r = radius.Denormalize(i); var u = profile.Denormalize(i); s.Points.Add(new DataPoint(r, neural.Conjure(w, r, u)[testKey])); // s.Points.Add(new DataPoint(r, neural.Conjure(testKey, w, r, u))); } s.Color = new[] { Color.Red, Color.Orange, Color.Brown, Color.Lime, Color.Cyan, Color.Blue, Color.Magenta }[x]; })); }).ToArray()); } catch (Exception e) { Console.WriteLine(e); } Console.WriteLine(neural.Conjure(width.Denormalize(0.5), radius.Denormalize(0.5), profile.Denormalize(0.5))[testKey]); }
public void SetOptions(NeuralTyresOptions options) { _options = options; }
public void SetOptions(NeuralTyresOptions options) { _options = options; _list?.ForEach(x => x.SetOptions(options)); }
public static async Task <TyresMachine> CreateAsync(IEnumerable <NeuralTyresEntry> tyres, NeuralTyresOptions options, [CanBeNull] IProgress <Tuple <string, double?> > progress = null, CancellationToken cancellationToken = default) { var result = new TyresMachine(tyres.ToArray(), options); await Task.Run(() => result.Train(progress, cancellationToken), cancellationToken).ConfigureAwait(false); return(cancellationToken.IsCancellationRequested ? null : result); }
private TyresMachine([NotNull] Stream stream, [CanBeNull] ITyresMachineExtras extras) { using (var zip = new ZipArchive(stream, ZipArchiveMode.Read, false)) { var manifest = Read <JObject>("Manifest.json"); if (manifest.GetIntValueOnly("version") != SaveFormatVersion) { throw new Exception("Unsupported version: " + manifest.GetIntValueOnly("version")); } TyresVersion = manifest.GetIntValueOnly("tyresVersion", 0); if (TyresVersion < 7) { throw new Exception("Unsupported tyres version: " + TyresVersion); } _loadedManifest = manifest; _options = Read <NeuralTyresOptions>("Options.json"); _tyresSources = Read <NeuralTyresSource[]>("Input/Sources.json"); _luts = Read <Dictionary <string, string>[]>("Input/LUTs.json") .Select(x => (IReadOnlyDictionary <string, Lut>)x.ToDictionary(y => y.Key, y => Lut.FromValue(y.Value))).ToArray(); _inputNormalizations = Read <Normalization[]>("Input/Normalizations.json"); _outputKeys = Read <string[]>("Output/Keys.json"); _outputNormalizations = Read <Normalization[]>("Output/Normalizations.json"); extras?.OnLoad(zip, manifest, this); if (_options.SeparateNetworks) { _networks = new INeuralNetwork[_outputKeys.Length]; for (var i = 0; i < _outputKeys.Length; i++) { var key = _outputKeys[i]; var typeName = zip.ReadString($"Networks/{key}/Type.txt"); var type = Type.GetType(typeName); if (type == null) { throw new Exception("Type not found: " + typeName); } var instance = (INeuralNetwork)Activator.CreateInstance(type); instance.SetOptions(_options); instance.Load(zip.ReadBytes($"Networks/{key}/Data.bin")); _networks[i] = instance; } } else { var typeName = zip.ReadString("Network/Type.txt"); var type = Type.GetType(typeName); if (type == null) { throw new Exception("Type not found: " + typeName); } var instance = (INeuralNetwork)Activator.CreateInstance(type); instance.SetOptions(_options); instance.Load(zip.ReadBytes("Network/Data.bin")); _singleNetwork = instance; } T Read <T>(string key) { return(JsonConvert.DeserializeObject <T>(zip.ReadString(key))); } } }