【机器学习】使用Matlab和CNN完成回归任务

文章目录

前言

今天我们完成一个需求:给不同图片打上一个量化的标签,将图像作为输入,量化标签(浮点数)作为输出。我们的例子为:一个柔性视觉力度传感器:随着力的大小变化,弹性体发生形变,输出即为力的大小。

本文只提供部分技术的解决方案。

一、数据集的制作

使用通常的应变力传感器来完成标定,给图片打上标签。

【机器学习】使用Matlab和CNN完成回归任务

; 二、网络构建与训练

1. 图像预处理

我们相机拍摄的图片为1280×760。我们这里需要裁剪并缩小为56×56,并将其变为灰阶和二值化。

function preprocessed = preprocess(img)
    tmp = img(0:720, 240:960);
    tmp = imresize(tmp, [56, 56]);
    tmp = im2gray(tmp);
    preprocessed = imbinarize(tmp);
end

2. 训练数据生成

按照80%和20%的分组将数据集分为训练集和测试集。

function [XTrain, YTrain, XValidation, YValidation] = generateTrainData(sourcePath)
    imds = imageDatastore(sourcePath, 'IncludeSubfolders', true, 'LabelSource', 'foldernames');
    [dsTrain, dsVal] = splitEachLabel(imds, 0.8, 0.2, 'randomized');
    [XTrain, YTrain] = imds2array(dsTrain);
    [XValidation, YValidation] = imds2array(dsVal);
end

由于Matlab的回归任务需要将四维数组作为输入,我们还需要一个函数将图片集转换为4-D double数组。

function [X, T] = imds2array(imds)
    % imds2array   Convert an image datastore into a 4-D array
    %
    %   X       - Input data as an H-by-W-by-C-by-N array, where H is the
    %             height and W is the width of the images, C is the number of
    %             channels, and N is the number of images.

    %   T       - Categorical vector containing the labels for each
    %             observation.

    imagesCellArray = imds.readall();
    numImages = numel(imagesCellArray);
    [h, w, c] = size(imagesCellArray{1});

    X = zeros(h, w, c, numImages);

    for i = 1:numImages
        X(:, :, :, i) = im2double(imagesCellArray{i});
    end

    T = double(string(imds.Labels));
end

3. 网络构建

根据图片的特征,构建深度网络:

【机器学习】使用Matlab和CNN完成回归任务
layers = [
    imageInputLayer([56 56 1])
    convolution2dLayer(3,8,'Padding','same')
    batchNormalizationLayer
    reluLayer
    averagePooling2dLayer(2,'Stride',2)
    convolution2dLayer(3,16,'Padding','same')
    batchNormalizationLayer
    reluLayer
    averagePooling2dLayer(2,'Stride',2)
    convolution2dLayer(3,32,'Padding','same')
    batchNormalizationLayer
    reluLayer
    convolution2dLayer(3,32,'Padding','same')
    batchNormalizationLayer
    reluLayer
    dropoutLayer(0.2)
    fullyConnectedLayer(1)
    regressionLayer];

4. 指定参数并训练

miniBatchSize = 128;
validationFrequency = floor(numel(YTrain) / miniBatchSize);
options = trainingOptions('sgdm', ...

    'MiniBatchSize', miniBatchSize, ...

    'MaxEpochs', 100, ...

    'InitialLearnRate', 1e-4, ...

    'LearnRateSchedule', 'piecewise', ...

    'LearnRateDropFactor', 0.1, ...

    'LearnRateDropPeriod', 20, ...

    'Shuffle', 'every-epoch', ...

    'ValidationData', {XValidation, YValidation}, ...

    'ValidationFrequency', 10, ...

    'Plots', 'training-progress', ...

    'Verbose', false);

net = trainNetwork(XTrain, YTrain, layers, options);

三、试用网络

这里我们使用摄像头实时获取图片,需要Matlab的Image Acquisition Toolbox。
首先查询摄像机Adapter: imaqInfo = imaqhwinfo,输出:

InstalledAdaptors: {'winvideo'}
MATLABVersion: '9.11 (R2021b)'
ToolboxName: 'Image Acquisition Toolbox'
ToolboxVersion: '6.5 (R2021b)'

可以看到,存在的Adaptor只有 winvideo,继续查看 winvideo的信息: winvideoinfo = imaqhwinfo('winvideo'),找到 DeviceInfo,并找到USB Camera的ID。我这里为1。

【机器学习】使用Matlab和CNN完成回归任务
接下来调用相机:
vid = videoinput('winvideo', 1, 'MJPG_1280x720');
vid.TriggerRepeat = 100;
vid.FrameGrabInterval = 5;
% 加载训练好的网络
load("network.mat");
figure
hold on
i = 0;
start(vid)
while i < 2000
    if vid.FramesAvailable >= 1
        i = i + 1;
        img = getdata(vid, 1);
        img = preprocess2(img);
        inp = img2array(img);
        out = predict(net, inp);
        plot(i, double(out)/10, 'o');
        double(out) / 10
    end
end
stop(vid)

随着按下的力度变化,采集到的力度数据变化曲线如图所示:

【机器学习】使用Matlab和CNN完成回归任务
虽然值不是很准确,但是趋势是正确的。后续还需要继续调整网络结构和参数。

Original: https://blog.csdn.net/weixin_44488503/article/details/124552891
Author: 梦中梦?
Title: 【机器学习】使用Matlab和CNN完成回归任务

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/629718/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球