AI在线 AI在线

C#与AI联姻:零依赖!用Keras.NET训练深度学习模型实录

在C#中实现深度学习通常需要依赖复杂的框架,但通过Keras.NET,我们可以在零外部依赖的情况下训练强大的深度学习模型。 下面我将分享一个完整的实战案例,展示如何用C#和Keras.NET训练一个图像分类模型。 这个实现具有以下特点:零外部依赖:仅使用Keras.NET和Numpy.NET库,无需安装Python或其他深度学习框架完整的训练流程:包括模型构建、数据加载、训练、评估和保存卷积神经网络:使用现代CNN架构进行图像分类模型检查点:自动保存验证集表现最佳的模型灵活的配置:可调整图像尺寸、批次大小和训练轮数要运行此代码,你需要安装以下NuGet包:Keras.NETNumpy.NETSciSharp.TensorFlow.Redist在实际应用中,你需要替换LoadData方法中的模拟数据加载逻辑,使用真实的图像数据。

在C#中实现深度学习通常需要依赖复杂的框架,但通过Keras.NET,我们可以在零外部依赖的情况下训练强大的深度学习模型。下面我将分享一个完整的实战案例,展示如何用C#和Keras.NET训练一个图像分类模型。

这个实现具有以下特点:

  1. 零外部依赖:仅使用Keras.NET和Numpy.NET库,无需安装Python或其他深度学习框架
  2. 完整的训练流程:包括模型构建、数据加载、训练、评估和保存
  3. 卷积神经网络:使用现代CNN架构进行图像分类
  4. 模型检查点:自动保存验证集表现最佳的模型
  5. 灵活的配置:可调整图像尺寸、批次大小和训练轮数

要运行此代码,你需要安装以下NuGet包:

  • Keras.NET
  • Numpy.NET
  • SciSharp.TensorFlow.Redist

在实际应用中,你需要替换LoadData方法中的模拟数据加载逻辑,使用真实的图像数据。你可以使用如ImageSharp等库来处理图像加载和预处理。

通过这种方法,你可以在C#环境中完全实现深度学习模型的训练和部署,无需依赖Python环境,特别适合需要集成深度学习功能的.NET应用程序。

复制
using Keras;
using Keras.Layers;
using Keras.Models;
using Keras.Optimizers;
using Numpy;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;


namespace DeepLearningExample
{
    public class DeepLearningTrainer
    {
        private Sequential model;


        // 构建卷积神经网络模型
        public void BuildModel(int imgWidth, int imgHeight, int numClasses)
        {
            // 创建序贯模型
            model = new Sequential();


            // 添加卷积层和池化层
            model.Add(new Conv2D(32, new Shape(3, 3), activation: "relu", input_shape: new Shape(imgWidth, imgHeight, 3)));
            model.Add(new MaxPooling2D(pool_size: new Shape(2, 2)));


            model.Add(new Conv2D(64, new Shape(3, 3), activation: "relu"));
            model.Add(new MaxPooling2D(pool_size: new Shape(2, 2)));


            model.Add(new Conv2D(128, new Shape(3, 3), activation: "relu"));
            model.Add(new MaxPooling2D(pool_size: new Shape(2, 2)));


            // 展平并添加全连接层
            model.Add(new Flatten());
            model.Add(new Dense(128, activation: "relu"));
            model.Add(new Dropout(0.5));
            model.Add(new Dense(numClasses, activation: "softmax"));


            // 编译模型
            var opt = new Adam(lr: 0.001f);
            model.Compile(optimizer: opt, loss: "categorical_crossentropy", metrics: new string[] { "accuracy" });


            Console.WriteLine("模型结构已构建:");
            model.Summary();
        }


        // 加载图像数据
        public (NDarray xTrain, NDarray yTrain, NDarray xVal, NDarray yVal) LoadData(string dataPath, int imgWidth, int imgHeight)
        {
            Console.WriteLine($"开始加载数据: {dataPath}");


            // 这里应该实现实际的图像加载和预处理逻辑
            // 为简化示例,我们创建一些随机数据作为占位符
            int trainSamples = 8000;
            int valSamples = 2000;


            // 创建随机训练数据
            var xTrain = np.random.rand(trainSamples, imgWidth, imgHeight, 3);
            var yTrain = np.zeros((trainSamples, 10));


            // 创建随机验证数据
            var xVal = np.random.rand(valSamples, imgWidth, imgHeight, 3);
            var yVal = np.zeros((valSamples, 10));


            // 为简化示例,随机分配类别
            for (int i = 0; i < trainSamples; i++)
            {
                int label = new Random().Next(0, 10);
                yTrain[i, label] = 1;
            }


            for (int i = 0; i < valSamples; i++)
            {
                int label = new Random().Next(0, 10);
                yVal[i, label] = 1;
            }


            Console.WriteLine($"数据加载完成: 训练样本={trainSamples}, 验证样本={valSamples}");
            return (xTrain, yTrain, xVal, yVal);
        }


        // 训练模型
        public void TrainModel(NDarray xTrain, NDarray yTrain, NDarray xVal, NDarray yVal, int epochs = 10, int batchSize = 32)
        {
            Console.WriteLine($"开始训练模型: 轮数={epochs}, 批次大小={batchSize}");


            // 设置回调函数
            var callbacks = new List<BaseCallback>
            {
                new ModelCheckpoint("best_model.h5", monitor: "val_accuracy", save_best_only: true, verbose: 1),
                new EarlyStopping(monitor: "val_loss", patience: 3, verbose: 1),
                new TensorBoard(log_dir: "logs", histogram_freq: 1)
            };


            // 训练模型
            var history = model.Fit(xTrain, yTrain, 
                batch_size: batchSize, 
                epochs: epochs,
                validation_data: new NDarray[] { xVal, yVal },
                callbacks: callbacks.ToArray(),
                verbose: 1);


            // 输出训练结果
            Console.WriteLine("训练历史:");
            foreach (var key in history.HistoryDict.Keys)
            {
                Console.WriteLine($"{key}: {string.Join(", ", history.HistoryDict[key].Select(v => v.ToString("0.0000")))}");
            }
        }


        // 评估模型
        public void EvaluateModel(NDarray xVal, NDarray yVal)
        {
            Console.WriteLine("开始评估模型...");
            var scores = model.Evaluate(xVal, yVal, verbose: 1);
            Console.WriteLine($"验证集损失: {scores[0]:0.0000}");
            Console.WriteLine($"验证集准确率: {scores[1] * 100:0.00}%");
        }


        // 保存模型
        public void SaveModel(string modelPath)
        {
            Console.WriteLine($"保存模型到: {modelPath}");
            model.Save(modelPath);
        }
    }
}

相关资讯