one-vs-all案例

简介: 使用one-vs-all初始手写字母识别数据特点每一个图片都是20 x 20的像素矩阵,但是在输入的样本中是一个1 x 400的向量,标签y在{0, 1, 2, ..., 9}之间取值共有5000个训练样本可视化数据从5000个样本中随机的挑选出100个训练样本进行可视化得到的10...

使用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(\theta)=g(\theta^{T}x)={{1}\over{1+e^{-\theta^{T}x}}}\]
  • 因为这个一个10分类的问题,所以需要拟合出10个假设函数才行,也就是要最小化出10个\(\theta\)向量,我们调用oneVsAll函数返回的参数应该是一个矩阵,每一个行向量是一个类别的假设函数的参数

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

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

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

  • 每一个类都进行梯度下降,计算出这一类的参数,也就是写一个循环,在每一个循环中都有可以得到最终的这个类别对应的参数,循环的次数为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个假设函数中,计算出最大的值,那个值对应的就是类别。
  • 核心代码
tmp = zeros(m, num_labels);
for i = 1:num_labels
    tmp(:, i) = sigmoid(X * allTheta(i, :)');
end
[val, p] = max(tmp, [], 2);
目录
相关文章
|
机器学习/深度学习 存储 人工智能
极智AI | 周易AIPU算法部署仿真测试
本教程详细记录了使用周易 AIPU 进行算法部署仿真测试的方法,带大家尝尝鲜。
524 0
|
存储 算法 Java
Java解压本地zip文件(zip4j)
Java解压本地zip文件(zip4j)
Java解压本地zip文件(zip4j)
|
机器学习/深度学习 人工智能 小程序
|
XML Java Maven
【Maven技术专题】「实战开发系列」盘点Maven项目中打包需要注意到的那点事儿
【Maven技术专题】「实战开发系列」盘点Maven项目中打包需要注意到的那点事儿
377 1
|
8月前
|
Java API 数据处理
方法引用和 Lambda 表达式详解
本文详细解析了Java 8中方法引用和Lambda表达式的特性和应用。Lambda表达式通过简化匿名内部类语法,提供函数式接口的实现方式,增强代码可读性与灵活性;方法引用作为其特例,进一步优化了对现有方法的调用。两者结合Stream API,极大提升了数据处理效率与代码简洁性。文章从理论到实践,深入探讨设计思想、语法特性及应用场景,帮助开发者掌握这两项核心工具,提升编程效率与代码质量。
171 0
|
Android开发
Android 如何将定制的Launcher成为系统中唯一的Launcher
Android 如何将定制的Launcher成为系统中唯一的Launcher
447 2
|
存储 编译器 C++
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
【C++练级之路】【Lv.13】多态(你真的了解虚函数和虚函数表吗?)
251 0
|
存储 监控 网络协议
GlusterFS的复制
【10月更文挑战第1天】GlusterFS的复制
194 2
|
XML 前端开发 Java
springMVC01,【第一个springMVC例子(注解版):HelloWorld】
文章介绍了如何使用注解配置创建第一个SpringMVC项目,并讲解了SpringMVC的执行流程,包括配置web.xml、编写springmvc-servlet.xml配置文件、创建带有@RequestMapping注解的控制器层以及运行测试和执行流程小结。
|
缓存 UED 开发者
全面加速Angular应用:从代码拆分到服务器端渲染的性能优化全攻略——深入探讨提升加载速度的有效策略
【8月更文挑战第31天】在现代Web开发中,提升应用加载速度对增强用户体验至关重要,尤其对于使用Angular框架的单页应用而言更是如此。本文通过解答五个常见问题,提供了一份全面的Angular性能优化攻略,涵盖减少初始加载时间、处理大型第三方库、优化变更检测、利用缓存以及服务器端渲染等技术。通过这些方法,开发者能够显著提升应用性能,确保流畅高效的用户体验。
282 0