你、我,甚至隔壁的约翰都知道,机器学习通过使用提供给它们的数据来预测未来的结果,让你的机器变得“更智能”。 机器学习网络 是 .NET 中用于机器学习的事实上的标准,它允许您预先训练模型并准确地做出预测。
假设您有一个 ML.NET 应用程序,用于根据以前的行程数据和当前交通情况预测出租车费用。 鉴于当前的 COVID-19 大流行,我们已经看到消费者行为发生了巨大转变:长途旅行被最小化,更多的快递被用来运送食品/杂货,一些地区被完全封锁,等等。 此应用程序的传入数据快速且不断变化,因此机器学习模型需要经常重新训练。 如果机器学习端读取这些数据,可能会导致速度变慢。
要解决此类问题,您需要缓存行程数据,以便 ML.NET 应用程序可以访问数据而不会遇到任何瓶颈。 ML.NET 提供默认缓存,但不可扩展。 NCache 是一个 内存中,分布式缓存 在.NET 中。 使用 NCache 数据处理提高了应用程序的性能,因为它在内存中提供了快速的读/写操作。 被分发, NCache 如果数据集变得太大,可以在运行时扩展。
运用 NCache 扩展和重新训练机器学习模型
描绘如何 NCache 可以使这个 ML.NET 应用程序更具可扩展性并在运行时更快地重新训练模型,我们扩展了 Microsoft 广泛使用的 TaxiFarePrediction 项目以集成 NCache. 你可以找到这个扩展项目 NCache on GitHub上.
应用程序是这样工作的,如上图所示 图1:
- 出租车行程数据存储在缓存中作为 列表数据类型 这是一个扩展
IEnumerable IList
. ML.NET 支持LoadFromEnumerable()
方法,因此不需要对数据进行额外的操作。 - ML.NET 应用程序订阅 发布/订阅 当指定大小的更多数据块添加到缓存中时,主题接收更新。
- 对于初始数据集,数据(存储为列表)由 ML.Net 应用程序获取以训练机器学习模型。 训练后,模型存储在本地模型存储中并缓存模型路径。
- 一旦将新数据块添加到缓存中,Pub/Sub 就会通知重新训练模型应用程序数据更新。 当应用程序获取任何新数据时,根据滑动窗口的概念,之前的数据块的一部分将被删除。 在此,根据新数据集的长度,删除先前使用的数据的第一部分。 修剪后的数据与新数据合并并添加到缓存中。 现在,这块数据和已经训练好的模型将在重新训练新模型时使用。
- 在模型的每次训练/再训练之后,对转换后的数据进行单值预测以测试模型的准确性。
NCache 更多信息 NCache 机器学习 GitHub 解决方案
使用数据结构缓存行程数据
NCache 提供 IEnumerable
分布式数据结构,这使得 ML.NET 直接获取和读取数据变得非常简单,因为 ML.NET 支持 LoadFromEnumerable()
. 数据可以方便地存储在 List 数据类型中,并直接加载到 ML.NET 模型中进行训练。
以下代码片段显示了如何使用 List 数据结构将数据存储在缓存中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Create lists in cache to add trip data IDistributedList initialDataList = Cache.DataTypeManager.CreateList(initialData); IDistributedList TrainingData = Cache.DataTypeManager.CreateList(datasetKey); using (StreamReader r = new StreamReader(filepath)) { while ((currentLine = r.ReadLine()) != null) { string[] incomingData = currentLine.Split(","); TaxiTrip data = new TaxiTrip(); data.TripTime = float.Parse(incomingData[0]); ... initialDataList.Add(data); TrainingData.Add(data); } } |
NCache 更多信息 NCache 机器学习 GitHub 解决方案
获取内存数据以训练模型
为了最初训练 ML.NET 模型,应用程序首先获取存储为 列表数据类型 止 NCache. 该模型是基于 随机双坐标上升 (SDCA) 回归算法并以 .zip 文件的形式保存以备后用。 这些保存的文件将来用于重新训练模型。 模型路径也被缓存以供以后使用。
1 2 3 4 5 6 7 8 9 10 11 |
// Get initial data for training from cache as list var datasetTraining = Cache.DataTypeManager.GetList(initialdataKey); var inputDataView = mlContext.Data.LoadFromEnumerable(datasetTraining); // ... Train Model logic here mlContext.Model.Save(trainedModel, transformedData.Schema, ModelPath); ModelTrained = true; // Save ModelPath in cache to use for retraining Cache.Add(ModelPath, ModelPath); |
使用 Pub/Sub 数据更新通知来重新训练模型
运用 NCache“ 发布/订阅,当更多数据在缓存中更新时,会向应用程序触发事件以重新训练数据。 ML.NET 应用程序订阅 NCache 有关正在更新的数据的通知主题。 如果缓存中的数据有更新, NCache Pub/Sub 通知应用程序数据已更新,并重新训练数据。
1 2 3 4 5 6 7 8 9 10 11 12 |
Cache = CacheManager.GetCache("myPartitionedCache"); // Create topic so ML.NET app subscribes for data update notifications Topic = Cache.MessagingService.CreateTopic("TaxiFareNotifications"); Topic.CreateSubscription(TaxiFareDataUpdated); ... // Retrain model when new data is updated static void TaxiFareDataUpdated(object sender, MessageEventArgs args) { RetrainModel(new MLContext(seed: 0)); } |
使用列表滑动数据以重新训练模型
将新数据添加到缓存后,使用滑动窗口概念填充训练数据以获取最新数据。 这会在列表中保留一大块以前的数据以及新数据。 更新数据后,将使用以下方式向订阅者发布消息 NCache“ 发布/订阅 机制,以便可以进行再培训。 模型和管道从 .zip 文件中加载,并根据 ML.NET 重新训练算法进行重新训练。
第 1 步:幻灯片数据并通过 Pub/Sub 通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
TaxiTrip data = new TaxiTrip(); ... dataList.Add(data); if(dataList.Count > 100) { // Move sliding window if (TrainingData.Count > dataList.Count) TrainingData.RemoveRange(0, dataList.Count); TrainingData.AddRange(dataList); // Publish message for notifying data update Topic.Publish(new Message("DataSet has been updated."), DeliveryOption.All); } |
第 2 步:从缓存中加载行程数据并重新训练模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//Load new data from List in Cache IDataView newData = mlContext.Data.LoadFromEnumerable(TrainingData); IDataView transformedNewData = dataPrepPipeline.Transform(newData); // Retrain model RegressionPredictionTransformer retrainedModel = mlContext.Regression.Trainers.OnlineGradientDescent() .Fit(transformedNewData, originalModelParameters); LinearRegressionModelParameters retrainedModelParameters = retrainedModel.Model as LinearRegressionModelParameters; IEstimator dataPrepEstimator = mlContext.Transforms.Concatenate("Features", new string[] { "PassengerCount", "TripTime", "TripDistance", "FareAmount" }) .Append(mlContext.Transforms.NormalizeMinMax("Features")); ... mlContext.Model.Save(retrainedModel, transformedNewData.Schema, ModelPath); |
NCache 更多信息 NCache 机器学习 GitHub 解决方案
把它们加起来…
通常,当为机器学习处理数据时,它是异步加载的,因此训练模型从磁盘加载数据并在其上多次执行其算法。 因此,在内存中缓存数据集 NCache 有助于减少不必要的磁盘数据加载,并更容易通过其 Pub/Sub 机制通知 ML.NET 应用程序立即开始重新训练。 此外,由于是分布式的,如果数据集太大,它会在运行时扩展。 所以,去结账 NCache 以及它如何提高您的机器学习应用程序性能!