一些前提的约定,还是沿用上篇文章的哈。先来致敬下男神。

一:人工神经网络(Artificial Neural Network)简介
它是一种模拟神经元网络组成的非线性分类算法,我们的大脑的基本组成是由一个个的神经元组成,大约有100亿个,而且每个神经元之间都是具有若干输入端和若干输出端,受到来自输出的刺激,决定输出,形成一个高度复杂高度灵活的动态网络。从而形成了我们的记忆和思维。
人工神经网络就是对这种结构的模拟实现,通过大量的基本单元,组成复杂的算法网络,设计相应的学习算法,模拟人脑的某种智能活动,然后在技术上实现出来用以解决实际问题。

二:ANN基本单元和组成。
ANN具有三层结构,输入层,隐藏层,输出层组成。

其中,最前端是输入层,就是根据样本的特征维度得到的。
最后一层是输出层,输出层可以有多个输出,因此可以完后多分类的实现。
其他的介于输入层和输出层之间的叫做隐藏层。隐藏层是此类复杂计算的隐式计算层,无法直接表明其代表的物理含义。
每一个单元,接受若干输入,经过计算输出给若干个其他的单元,组成复杂的计算系统。

在ANN网络中,最基本的单位如下图所示:


这是一个最基本的人工神经单元结构,就是由一个简单的线性组合和激励函数组成,其中Z = θX,激励函数就是我们上一博文学习的sigmoid函数。其实也就是这就是一个简单的逻辑斯特回归模型(logistic regression model),每一个单元的输出都是在[0,1]之间,模拟了神经元在兴奋和抑制两种状态,那么我们可以看到,在一个神经网络中,每个神经元的输出,都会只想大量的其他神经元,也就是由大量的基本的逻辑斯特回归模型组合而成,那么就会构建出超级复杂的非线性分类器。

三:神经元模拟逻辑运算单元(与/或/非/异或/同或)
1:与运算

真值表:
X1 X2 Z=θX h(Z) = y
0 0 -30 0
0 1 -10 0
1 0 -10 0
1 1 10 1

2:或运算

真值表:
X1 X2 Z=θX h(Z) = y
0 0 -10 0
0 1 10 1
1 0 10 1
1 1 30 1

3:非运算

真值表:
X1 Z=θX h(Z) = y
0 10 1
1 -10 0

因此我们可以发现,除了单个神经元可以组成一个较强大的逻辑回归,还可以做更简单的事情,形成简单且基本的逻辑运算,那么就跟数字电路一样,大量的逻辑运算组成在一起,就可以组成超级复杂的系统。神经网络也是基于此,由大量的基本简单的神经单元组成一起去做出复杂的系统。

四:多分类
当一个输出层有多个神经单元输出时,我们就可以实现多个分类。假设输出层与K个单元。
1)第一种多分类方法,可以表示K个分类,(K1, K2, K3……KK),某一个输入对应于只有一个单元输出是1,其他输出是0。这种比较好理解,也很清晰。

2)第二种分类方法,可以表示2^K 种分类,把K个单元看成是K个bit组成的数字,那么就会有2K组合。可以表示2K个分类。

五:前向传播算法(Forward propagation)

我们先来做好一些符号上的规定,天蓝色的代表输入层的单元,灰色代表隐藏层,淡橙色代表输出层。


好的,现在我们已经把这个网络的各个部分用数学符号描述出来了。接下来我们就去讲解前向转播。
一步步来:给定某个样本(x,y)。现在对每一层的单元进行向量化运算。

好了,结束了,到目前为止,根据输入的X得到最终的输出,这就是前向传播过程。
如果该网络还有更多层,按照同样的计算过程,就可以按照这种规律往下计算。

六:后向传播算法(Backward propagation)

按照惯例,我们这个网络存在大量的未知参数,怎么进行参数估计呢?又来了,找到某个代价函数,试图最小化这个代价函数,就又可以按照梯度下降等系列算法过程进行处理。

============================》
神经网络不同于logistic regression的之处在于,它可以有多个输出,logistic regression只有一个输出。

梯度下降再次搬出来瞅一瞅。

是不是觉得这个时候内心稍微一紧绷,这么复杂的公式,求偏导。我真的是给醉了。其实啊,别慌,这都是非常基本的求导过程,用到了链式求导法则的计算过程。

我们为了书写方便和理解方便,仅仅安排一个样本,一个输出,用来计算参数。然后就是累加就和操作就不讲了。


至此,我们把对参数的求偏导的过程已经全部证明了出来。具体具体实现和矩阵运算,就自行分析实现吧。这里是在单个实例和大哥输入的情况下的,多个实例和多个输出的情况下,也就是将其做累加运算。

一些骚话,我高数功底比较薄弱,但是基本简单的数学概念还是知道的,对于Andrew Ng的视频介绍,着实是没看懂每一步是具体怎么来的,视频里也没讲解,所以我就花了半天时间一步步推导。希望大家也能一起推导,这也是对学习的负责。现在看来好像也没啥难度哈。

现在我们就可以用梯度下降来进行参数迭代模拟了。

七:具体实践—基于ANN的OCR实现
光说不练假把式,来个实践操作搞一把。就拿OCR来说吧。

数据来源于MNIST手写数字数据库,地址:http://yann.lecun.com/exdb/mnist/
这里的每个数字图片都是28*28=784像素的灰度图像。数据分为两组,训练组和测试组。
训练组有60K个训练样本,有一个图像文件。每个像素占两个字节,将像素从上到下从左到右的顺序排列成一维向量,然后所有的图片的一位向量,紧挨着排在一起的组合的一个二进制文件,有一个标签文件。也是一个二进制文件,每个字节代表是数字0~9的其中一个,一个标签一个字节,和相应的图像的排列顺序一致。
测试组的文件格式和训练组一样,唯一不同的就是,它只有10K个样本供测试。后面的程序中也会介绍如何获取这些图像和标签信息。图示中(train开头就是训练数据集)

其实吧,单就所有像素来作为输入特征是很单一的,图像还有投影,直方图等其他特征。这里先暂时用所有像素点所谓特征实战吧。这里建立一个人工网络。

输入端有785的单元(1+28*28),1个隐藏层,分别有501个单元,输出层有10个单元。
前两层呢,第一个元素都是偏置(bias),用绿色表示。
附上计算过程:

加载测试集数据:将每个28*28的数据进行旋转,这样显示的就是我们查看的正常习惯视角上的数字,其实吧,这个操作对于模型来说没有任何意义,只要是像素按照一个规则排列,都是没问题的,我们习惯上是从上到下,从左到右。纯属个人爱好。关键的一步骤是将它二值化,这个操作是有很大意义的,尽量简化图片。这样减少不必要的信息量。

% =======================================================
% get test images
fidimg=fopen(‘D:/software/octave/doc/ANN/t10k-images-idx3-ubyte/t10k-images.idx3-ubyte’,‘rb’);
fidla=fopen(‘D:/software/octave/doc/ANN/t10k-labels-idx1-ubyte/t10k-labels.idx1-ubyte’,‘rb’);

[img, num]=fread(fidimg, 16);
[label, num]=fread(fidla, 8);
Test_N = 10000;
TestData=cell(Test_N,2);
for i=1:1:Test_N
[img, num]=fread(fidimg,[28,28]);
[label, num]=fread(fidla,1);

% mormalize this img,to make every pixel only values 1 or 0;
for j=1:1:28for k=1:1:28if img(j, k) > 20img(j, k) = 1;elseimg(j, k) = 0;end;end;
end;TestData{i,1}=rot90(flipud(img), 3);
TestData{i,2}=label;% write it into file as jpg format.
% na=['D:/software/octave/doc/ANN/tmp/', num2str(label), '-' ,num2str(i) , '.jpg'];%
% imwrite(rot90(flipud(img), 3),na) ;

end;

然后加载训练数据,方法如上一样,只是样本的个数有变化。
%

=======================================================
% get train images
fidimg=fopen(‘D:/software/octave/doc/ANN/train-images-idx3-ubyte/train-images.idx3-ubyte’,‘rb’)
fidla=fopen(‘D:/software/octave/doc/ANN/train-labels-idx1-ubyte/train-labels.idx1-ubyte’,‘rb’)

[img, num]=fread(fidimg, 16);
[label, num]=fread(fidla, 8);

train_N = 60000;
TrainData=cell(train_N,2);
for i=1:1:train_N
i
[img, num]=fread(fidimg,[28,28]);
[label, num]=fread(fidla,1);

% mormalize this img,to make every pixel only values 1 or 0;
for j=1:1:28for k=1:1:28if img(j, k) > 10img(j, k) = 1;elseimg(j, k) = 0;end;end;
end;TrainData{i,1}=rot90(flipud(img), 3);
TrainData{i,2}=label;   % write it into file as jpg format.
% na=['D:/software/octave/doc/ANN/tmp/',num2str(label),'-',num2str(i),'.jpg'];%
% imwrite(rot90(flipud(img), 3),na) ;

end;

接下来构造神经网络模型。

% construct the ANN
% input is 28*28 dimemsions (28 * 28 = 784 input units)(add bias 1)
% there is one hidden layer (512 hidden units)(add bias 1)
% output layer is (10 output units)

% constrcut the ANN
% set the theta and init its initial value. to
layer_num = [784+1, 500+1, 10];
L = size(layer_num)(2);

theta = cell(L-1, 1);
for i=1:1:L-1
if i == (L-1)
theta{i,1} = ones(layer_num(i+1), layer_num(i)) .* (0.0001 .+ 0.1 .* rand(layer_num(i+1), layer_num(i)));
else
theta{i,1} = ones(layer_num(i+1) - 1, layer_num(i)) .* (0.0001 .+ 0.1 .* rand(layer_num(i+1) - 1, layer_num(i)));
end;
end;

% set the a
a = cell(L, 1);
for i=1:1:L
a{i,1} = ones(layer_num(i), 1); % to make the first unit is bias == 1
end;

% set the Delta, there is no Delta(1).
Delta = cell(L, 1);
for i=2:1:L
Delta{i,1} = zeros(layer_num(i), 1);
end;

% do our work now.
itr = 1000; %iteration times
rate = 0.01; %step
cost = zeros(1, itr);

% if your computer has low cpu, choose small tarinset.
% so I choose 2000 smaple to tarin the model
M = size(TrainData)(1);
M = 5000;

% iterate many times
for it=1:itr

cost_sum = 0;for i=1:1:M% for every sample (X, Y)% forward propagationX = [1; reshape((TrainData{i, 1})', 784, 1)]; % original input X(every image)a{1,1} = X;    % first layer of activation units is X.for j=1:1:L-1z_next_layer = theta{j,1} * a{j,1};if j == (L-1)a{j+1, 1} = 1 ./ (1 + exp(-z_next_layer));elsea{j+1, 1} = [1; 1 ./ (1 + exp(-z_next_layer))];end;end;% get this sample's output% from top to buttom, is 0~9Y = zeros(size(a{L,1})(1), 1);Y(TrainData{i, 2} + 1) = 1;% get the cost, it contains all the K outputs.% but there is a big error is that if a{L,1} == 1, then log(1 - a{L,1}) == NaN% so we change another cost function to estimate cost.% cost_sum += (-1) * sum(Y .* log(a{L,1}) + (1 - Y) .* log(1 - a{L,1}));cost_sum += sum((Y - a{L,1}) .^ 2);% so now, we get the activation matrix, and we can cupute the cost.% backward propagation% first of all we must calculate all the Delta( from Delta{2} .... Delta{L}))Delta{L,1} = a{L,1} - Y;for j=L-1:-1:2if j == L-1Delta{j,1} = (theta{j,1}') * Delta{j+1,1} .* (a{j,1} .* (1 - a{j,1}));elseDelta{j,1} = (theta{j,1}') * (Delta{j+1,1}(2:size(Delta{j+1,1})(1),:)) .* (a{j,1} .* (1 - a{j,1}));end;end;% and then calaulate the theta% !!!!!!!!!!  this methord is to update theta based on every sample, !!!!!!!!!!!!!!!!!theta_temp = theta;for j=1:1:L-1if j == L-1theta_temp{j, 1} -= rate .* (Delta{j+1,1}) * (a{j,1}');elsetheta_temp{j, 1} -= rate .* (Delta{j+1,1}(2:size(Delta{j+1,1})(1),:)) * (a{j,1}');end;end;theta = theta_temp;end;% count the cost for each iteration
cost(it) = cost_sum / (M);
cost(it)

end;

% 画代价函数跟随迭代次数的收敛曲线
subplot(1, 1, 1);
xx = (1:1:itr);
scatter(xx, cost, ‘p’, ‘linewidth’, 3);
xlim([0,itr]);
ylim([0,1]);
%axis equal;
grid on;
hold on;
xlabel(‘iteration times’);
ylabel(‘cost value’);

我们很欣喜地看到,cost 在收敛,而且代价值很低很低,目测效果很好,用test 数据集合进行验证。

% and finally,  to check if this model is good enough?
% =======================================================Test by new data
Accuracy = 0;
K = size(a{L,1})(1);
M = size(TestData)(1);
for i=1:1:M% for every sample (X, Y)% forward propagationX = [1; reshape((TestData{i, 1})', 784, 1)]; % original input X(every image)a{1,1} = X;    % first layer of activation units is X.for j=1:1:L-1z_next_layer = theta{j,1} * a{j,1};if j == (L-1)a{j+1, 1} = 1 ./ (1 + exp(-z_next_layer));elsea{j+1, 1} = [1; 1 ./ (1 + exp(-z_next_layer))];end;end;% find the max possible output.max = 0;idx = 0;for j=1:1:Kif a{L,1}(j,1) >= maxmax = a{L,1}(j,1);idx = j;end;end;% fprintf('mdel=%s\n', 'as bolew...');% a{L,1}% no Accuracyif TestData{i, 2} + 1 == idxfprintf('it should be=%d\n', TestData{i, 2});fprintf('mdel=%d\n', idx);Accuracy++;end;
end;Accuracy = Accuracy/M

这里我们用的是1000次迭代,5000个训练样本,10000个测试样本,最后发现正确率能达到90%。
这里我用的是10000个测试样本测试的啊。

这里仅仅是用了一个例子,来说明神经网络的构造算法过程。后面还需要学习很多的。后面的文章继续分享了。

由于机器性能原因,我不是只拿了前5000个样本做训练么?我没忍住,就把整个训练集60000个样本都拿来测试了一把,结果也是没有令人失望啊。结果如下:我猜多出来那一小点应该是前5000个训练过的样本撑上去的。

我又随便找了一个数字,做成了28*28的图像,拿数据去测试。如下图,是个数字7

img = imread('D:/software/octave/doc/ANN/7.PNG');% 灰度化
gdata = 255 .- rgb2gray(img);% 二值化
for j=1:1:28for k=1:1:28if gdata(j, k) > 20gdata(j, k) = 1;elsegdata(j, k) = 0;end;end;
end;

验证如下:

Accuracy = 0;
K = 10;% for every sample (X, Y)
% forward propagation
X = [1; reshape((gdata)', 784, 1)]; % original input X(every image)
a{1,1} = X;    % first layer of activation units is X.
for j=1:1:L-1z_next_layer = theta{j,1} * a{j,1};if j == (L-1)a{j+1, 1} = 1 ./ (1 + exp(-z_next_layer));elsea{j+1, 1} = [1; 1 ./ (1 + exp(-z_next_layer))];end;
end;% find the max possible output.
max = 0;
idx = 0;
for j=1:1:Kif a{L,1}(j,1) >= maxmax = a{L,1}(j,1);idx = j;end;
end;fprintf('mdel=%s\n', 'as bolew...');
a{L,1}% no Accuracy
if 7 + 1 == idxfprintf('it should be=%d\n', 7);fprintf('mdel=%d\n', idx);Accuracy++;
end;Accuracy = Accuracy/1

结果也是OK的。

这里数字缺乏对很多图片的训练,比如标准格式的数字,彩印,空心化等很多数字图片样式的训练,因此还远远不够。但是算法核心基本大体上入如此了。

在操作实践方面,感谢以下几个链接的帮助:
https://zhuanlan.zhihu.com/p/87078890
https://blog.csdn.net/panrenlong/article/details/81736754
https://zhuanlan.zhihu.com/p/42174696

每天进步一点点《ML - 人工神经网络》相关推荐

  1. 每天进步一点点《ML - 感知机》

    一些前提的约定,还是沿用上篇文章的哈.先来致敬下男神. 一:感知机 感知机是一种线性二分类模型,其目的是找到能将训练数据线性可分的分离超平面.超平面线性模型为 联想起之前学到逻辑斯特回归的决策边界,Z ...

  2. 感知机介绍及MATLAB实现

    文章目录 前言 1 感知机简介 2 感知机结构 3 感知机学习过程 3.1 数据传播过程 3.2 参数更新过程 4 代码实现 4.1 准备数据 4.2 感知机训练学习 4.3 感知机仿真测试 总结 2 ...

  3. 每天进步一点点《ML - 线性回归》

    本系列Machine Learning 的学习博文很大部分全是受教于 Andrew Ng 的Stanford录制的ML视频,我的男神. 致敬男神! 第一次写这样系列的博文,单纯是为了记录自己的所学,做 ...

  4. 【ML】基于机器学习的心脏病预测研究(附代码和数据集,多层感知机模型)

    写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大努力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌. 之前创作过心脏病预测研究文章如下: [ML]基于机器学 ...

  5. 每天进步一点点《ML - 支持向量机》

    一些前提的约定,还是沿用上篇文章的哈.先来致敬下男神. 一:支持向量机(support vector machine) 在感知机那一章节我们讲了,对样本的分类过程中,可以用维度空间内的某个超平面划分开 ...

  6. 每天进步一点点《ML - 正则化代价函数》

    本系列Machine Learning 的学习博文很大部分全是受教于 Andrew Ng 的Stanford录制的ML视频,我的男神. 一:欠拟合(Under fitting)与过拟合(Over fi ...

  7. 每天进步一点点《ML - 高斯混合模型》

    上一篇文章学习了极大似然估计和EM算法,这一章节就是学习EM算法的具体应用场景,高斯混合模型,是一中聚类的算法. 一:高斯混合模型(GMM) 我们将一个分布复杂的数据分布,用多个高斯概率分布来共同表示 ...

  8. 每天进步一点点《ML - 从极大似然到EM算法》

    一:极大似然 1:概念引入 极大似然参数估计是概率论中学习过的内容,就是预先定义概率分布模型,根据一堆的同概率分布的一堆样本数据去估计该概率模型中的未知参数. 举个例子:有很多西瓜x,我们可以得到每一 ...

  9. 每天进步一点点《ML - Sklearn库简单学习》

    一:Sklearn介绍 Sklearn是一个强大的机器学习库,基于python的.官方文档(http://scikit-learn.org/stable/ ).如下列举部分的使用场景. 由图中,可以看 ...

  10. 每天进步一点点《ML - 异常点检测》

    一些前提的约定,还是沿用上篇文章的哈.先来致敬下男神. 一:异常点检查(Anomaly Detection) 这一章节相对来说简单很多,也可以说是很大程度是概率论的知识内容了. 异常点,和大部分正常状 ...

最新文章

  1. python出现typeerror原因是_Python 文件添加列表数据后TypeError原因
  2. 微服务架构 为什么需要配置中心
  3. 2005链接mysql_VISUAL STUDIO 2005连接MYSQL数据库
  4. 数学-矩阵计算(1)矩阵和向量的求导法则
  5. 十大下班最晚城市,四个在广东
  6. 名词解释:什么是RSS? [转贴]
  7. 对mysql having 的理解
  8. location.href参数丢失
  9. linux http嗅探工具 httpry
  10. 写DM9000网卡芯片驱动的预备知识
  11. sql注入实验一 ——合天网安实验室学习笔记
  12. 全国哀悼日 网站灰黑色CSS滤镜代码
  13. RL(Chapter 5): Monte Carlo Methods (MC) (蒙特卡洛方法)
  14. FastReport Mono 2023.1 Crack
  15. python迅雷远程下载页面_迅雷远程下载 linux
  16. 基于SpingBoot2.0与activiti7.x构建的一套工作流程管理系统
  17. 02、alex 说过“普通运维人员就是秋后的蚂蚱”
  18. AI基础:入门人工智能必看的论文
  19. xml文件解析(使用解析器)
  20. Flink集群之flink集群的启动问题:start-cluster.sh

热门文章

  1. 迷你MVVM框架 avalonjs 学习教程20、路由系统
  2. js:如何文艺地理解闭包
  3. 商品WEB开发的商品定单与存储过程的应用
  4. VNC客户端连接MacOS时一闪而过的解决办法
  5. Enterprise Vault 2007 Series [PST Migration]
  6. Ngnix的TCP和UDP负载平衡配置
  7. 如何使用 IntelliJ IDEA 2017 配置PHP开发环境 及项目搭建
  8. 【Nginx那些事】nginx 安装及常用指令
  9. Oralce定时任务实际应用
  10. 机器学习:算法视角pdf_何时使用不同的机器学习算法:简单指南