C#與AI聯(lián)姻:零依賴!用Keras.NET訓(xùn)練深度學(xué)習(xí)模型實錄
在C#中實現(xiàn)深度學(xué)習(xí)通常需要依賴復(fù)雜的框架,但通過Keras.NET,我們可以在零外部依賴的情況下訓(xùn)練強大的深度學(xué)習(xí)模型。下面我將分享一個完整的實戰(zhàn)案例,展示如何用C#和Keras.NET訓(xùn)練一個圖像分類模型。
這個實現(xiàn)具有以下特點:
- 零外部依賴:僅使用Keras.NET和Numpy.NET庫,無需安裝Python或其他深度學(xué)習(xí)框架
 - 完整的訓(xùn)練流程:包括模型構(gòu)建、數(shù)據(jù)加載、訓(xùn)練、評估和保存
 - 卷積神經(jīng)網(wǎng)絡(luò):使用現(xiàn)代CNN架構(gòu)進行圖像分類
 - 模型檢查點:自動保存驗證集表現(xiàn)最佳的模型
 - 靈活的配置:可調(diào)整圖像尺寸、批次大小和訓(xùn)練輪數(shù)
 
要運行此代碼,你需要安裝以下NuGet包:
- Keras.NET
 - Numpy.NET
 - SciSharp.TensorFlow.Redist
 
在實際應(yīng)用中,你需要替換LoadData方法中的模擬數(shù)據(jù)加載邏輯,使用真實的圖像數(shù)據(jù)。你可以使用如ImageSharp等庫來處理圖像加載和預(yù)處理。
通過這種方法,你可以在C#環(huán)境中完全實現(xiàn)深度學(xué)習(xí)模型的訓(xùn)練和部署,無需依賴Python環(huán)境,特別適合需要集成深度學(xué)習(xí)功能的.NET應(yīng)用程序。
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;
        // 構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)模型
        public void BuildModel(int imgWidth, int imgHeight, int numClasses)
        {
            // 創(chuàng)建序貫?zāi)P?            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("模型結(jié)構(gòu)已構(gòu)建:");
            model.Summary();
        }
        // 加載圖像數(shù)據(jù)
        public (NDarray xTrain, NDarray yTrain, NDarray xVal, NDarray yVal) LoadData(string dataPath, int imgWidth, int imgHeight)
        {
            Console.WriteLine($"開始加載數(shù)據(jù): {dataPath}");
            // 這里應(yīng)該實現(xiàn)實際的圖像加載和預(yù)處理邏輯
            // 為簡化示例,我們創(chuàng)建一些隨機數(shù)據(jù)作為占位符
            int trainSamples = 8000;
            int valSamples = 2000;
            // 創(chuàng)建隨機訓(xùn)練數(shù)據(jù)
            var xTrain = np.random.rand(trainSamples, imgWidth, imgHeight, 3);
            var yTrain = np.zeros((trainSamples, 10));
            // 創(chuàng)建隨機驗證數(shù)據(jù)
            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($"數(shù)據(jù)加載完成: 訓(xùn)練樣本={trainSamples}, 驗證樣本={valSamples}");
            return (xTrain, yTrain, xVal, yVal);
        }
        // 訓(xùn)練模型
        public void TrainModel(NDarray xTrain, NDarray yTrain, NDarray xVal, NDarray yVal, int epochs = 10, int batchSize = 32)
        {
            Console.WriteLine($"開始訓(xùn)練模型: 輪數(shù)={epochs}, 批次大小={batchSize}");
            // 設(shè)置回調(diào)函數(shù)
            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)
            };
            // 訓(xùn)練模型
            var history = model.Fit(xTrain, yTrain, 
                batch_size: batchSize, 
                epochs: epochs,
                validation_data: new NDarray[] { xVal, yVal },
                callbacks: callbacks.ToArray(),
                verbose: 1);
            // 輸出訓(xùn)練結(jié)果
            Console.WriteLine("訓(xùn)練歷史:");
            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($"驗證集準(zhǔn)確率: {scores[1] * 100:0.00}%");
        }
        // 保存模型
        public void SaveModel(string modelPath)
        {
            Console.WriteLine($"保存模型到: {modelPath}");
            model.Save(modelPath);
        }
    }
}














 
 
 











 
 
 
 