zoukankan      html  css  js  c++  java
  • one-vs-all案例

    使用one-vs-all初始手写字母识别

    数据特点

    • 每一个图片都是20 x 20的像素矩阵,但是在输入的样本中是一个1 x 400的向量,标签y在{0, 1, 2, ..., 9}之间取值
    • 共有5000个训练样本

    可视化数据

    • 从5000个样本中随机的挑选出100个训练样本进行可视化
    • 得到的100个样本中,每一个样本都是一个向量,要想对其可视化,需要将其从向量还原为原始的矩阵
    • 首先确定矩阵的高和宽(单位是像素pixel)
    • 创建一个displayArray矩阵,用来保存100个样本转换为矩阵的像素数据,形象地讲,就是将100个图片放到一个大的面板上,这样才能做到可视化数据
    • 初始完毕displayArray矩阵之后,使用matlib中的imagesc函数将其显示出来
    • 代码如下:
    • myDisplayData.m
    function [h, displayArray] = myDisplayData(X)
    
    % 获取一张图片的高和宽
    exampleHeight = round(sqrt(size(X(1, :), 2)));
    exampleWidth = round(size(X(1, :), 2) / exampleHeight);
    
    % 计算整个面板的高和宽(但是是图片的个数)
    [m, n] = size(X);
    displayRows = round(sqrt(m));
    displayCols = round(m / displayRows);
    
    % 先创建出displayRows * exampleHeight, displayCols * exampleWidth的面板
    displayArray = ones(displayRows * exampleHeight, displayCols * exampleWidth);
    
    % 将图片放到面板对应的位置上
    % 下面的式子就和数学有一些关系,如何确定现在填充的矩阵在displayArray中的位置
    currExample = 1;
    for i = 1:displayRows
        for j = 1:displayCols
            displayArray(...
                         (i - 1) * exampleWidth + 1:exampleWidth + (i - 1) * exampleWidth, ...
                         (j - 1) * exampleHeight + 1:exampleHeight + (j - 1) * exampleHeight ...
                         ) = ...
                                                     reshape(X(currExample, :), ...
                                                     exampleHeight, exampleWidth);
            currExample = currExample + 1;
        end
    end
    
    colormap(gray);
    h = imagesc(display_array);
    axis image off;
    end
    

    数据预处理

    • 为X添加bias(偏移量): X = [ones(m, 1), X]; % m表示样本的数量
    • m: 训练样本的数量
    • n: 特征的数量,不包括bias(偏移)特征
    • y: 标签,{0, 1, 2, ..., 9}
    • numLabel: y可以取的值的个数,这里为10

    确定假设函数

    • 由题目可知,这是一个典型的Multi-Class Logistic Regression问题,因此使用逻辑回归模型
    • 模型函数: $$h( heta)=g( heta{T}x)={{1}over{1+e{- heta^{T}x}}}$$
    • 因为这个一个10分类的问题,所以需要拟合出10个假设函数才行,也就是要最小化出10个( heta)向量,我们调用oneVsAll函数返回的参数应该是一个矩阵,每一个行向量是一个类别的假设函数的参数

    计算损失函数(cost function)和梯度

    • 损失函数公式: $$J( heta)={{1}over{m}}sum_{i=1}m(-y{(i)}log(h_{ heta}(x^{(i)})) - (1-y{(i)})log(1-h_{ heta}(x{(i)})))+{{lambda}over{2m}}sum_{j=1}m{ heta_{j}2}$$其中( heta), (y^{(i)}), (x^{(i)})为向量或者矩阵,后一项是对非偏差项的正则化
    • 梯度公式: j >= 1 $${{partial}over{partial} heta_{j}}J( heta)={{1}over{m}}sum_{i=1}m{(h_{ heta}(x{(i)})-y{(i)})x{(i)}} + {{lambda}over{m}} heta_{j}$$ j = 0 $${{partial}over{partial} heta_{0}}J( heta)={{1}over{m}}sum_{i=1}m{(h_{ heta}(x{(i)})-y{(i)})x{(i)}}$$
    • 注意,上面的(h_{ heta}(x^{(i)}))是sigmoid函数,自己在实现的时候总是将其写成线性回归函数

    在oneVsAll.m文件中实现(minimize_{ heta}J( heta))

    • 每一个类都进行梯度下降,计算出这一类的参数,也就是写一个循环,在每一个循环中都有可以得到最终的这个类别对应的参数,循环的次数为numLabels

    • 核心代码

      for index = 1:numLabels 
        initialTheta = zeros(n + 1, 1);
        options = optimset('GradObj', 'on', 'MaxIter', 50);
        % fmincg会自动选择最优的学习率alpha
        allTheta(index, :) = fmincg(@(t)(lrCostFunction(t, X, (y == index), lambda)), ...
                                initialTheta, options);
      

    end

    
    ## 预测
    
    + 输入的一个样本,需要为其添加bias值,在将样本分别输入到10个假设函数中,计算出最大的值,那个值对应的就是类别。
    + 核心代码
    
    ```matlib
    tmp = zeros(m, num_labels);
    for i = 1:num_labels
      tmp(:, i) = sigmoid(X * allTheta(i, :)');
    end
    [val, p] = max(tmp, [], 2);
    
  • 相关阅读:
    设计模式学习工厂模式
    vector详解
    sizeof() c++primer
    list vector
    vc windows 服务问题:服务没有及时响应启动或控制请求
    程序员规范
    c++ map
    省略符形参
    SQL2005附加数据库时遇到的问题:用户组或角色在当前数据库已存在 .
    Socket 阻塞
  • 原文地址:https://www.cnblogs.com/megachen/p/9955749.html
Copyright © 2011-2022 走看看