• 机器学习框架ML.NET学习笔记【7】人物图片颜值判断


    一、概述

     这次要解决的问题是输入一张照片,输出人物的颜值数据。

    学习样本来源于华南理工大学发布的SCUT-FBP5500数据集,数据集包括 5500 人,每人按颜值魅力打分,分值在 1 到 5 分之间。其中包括男性、女性、中国人、外国人四个分类。

    SCUT-FBP5500_full.csv文件标记了每个图片人物的颜值打分数据。(我把分值一项乘以了20,变成了满分100分,不影响计算结果)

    整个程序处理流程和前一篇图片分类的基本一致,唯一的区别,分类用的是多元分类算法,这次采用的是回归算法。

    二、源码

     下面是全部代码:

    namespace TensorFlow_ImageClassification
    {    
    
        class Program
        {
            //Assets files download from:https://gitee.com/seabluescn/ML_Assets
            static readonly string AssetsFolder = @"D:StepByStepBlogsML_Assets";
            static readonly string TrainDataFolder = Path.Combine(AssetsFolder, "FaceValueDetection", "SCUT-FBP5500");
            static readonly string TrainTagsPath = Path.Combine(AssetsFolder, "FaceValueDetection", "SCUT-FBP5500_asia_full.csv");
            static readonly string TestDataFolder = Path.Combine(AssetsFolder, "FaceValueDetection", "testimages");
            static readonly string inceptionPb = Path.Combine(AssetsFolder, "TensorFlow", "tensorflow_inception_graph.pb");
            static readonly string imageClassifierZip = Path.Combine(Environment.CurrentDirectory, "MLModel", "imageClassifier.zip");
    
            //配置用常量
            private struct ImageNetSettings
            {
                public const int imageHeight = 224;
                public const int imageWidth = 224;
                public const float mean = 117;
                public const float scale = 1;
                public const bool channelsLast = true;
            }
    
            static void Main(string[] args)
            {
                TrainAndSaveModel();
                LoadAndPrediction();
    
                Console.WriteLine("Hit any key to finish the app");
                Console.ReadKey();
            }
    
            public static void TrainAndSaveModel()
            {
                MLContext mlContext = new MLContext(seed: 1);
    
                // STEP 1: 准备数据
                var fulldata = mlContext.Data.LoadFromTextFile<ImageNetData>(path: TrainTagsPath, separatorChar: ',', hasHeader: true);
                var trainTestData = mlContext.Data.TrainTestSplit(fulldata, testFraction: 0.2);
                var trainData = trainTestData.TrainSet;
                var testData = trainTestData.TestSet;
    
                // STEP 2:创建学习管道
                var pipeline = mlContext.Transforms.LoadImages(outputColumnName: "input", imageFolder: TrainDataFolder, inputColumnName: nameof(ImageNetData.ImagePath))
                    .Append(mlContext.Transforms.ResizeImages(outputColumnName: "input", imageWidth: ImageNetSettings.imageWidth, imageHeight: ImageNetSettings.imageHeight, inputColumnName: "input"))
                    .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "input", interleavePixelColors: ImageNetSettings.channelsLast, offsetImage: ImageNetSettings.mean))
                    .Append(mlContext.Model.LoadTensorFlowModel(inceptionPb).
                         ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))
                    .Append(mlContext.Regression.Trainers.LbfgsPoissonRegression(labelColumnName: "Label", featureColumnName: "softmax2_pre_activation"));
    
    
                // STEP 3:通过训练数据调整模型             
                ITransformer model = pipeline.Fit(trainData);          
    
                // STEP 4:评估模型           
                var predictions = model.Transform(testData); 
                var metrics = mlContext.Regression.Evaluate(predictions, labelColumnName: "Label", scoreColumnName: "Score");
                PrintRegressionMetrics( metrics);          
    
                //STEP 5:保存模型
                Console.WriteLine("====== Save model to local file =========");
                mlContext.Model.Save(model, trainData.Schema, imageClassifierZip);
            }
    
            static void LoadAndPrediction()
            {
                MLContext mlContext = new MLContext(seed: 1);
    
                // Load the model
                ITransformer loadedModel = mlContext.Model.Load(imageClassifierZip, out var modelInputSchema);
    
                // Make prediction function (input = ImageNetData, output = ImageNetPrediction)
                var predictor = mlContext.Model.CreatePredictionEngine<ImageNetData, ImageNetPrediction>(loadedModel);
                
                DirectoryInfo testdir = new DirectoryInfo(TestDataFolder);
                foreach (var jpgfile in testdir.GetFiles("*.jpg"))
                {
                    ImageNetData image = new ImageNetData();
                    image.ImagePath = jpgfile.FullName;
                    var pred = predictor.Predict(image);
    
                    Console.WriteLine($"Filename:{jpgfile.Name}:	Predict Result:{pred.FaceValue}");
                }
            }       
        }
    
        public class ImageNetData
        {
            [LoadColumn(0)]
            public string ImagePath;
    
            [LoadColumn(1)]
            public float Label;
        }
    
        public class ImageNetPrediction
        {
            [ColumnName("Score")]
            public float FaceValue;
        }   
    }
    View Code

      

    三、分析

    1、数据处理通道

    // STEP 2:创建学习管道
    var pipeline = mlContext.Transforms.LoadImages(...)
        .Append(mlContext.Transforms.ResizeImages(...)
        .Append(mlContext.Transforms.ExtractPixels(...)
        .Append(mlContext.Model.LoadTensorFlowModel(inceptionPb)
            .ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))    
    .Append(mlContext.Regression.Trainers.LbfgsPoissonRegression(labelColumnName: "Label", featureColumnName: "softmax2_pre_activation"));

     LoadImages、ResizeImages、ExtractPixels:上篇文章都已经介绍过了;

    ScoreTensorFlowModel方法把图片像素值转换为图片特征数据,并存储在softmax2_pre_activation列,Label列保存的是颜值数据,通过回归算法形成模型,当输入新的特征数据时就可以得出对应的颜值数据。

    算法采用的是:L-BFGS Poisson Regression (拟牛顿法泊松回归)

     

    2、预测结果

     在网上找了一些大头照,通过程序进行预测,右侧是预测结果:

    预测结果虽然和我认为的不完全一致,但总体上可以接受,大方向没什么问题,存在偏差主要有以下几个因素:

    1、学习样本的客观性存疑,其打分数据可能是分配给多人打分后汇总的,每个人标准不一致;

    2、被检测图片不是很规范,如尺寸、比例、背景、使用美颜软件等;

    3、颜值本身就不具备客观性,不存在标准答案,如果我说林心如比如花漂亮,大家肯定都同意,但我如果说古力娜扎比迪丽热巴漂亮,肯定有人不赞成。

    四、资源获取 

    源码下载地址:https://github.com/seabluescn/Study_ML.NET

    工程名称:TensorFlow_FaceValueDetection

    资源获取:https://gitee.com/seabluescn/ML_Assets (SCUT-FBP5500)

    点击查看机器学习框架ML.NET学习笔记系列文章目录

  • 相关阅读:
    HTML之元素分类(HTML基础知识)
    GreenPlum 与hadoop什么关系?(转)
    安装配置MySQL
    Linux下安装jdk步骤
    Linux ssh无密码登录
    左右无间切换走马灯angularJS指令
    CSS3制作立方体--有趣的应用
    hello,2017
    渐进增强与优雅降级
    图片上传预览(包含大小压缩)
  • 原文地址:https://www.cnblogs.com/seabluescn/p/10947650.html
Copyright © 2020-2023  润新知