吴承恩机器学习作业3 4 手写数字的识别

题目要求

题目给出了5000张像素为400的图片,都为手写的1到10,要求用这些图片作为训练集,能识别其他的手写数字。用逻辑回归实现多分类和神经网络实现。

刚开始听到用像素点做识别还觉得挺不可思议的,以为识别用的都是先用梯度识别轮廓然后归类这种。但看完代码的实现过程,是把每个像素作为特征。想想实际上写数字,同样的图片大小,基本写的区域也差不多,有笔迹的区域应该也差不多,做回归预测理论上也可行,却没想到可以达到95%这么高的正确率。

有个疑问是所给数据中X矩阵存的像素数据是【-1,1】的值,是把灰度值归一到这个区间上吗,而且具体值的意义不大?只要知道这个区域有没有笔迹不就好了?或许这个值和落笔轻重也有关系?不管怎么说,带进去回归能出来就是了

一、多类logistic回归实现

总体思路

首先利用公式给出J(seita)和梯度的表达式,调用fmincg函数直接用高级优化给出训练的结构。注意在调整seita参数的值时,是用一个for循环,对1到10十个数分别进行识别(0或1),优化出10组seita集合,即 是n的时候有一组对应的seita集合使输出为1(n为1到10任意值)。
预测的过程就是把输入和10各seita集相乘,找出其中输出最大的一个seita集对应的数字即可(也就是对应概率最大的,sigmoid函数的输出就是概率)

关于公式使用

要注意sigmoid函数和线性回归虽然J(seita)求偏导的表达式相同(推出来相同而已,可认为是偶然),但其中h函数不一样,J(seita)不一样。
在这里插入图片描述

二、神经网络实现(前馈传播)

是一个3层神经网络,要求使用所给权重进行预测
由于图像大小为20×20,因此我们有400个输入层单元(不包括总是输出+1的额外偏置单元),第二层有25个单元和10个输出单元(对应于10个数字类别)

题目中已经给出了seita,所以关键的调seita矩阵的工作就不需要我们做了,只需要根据他们的关系一层层往后变换就可以了,所以J,grad也不用求,算是学反向传播前的代码铺垫。
在这里插入图片描述
其实就是逐步映射将特征逐渐减少,最后变成10个输出,然后给任何一个图片就可以根据它的401个特征输出10个特征,看

X = [ones(m,1) X];
a2 = sigmoid(X*Theta1');%5000x401乘以401x25得到5000x25。即把401个feature映射到25
a2 = [ones(size(a2,1),1) a2];
a3 = (sigmoid(a2*Theta2'));%5000x26乘以26x10得到5000x10。即把26个feature映射到10
[c, p] = max(a3, [], 2);

三、反馈神经网络的整体实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于代码的一些记录

1、图片数据是存储在ex3data1.mat中的,运行如下代码之后会生成X和y两个变量

load('ex3data1.mat'); % training data stored in arrays X, y

有5000张图,每张图有400个像素点,也就是400个特征,X中存储图片的灰度强度(但是不知道为什么值好像都是-1到1的值,归一化到-1,1?);y中是图片对应的数值1到10
在这里插入图片描述
matlab批量图片导出图片大小,MATLAB实例:将批量的图片保存为.mat文件.
MATLAB将批量的图片保存为mat文件.

2、随机显示所有图片中的100张

randperm(m)函数把1到m的m个数打乱顺序

% Randomly select 100 data points to display
rand_indices = randperm(m);%1到m这些数随机打乱得到的一个数字序列
sel = X(rand_indices(1:100), :);

displayData(sel);

3、关于矩阵运算

3.1为了运算生成的新y

h = eye(10);%10*10
y = h(y,:);%y原来是5000*1 !!!.y矩阵中的数是对应的行数

最后生成的y是5000*10,前500行为第十列全1,第二个500行为第1列全为1,第三个500行为第2列全为1

3.2算代价函数J的时候用了矩阵的点乘(两个矩阵维度相同时可用)

J = sum(sum(-y.*log(a3) - (1-y).*log(1-a3)))/m;
注意sum是按列求和

注意之前的J是直接矩阵相乘即可,而这里神经网络的公式中有两层求和,需要使用 “矩阵点乘,sum,再sum” 的方式计算。 如果使用矩阵相乘省略一层sum,结果会出错。

3.3矩阵求和
在这里插入图片描述
补:上面举例的sum(A)是对列求和,但是当sum中的矩阵是一个向量时就是其中的数相加。如sum([4,2])=6,所以最后J求出来才是一个数值

3.4矩阵操作
参考ch2 Matlab矩阵的生成与运算.内容很全
在这里插入图片描述
在这里插入图片描述


data = rand(4,4) %初始化1[0,1]4*4的随机矩阵
a = data(:,1) %取data的所有行,第1列
b = data(:,[1,3]) %取所有行,第13列
c = data([2,3],[1,2]) %%取第23行,以及12data(:) 就是把矩阵的元素按列的顺序变为一列,矩阵转化为向量

在这里插入图片描述
矩阵的删除
在这里插入图片描述

4、求准确率的方法

注意其中pred 和 y是两个矩阵,通过计算矩阵中有多少对应元素相等来算准确率。

fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);%求准确率的方法

5、关于出现的“…",是换行用的

%以下两种函数表达方式相同,加...是因为换行,对应中文的句号“。”
% function [J grad] = nnCostFunction(nn_params, ...
%                                    input_layer_size, ...
%                                    hidden_layer_size, ...
%                                    num_labels, ...
%                                    X, y, lambda)
function [J grad] = nnCostFunction(nn_params, input_layer_size,hidden_layer_size, num_labels,X, y, lambda)

6、randperm

将一列序号随机打乱,序号必须是整数。
sel = randperm(m);% 是把1到n这些数随机打乱得到的一个数字序列。

 randperm(100,5)
ans =
91 37 11 76 38
这个意思是将前100个数中,随机选择5个。所以randperm(n,m)中,n一定大于等于m。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值