forked from amkovkov/GranuSightSoftware2
feat: models caching
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
##
|
##
|
||||||
## Get latest from `dotnet new gitignore`
|
## Get latest from `dotnet new gitignore`
|
||||||
|
|
||||||
|
.models_cache
|
||||||
.zed
|
.zed
|
||||||
*.png
|
*.png
|
||||||
cache
|
cache
|
||||||
|
|||||||
@@ -141,6 +141,35 @@ public partial class AnalyzerService
|
|||||||
var sampleRecords = _context.SampleRecords
|
var sampleRecords = _context.SampleRecords
|
||||||
.Where(r => r.BrandId == brand.Id);
|
.Where(r => r.BrandId == brand.Id);
|
||||||
|
|
||||||
|
var dataSb = new System.Text.StringBuilder();
|
||||||
|
dataSb.AppendLine(brand.Id.ToString());
|
||||||
|
dataSb.AppendLine(brand.EditDateTime.ToString());
|
||||||
|
foreach (var record in sampleRecords.OrderBy(r => r.Id))
|
||||||
|
{
|
||||||
|
dataSb.AppendLine(record.Id.ToString());
|
||||||
|
dataSb.AppendLine(record.EditDateTime.ToString());
|
||||||
|
}
|
||||||
|
dataSb.AppendLine(separator.Id.ToString());
|
||||||
|
dataSb.AppendLine(separator.EditDateTime.ToString());
|
||||||
|
var dataHashCode = Convert.ToHexString(
|
||||||
|
System.Security.Cryptography.MD5.HashData(
|
||||||
|
System.Text.Encoding.UTF8.GetBytes(dataSb.ToString())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_logger.LogInformation("Хэш калибровочных записей: {}", dataHashCode);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(".models_cache");
|
||||||
|
var cachedModelPath = Path.Combine(".models_cache", dataHashCode) + ".zip";
|
||||||
|
|
||||||
|
if (File.Exists(cachedModelPath))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Модель найдена к кэше");
|
||||||
|
var model = _ml.Model.Load(cachedModelPath, out _);
|
||||||
|
_clusterizationEngine = _ml.Model.CreatePredictionEngine<ClusterizationData, ClusterizationPrediction>(model);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_logger.LogInformation("Найдено калибровочных записей проб для марки: {}", sampleRecords.Count());
|
_logger.LogInformation("Найдено калибровочных записей проб для марки: {}", sampleRecords.Count());
|
||||||
if (sampleRecords.Count() == 0)
|
if (sampleRecords.Count() == 0)
|
||||||
throw new InvalidDataException($"Не найдено калибровочных записей для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
throw new InvalidDataException($"Не найдено калибровочных записей для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
||||||
@@ -202,9 +231,13 @@ public partial class AnalyzerService
|
|||||||
var model = pipeline.Fit(trainData);
|
var model = pipeline.Fit(trainData);
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
_ml.Model.Save(model, trainData.Schema, cachedModelPath);
|
||||||
|
|
||||||
_clusterizationEngine = _ml.Model.CreatePredictionEngine<ClusterizationData, ClusterizationPrediction>(model);
|
_clusterizationEngine = _ml.Model.CreatePredictionEngine<ClusterizationData, ClusterizationPrediction>(model);
|
||||||
|
|
||||||
model.Dispose();
|
model.Dispose();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private async Task InitializeMlRegressionEngine(BrandRecord brand, CancellationToken cancellationToken)
|
private async Task InitializeMlRegressionEngine(BrandRecord brand, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Инициализация модели регрессии для марки \"{} - {}\"", brand.BrandName, brand.MixtureName);
|
_logger.LogInformation("Инициализация модели регрессии для марки \"{} - {}\"", brand.BrandName, brand.MixtureName);
|
||||||
@@ -217,6 +250,33 @@ public partial class AnalyzerService
|
|||||||
var sampleRecords = _context.SampleRecords
|
var sampleRecords = _context.SampleRecords
|
||||||
.Where(r => r.BrandId == brand.Id);
|
.Where(r => r.BrandId == brand.Id);
|
||||||
|
|
||||||
|
var dataSb = new System.Text.StringBuilder();
|
||||||
|
dataSb.AppendLine(brand.Id.ToString());
|
||||||
|
dataSb.AppendLine(brand.EditDateTime.ToString());
|
||||||
|
foreach (var record in sampleRecords.OrderBy(r => r.Id))
|
||||||
|
{
|
||||||
|
dataSb.AppendLine(record.Id.ToString());
|
||||||
|
dataSb.AppendLine(record.EditDateTime.ToString());
|
||||||
|
}
|
||||||
|
var dataHashCode = Convert.ToHexString(
|
||||||
|
System.Security.Cryptography.MD5.HashData(
|
||||||
|
System.Text.Encoding.UTF8.GetBytes(dataSb.ToString())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_logger.LogInformation("Хэш калибровочных записей: {}", dataHashCode);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(".models_cache");
|
||||||
|
var cachedModelPath = Path.Combine(".models_cache", dataHashCode) + ".zip";
|
||||||
|
|
||||||
|
if (File.Exists(cachedModelPath))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Модель найдена к кэше");
|
||||||
|
var model = _ml.Model.Load(cachedModelPath, out _);
|
||||||
|
_regressionEngine = _ml.Model.CreatePredictionEngine<RegressionData, RegressionPrediction>(model);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_logger.LogInformation("Найдено калибровочных записей проб для марки: {}", sampleRecords.Count());
|
_logger.LogInformation("Найдено калибровочных записей проб для марки: {}", sampleRecords.Count());
|
||||||
if (sampleRecords.Count() == 0)
|
if (sampleRecords.Count() == 0)
|
||||||
throw new InvalidDataException($"Не найдено калибровочных записей для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
throw new InvalidDataException($"Не найдено калибровочных записей для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
||||||
@@ -250,6 +310,7 @@ public partial class AnalyzerService
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_logger.LogInformation("Загружено векторов для обучения: {}", trainDataSet.Count());
|
_logger.LogInformation("Загружено векторов для обучения: {}", trainDataSet.Count());
|
||||||
|
|
||||||
if (trainDataSet.Count() == 0)
|
if (trainDataSet.Count() == 0)
|
||||||
throw new InvalidDataException($"Не найдено калибровочных данных для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
throw new InvalidDataException($"Не найдено калибровочных данных для марки: \"{brand.BrandName} - {brand.MixtureName}\"");
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
@@ -287,10 +348,13 @@ public partial class AnalyzerService
|
|||||||
|
|
||||||
_logger.LogInformation("Обучение модели");
|
_logger.LogInformation("Обучение модели");
|
||||||
var model = pipeline.Fit(trainData);
|
var model = pipeline.Fit(trainData);
|
||||||
|
_ml.Model.Save(model, trainData.Schema, cachedModelPath);
|
||||||
|
|
||||||
_regressionEngine = _ml.Model.CreatePredictionEngine<RegressionData, RegressionPrediction>(model);
|
_regressionEngine = _ml.Model.CreatePredictionEngine<RegressionData, RegressionPrediction>(model);
|
||||||
|
|
||||||
model.Dispose();
|
model.Dispose();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<(Mat avgImage, Rect roi, Mat mask, IEnumerable<Point[]> contours, Mat result)?> Analyze(IEnumerable<ImageData> imagesData)
|
public async Task<(Mat avgImage, Rect roi, Mat mask, IEnumerable<Point[]> contours, Mat result)?> Analyze(IEnumerable<ImageData> imagesData)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user