机器学习- 吴恩达Andrew Ng Week5 神经网络学习Neural Networks Learning知识总结

Posted 架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习- 吴恩达Andrew Ng Week5 神经网络学习Neural Networks Learning知识总结相关的知识,希望对你有一定的参考价值。

Coursera课程地址

因为Coursera的课程还有考试和论坛,后续的笔记是基于Coursera
https://www.coursera.org/learn/machine-learning/home/welcome

Neural Networks: Learning

特别好讲解反向传播的课程 backpropagation
https://www.youtube.com/watch?app=desktop&v=Ilg3gGewQ5U&ab_channel=3Blue1Brown
在这里插入图片描述

词汇表:

这些变量中的每一个都有一个下标,指出它与哪个 NN 层相关联。

  • Θ:用于计算神经网络内部值的权重 Theta 矩阵。当我们使用向量 theta 时,它用小写的 theta 字符表示θ.

  • z : 是数据向量乘以一个的结果 \\θΘ矩阵。典型的变量名称是“z2”。

  • a:来自神经层的“激活”输出。这总是使用 sigmoid 函数生成g() 在一个 z价值。典型的变量名称是“a2”。

  • δ:小写 delta 用于每一层中的“错误”术语。典型的变量名称是“d2”。

  • Δ : 大写 delta 用于保存 a 的乘积之和 δ 与上一层的值 a 的值。在矢量化解决方案中,这些和是通过矩阵代数的魔法自动计算的。典型的变量名称是“Delta2”。

  • Θ_gradient :这就是我们要解决的问题,theta 的偏导数。这些变量中的a与每个变量相关联Δ. 这些值由 nnCostFunction() 返回,因此变量名称必须是“Theta1_grad”和“Theta2_grad”。

  • g() 是 sigmoid 函数。

  • g’() 是 sigmoid 梯度函数。

提示:排除一列偏置单元的一种方便方法是使用符号 SomeMatrix(:,2:end)。这将选择矩阵的所有行,并省略整个第一列。

有关数据对象大小的信息,请参阅教程底部的附录。

关于偏置单元、正则化和反向传播的说明:

在反向传播和梯度计算中,有两种方法可以排除 Theta 矩阵中的偏置单元。我在这里只描述了其中一种,这是我最了解的一种。两种方法都有效,选择对您有意义的方法并避免尺寸错误。在计算之前或之后排除偏置单元无关紧要 - 两种方法都给出相同的结果,尽管所需的操作和换位顺序可能不同。

1. 成本函数 Cost function - Neural Networks: Learning

在这里插入图片描述

让我们首先定义一些我们需要使用的变量:

a) L=网络中的总层数

b) Sl = 层 l 中的单元数(不计算偏置单元)

c) K= 输出单元/类的数量

回想一下,在神经网络中,我们可能有很多输出节点。我们表示hΘ(x)k作为一个假设,导致 k^(th) 输出。

我们的神经网络成本函数将是我们用于逻辑回归的成本函数的推广。
在这里插入图片描述
我们添加了一些嵌套求和来说明我们的多个输出节点。在等式的第一部分,在方括号之间,我们有一个额外的嵌套求和,它循环遍历输出节点的数量。

在正则化部分,在方括号之后,我们必须考虑多个 theta 矩阵。我们当前 theta 矩阵中的列数等于我们当前层中的节点数(包括偏置单元)。我们当前的 theta 矩阵中的行数等于下一层的节点数(不包括偏置单元)。与之前的逻辑回归一样,我们对每一项进行平方。

笔记:

  • double sum 简单地将输出层中每个单元格计算的逻辑回归成本相加;
  • 三重和只是将整个网络中所有单个 Θ 的平方相加。
  • 三重总和中的 i不是指训练示例 i

2. 反向传播算法 Backpropagation Algorithm - Neural Networks: Learning

Gradient computation: 梯度的计算
在这里插入图片描述

“反向传播”是神经网络术语,用于最小化我们的成本函数,就像我们在逻辑回归和线性回归中使用梯度下降所做的一样。

我们的目标是计算:在这里插入图片描述

也就是说,我们希望使用 theta 中的一组最佳参数来最小化我们的成本函数 J。

在本节中,我们将查看用于计算 J(Θ) 偏导数的方程:在这里插入图片描述
Gradient computation, 用一个参数(x, y)为例来推导,
Forward propagation 正向传播计算alpha
在这里插入图片描述
Gradient computation: Backpropagation algorithm 反向传播的计算过程,计算delta
在这里插入图片描述

在反向传播中,我们将为每个节点计算:
在这里插入图片描述
对于最后一层,我们可以计算 delta 值的向量:

在这里插入图片描述
其中 L 是我们的总层数, a^(L) 是最后一层激活单元的输出向量。所以我们最后一层的“错误值”只是我们在最后一层的实际结果与 y 中正确输出的差异。
要获得最后一层之前各层的 delta 值,我们可以使用一个从右向左逐步返回的等式:
在这里插入图片描述

第 l 层的 delta 值是通过将下一层的 delta 值与第 l 层的 theta 矩阵相乘来计算的。然后我们将它与一个名为 g’ 或 g-prime 的函数逐元素相乘,它是激活函数 g 的导数,该函数用 z(l) 给定的输入值进行评估。

g-prime 导数项也可以写成:
在这里插入图片描述

完整反向传播方程为:
在这里插入图片描述

A. Ng 表示推导和证明是复杂和复杂的,但您仍然可以在不知道细节的情况下实现上述等式进行反向传播。

我们可以通过将每个训练示例 t 的激活值和误差值相乘来计算偏导项:
在这里插入图片描述

然而,这忽略了正则化,我们稍后会处理。
在这里插入图片描述
我们现在可以将所有这些方程放在一起,形成一个反向传播算法:

1.1 反向传播算法

在这里插入图片描述
capital-delta (Delta)矩阵用作“累加器”,以在我们继续进行时将我们的值相加并最终计算我们的偏导数。

在这里插入图片描述

2. 反向传播直觉 Backpropagation intuition - Neural Networks: Learning

回顾一下正Forward propagation 正向传播计算alpha
在这里插入图片描述
backpropagation 反向传播计算成本方程
在这里插入图片描述

cost function代价函数为:
在这里插入图片描述

如果我们考虑简单的非多类分类 (k = 1) 并忽略正则化,则成本计算如下:
在这里插入图片描述

更直观地,您可以将该等式大致理解为:
在这里插入图片描述
再次Forward Propagation正向传播计算梯度下降方程
在这里插入图片描述

更正式地说,delta 值实际上是成本函数的导数:
在这里插入图片描述

回想一下,我们的导数是与成本函数相切的线的斜率,所以斜率越陡,我们就越不正确。

注意:在讲座中,有时 i 用于索引训练示例。有时它用于索引图层中的单元。在此处描述的反向传播算法中,t 用于索引训练示例,而不是重载 i 的使用。

3. 实施说明:展开参数 Implementation note: Unrolling parameters - Neural Networks: Learning

高级优化函数fminunc
在这里插入图片描述

对于神经网络,我们正在处理矩阵集:
在这里插入图片描述

为了使用诸如“fminunc()”之类的优化函数,我们需要“展开”所有元素并将它们放入一个长向量中:

thetaVector = [ Theta1(:); Theta2(:); Theta3(:); ]
deltaVector = [ D1(:); D2(:); D3(:) ]

在这里插入图片描述

如果 Theta1 的尺寸为 10x11,Theta2 为 10x11,Theta3 为 1x11,那么我们可以从“展开”版本中取回原始矩阵,如下所示:

Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)

在这里插入图片描述

注意:讲座幻灯片显示了一个具有 3 层的示例神经网络。但是,定义了3 个theta 矩阵:Theta1、Theta2、Theta3。应该只有 2 个 theta 矩阵:Theta1 (10 x 11)、Theta2 (1 x 11)。

4. 梯度检查 Gradient checking - Neural Networks: Learning

梯度检查将确保我们的反向传播按预期工作。
在这里插入图片描述

我们可以用以下方法近似成本函数的导数:
在这里插入图片描述

使用多个 theta 矩阵,我们可以近似推导关于 Θj 如下:
在这里插入图片描述
在这里插入图片描述

一个很好的小价值ε(epsilon),保证上面的数学成为真。如果值小得多,可能我们最终会出现数值问题。吴恩达教授通常使用值ε=10^(−4).
我们只是增加或减去 epsilon 到 Θj 矩阵。在octave中,我们可以这样做:

epsilon = 1e-4;
for i = 1:n,
  thetaPlus = theta;
  thetaPlus(i) += epsilon;
  thetaMinus = theta;
  thetaMinus(i) -= epsilon;
  gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
end;

然后我们要检查 gradApprox ≈ deltaVector

一旦你已经验证,一旦你的BP算法是正确的,那么你就需要重新计算gradApprox。计算 gradApprox 的代码非常慢。
在这里插入图片描述

5. 随机初始化 Random initialization - Neural Networks: Learning

将所有 theta 权重初始化为零不适用于神经网络。当我们反向传播时,所有节点都会重复更新为相同的值。
在这里插入图片描述

相反,我们可以随机初始化我们的权重:
在这里插入图片描述

在这里插入图片描述

If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.

Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;

rand(x,y) 将初始化一个介于 0 和 1 之间的随机实数矩阵。(注意:这个 epsilon 与来自 Gradient Checking 的 epsilon 无关)

为什么要使用这种方法?这篇论文可能有用
https://web.stanford.edu/class/ee373b/nninitialization.pdf

6. 把它放在一起

首先,选择一个网络架构;选择神经网络的布局,包括每层有多少隐藏单元以及总共有多少层。
在这里插入图片描述

  • 输入单元数 = 特征维度 x^(i)
  • 输出单元数 = 类数
  • 每层隐藏单元的数量 = 通常越多越好(必须与计算成本平衡,因为它会随着更多隐藏单元的增加而增加)
  • 默认值:1 个隐藏层。如果隐藏层超过 1 个,则每个隐藏层的单元数相同。

6.1 训练神经网络 Putting it together - Neural Networks: Learning

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

  1. 随机初始化权重
  2. 实现前向传播得到 hθ(x^(i))
  3. 实现成本函数
  4. 实现反向传播以计算偏导数
  5. 使用梯度检查来确认您的反向传播有效。然后禁用梯度检查。
  6. 使用梯度下降或内置优化函数来最小化权重为 theta 的成本函数。

当我们执行前向和反向传播时,我们会在每个训练示例上循环:

for i = 1:m,
   Perform forward propagation and backpropagation using example (x(i),y(i))
   (Get activations a(l) and delta terms d(l) for l = 2,...,L

在这里插入图片描述

7. 奖励:关于如何对自己的数字图像进行分类的教程

本教程将指导您如何使用练习 3 中提供的分类器对您自己的图像进行分类,如下所示:
在这里插入图片描述
它还将解释如何通过多种格式转换图像以进行处理和显示。

7.1 介绍

提供的分类器期望在 400 个实数的行向量中转换 20 x 20 像素的黑白图像,如下所示

[ 0.14532, 0.12876, ...]

每个像素由 -1.0 到 1.0 之间的实数表示,这意味着 -1.0 等于黑色,1.0 等于白色(中间的任何数字都是灰色阴影,而数字 0.0 正好是中间灰色)。

7.2 .jpg 和彩色 RGB 图像

Octave 可以读取的最常见的图像格式是 .jpg 使用函数输出从 0 到 255 的整数的三维矩阵,表示高 x 宽 x 3 整数作为每个像素的颜色映射的索引(解释彩色地图超出了范围)。

Image3DmatrixRGB = imread("myOwnPhoto.jpg");

7.3 转换为黑白

将彩色图像转换为黑白的常用方法是将它们转换为 YIQ 标准并仅保留表示亮度信息(黑白)的 Y 分量。I 和 Q 代表色度信息(颜色)。 Octave 有一个函数rgb2ntsc()输出一个类似的三维矩阵,但实数从 -1.0 到 1.0,代表高 x 宽 x 3 (Y luma, I in-相位,Q 正交)每个像素的强度。

Image3DmatrixYIQ = rgb2ntsc(MyImageRGB);

要获得黑白分量,只需丢弃 I 和 Q 矩阵。这留下了一个从 -1.0 到 1.0 的实数二维矩阵,表示高度 x 宽度像素黑白值。

Image2DmatrixBW = Image3DmatrixYIQ(:,:,1);

7.4 裁剪为方形图像

将原始图像裁剪为尽可能方形是很有用的。裁剪矩阵的方法是选择原始黑白图像内的区域并将其复制到新矩阵。这是通过选择定义区域的行和列来完成的。换句话说,它正在复制矩阵的矩形子集,如下所示:

croppedImage = Image2DmatrixBW(origen1:size1, origin2:size2);

裁剪不必一直到正方形。它可以只裁剪成正方形的一部分,这样你就可以让更多的图像完好无损。缩放的下一步将负责拉伸图像以适合正方形。

7.5 缩放至 20 x 20 像素

提供的分类器使用 20 x 20 像素的图像进行训练,因此我们需要缩放照片以满足要求。根据裁剪后的原始照片的高度和宽度比例,它可能会导致失真。缩放照片的方法有很多种,但我们将使用最简单的一种。我们在原始照片上放置一个 20 x 20 的缩放网格,并在每个网格的中心取一个样本像素。为了铺设一个缩放的网格,我们计算了两个包含 20 个索引的向量,每个向量在图像的原始大小上均匀分布。一种用于图像的高度,一种用于图像的宽度。例如,在 320 x 200 像素的图像中将产生像这样的向量

[9    25    41    57    73 ... 313] % 20 indexes
[6    16    26    36    46 ... 196] % 20 indexes

将这些索引的网格所在的每个像素的值复制到一个新矩阵中。以 20 x 20 实数矩阵结束。

7.6 黑白到灰白色

提供的分类器使用灰色背景上的白色数字图像进行训练。具体来说,20 x 20 实数矩阵的范围仅从 0.0 到 1.0,而不是完整的黑白范围 -1.0 到 1.0,这意味着我们必须将我们的照片归一化到 0.0 到 1.0 的范围才能使该分类器工作. 而且,我们反转黑白颜色,因为在我们的照片上更容易在白色上“绘制”黑色,我们需要获得白色数字。因此,在短期,我们颠倒黑白和弹力黑色到灰色。

7.7 图像旋转

有时我们的照片会像手机一样自动旋转。提供的分类器无法识别旋转的图像,因此我们有时可能需要将其旋转回来。这可以通过像这样的 Octave 函数rot90()来完成。

ImageAligned = rot90(Image, rotationStep);

其中 rotationStep 是一个整数:-1 表示逆时针旋转 90 度,1 表示逆时针旋转 90 度。

7.8 方法

  1. 方法是使用一个函数将我们的照片转换为分类器期望的格式。好像它只是训练数据集中的一个样本。
  2. 使用分类器预测转换图像中的数字。

7.9 代码一步一步

定义函数名、输出变量和三个参数,一个是我们照片的文件名,一个可选的裁剪百分比(如果不提供将默认为零,表示不裁剪)和图像的最后一个可选旋转(如果不提供将默认为 cero,表示不旋转)。

function vectorImage = imageTo20x20Gray(fileName, cropPercentage=0, rotStep=0)

将文件作为 RGB 图像读取并将其转换为黑白 2D 矩阵(请参阅简介)。

% Read as RGB image
Image3DmatrixRGB = imread(fileName);
% Convert to NTSC image (YIQ)
Image3DmatrixYIQ = rgb2ntsc(Image3DmatrixRGB );
% Convert to grays keeping only luminance (Y)
%        ...and discard chrominance (IQ)
Image2DmatrixBW  = Image3DmatrixYIQ(:,:,1);

确定裁剪图像的最终尺寸。

% Get the size of your image
oldSize = size(Image2DmatrixBW);
% Obtain crop size toward centered square (cropDelta)
% ...will be zero for the already minimum dimension
% ...and if the cropPercentage is zero, 
% ...both dimensions are zero
% ...meaning that the original image will go intact to croppedImage
cropDelta = floor((oldSize - min(oldSize)) .* (cropPercentage/100));
% Compute the desired final pixel size for the original image
finalSize = oldSize - cropDelta;

获取要复制到裁剪图像的列和行的原点和数量。

% Compute each dimension origin for croping
cropOrigin = floor(cropDelta / 2) + 1;
% Compute each dimension copying size
copySize = cropOrigin + finalSize - 1;
% Copy just the desired cropped image from the original B&W image
croppedImage = Image2DmatrixBW( ...
                    cropOrigin(1):copySize(1), cropOrigin(2):copySize(2));

计算比例并计算回新的大小。最后一步是额外的。它被计算回来,所以代码保持通用,以备将来修改分类器大小。例如:如果从 20 x 20 像素更改为 30 x 30。那么我们只需要更改计算比例的代码行。

% Resolution scale factors: [rows cols]
scale = [20 20] ./ finalSize;
% Compute back the new image size (extra step to keep code general)
newSize = max(floor(scale .* finalSize),1); 

计算两组均匀分布的 20 个索引。一个超过图像的原始高度,一个超过图像的原始宽度。

% Compute a re-sampled set of indices:
rowIndex = min(round(((1:newSize(1))-0.5)./scale(1)+0.5), finalSize(1));
colIndex = min(round(((1:newSize(2))-0.5)./scale(2)+0.5), finalSize(2));

仅复制旧图像中的索引值以获得 20 x 20 实数的新图像。这称为“采样”,因为它仅复制由网格索引的样本像素。所有样本像素构成新图像。

% Copy just the indexed values from old image to get new image
newImage = croppedImage(rowIndex,colIndex,:);

使用rot90()函数和 rotStep 参数旋转矩阵:-1 是逆时针,0 是不旋转,1 是顺时针。

% Rotate if needed: -1 is CCW, 0 is no rotate, 1 is CW
newAlignedImage = rot90(newImage, rotStep);

反转黑白是因为在我们的照片中在白色背景上绘制黑色数字更容易,但分类器需要白色数字。

% Invert black and white
invertedImage = - newAlignedImage;

找出图像中的最小和最大灰度值并计算总值范围,为归一化做准备。

% Find min and max grays values in the image
maxValue = max(invertedImage(:));
minValue = min(invertedImage(:));
% Compute the value range of actual grays
delta = maxValue - minValue;

进行归一化,以便所有值最终都在 0.0 和 1.0 之间,因为这个特定的分类器在处理负数时表现不佳。

% Normalize grays between 0 and 1
normImage = (invertedImage - minValue) / delta;

为图像添加一些对比度。倍增因子是对比度控制,如果需要,您可以增加它以获得更清晰的对比度(仅灰色和白色之间的对比度,黑色在标准化中已被删除)。

% Add contrast. Multiplication factor is contrast control.
contrastedImage = sigmoid((normImage -0.5) * 5);

显示指定黑白范围 [-1 1] 的图像,以避免使用灰度到白色的图像范围值自动调整范围。显示不同范围的照片,不影响输出矩阵中的值,因此不影响分类器。它仅作为用户的视觉反馈。

% Show image as seen by the classifier
imshow(contrastedImage, [-1, 1] );

最后,将矩阵输出为与分类器兼容的展开向量。

% Output the matrix as a unrolled vector
vectorImage = reshape(normImage, 1, newSize(1) * newSize(2));

结束函数。

end;

7.10 使用示例

单张照片

  • myDigit.jpg 中的照片文件
  • 将 60% 的方式裁剪为方形照片
  • 无旋转矢量图像 = imageTo20x20Gray('myDigit.jpg',60); 预测(Theta1,Theta2,vectorImage)
  • myDigit.jpg 中的照片文件
  • 无裁剪
  • CCW rotationvectorImage = imageTo20x20Gray('myDigit.jpg',:,-1); 预测(Theta1,Theta2,vectorImage)

多张照片

  • myFirstDigit.jpgmySecondDigit.jpg 中的照片文件
  • 第一次裁剪为方形,第二次裁剪为方形照片的 25%
  • 第一个没有旋转,第二个 CW rotationvectorImage(1,:) = imageTo20x20Gray('myFirstDigit.jpg',100); vectorImage(2,:) = imageTo20x20Gray('mySecondDigit.jpg',25,1); 预测(Theta1,Theta2,vectorImage)

尖端

  • 白色背景黑色数字的 JPG 照片
  • 首选方形照片但不是必需的
  • 根据需要旋转,因为分类器只能处理垂直数字
  • 在数字周围留下背景空间。以 20 x 20 分辨率观看时至少为 2 个像素。这意味着分类器只能在 16 x 16 的区域中真正起作用。
  • 播放将对比度乘数更改为 10(或更多)。

7.11 完整的代码(只需复制和粘贴)

rgb2ntsc, octave 6.2.0没有该方法,所以手动加上,
参考:
https://stackoverflow.com/questions/63165479/octave-rgb2ntsc-missing-in-latest-version

function yiq_img = rgb2ntsc(rgb_img)
%RGB2NTSC Transform a colormap or image from red-green-blue (RGB) 
%   color space to luminance-chrominance (NTSC) space. 
%   The input may be of class uint8, uint16, single, or double. 
%   The output is of class double.

% https://octave.sourceforge.io/octave/function/rgb2ntsc.html

if isa(rgb_img, 'uint8') || isa(rgb_img, 'uint16') || ...
        isa(rgb_img, 'double')
    
    red = rgb_img(:, :, 1);
    green = rgb_img(:, :, 2);
    blue = rgb_img(:, :, 3);
    
    y = 0.299 * red + 0.587 * green + 0.114 * blue;
    i = 0.596 * red - 0.274 * green - 0.322 * blue;
    q = 0.211 * red - 0.523 * green + 0.312 * blue;
    
    yiq(:, :, 1) = y;
    yiq(:, :, 2) = i;
    yiq(:, :, 3) = q;
    
    yiq_img = double(yiq);
else
    error('Input image datatype is not supported')
end

end

方法 imageTo20x20Gray

function vectorImage = imageTo20x20Gray(fileName, cropPercentage=0, rotStep=0)
%IMAGETO20X20GRAY display reduced image and converts for digit classification
%
% Sample usage: 
%       imageTo20x20Gray('myDigit.jpg', 100, -1);
%
%       First parameter: Image file name
%             Could be bigger than 20 x 20 px, it will
%             be resized to 20 x 20. Better if used with
%             square images but not required.
% 
%       Second parameter: cropPercentage (any number between 0 and 100)
%             0  0% will be cropped (optional, no needed for square images)
%            50  50% of available croping will be cropped
%           100  crop all the way to square image (for rectangular images)
% 
%       Third parameter: rotStep
%            -1  rotate image 90 degrees CCW
%             0  do not rotate (optional)
%             1  rotate image 90 degrees CW
%
% (Thanks to Edwin Frühwirth for parts of this code)
% Read as RGB image
Image3DmatrixRGB = imread(fileName);
% Convert to NTSC image (YIQ)
Image3DmatrixYIQ = rgb2ntsc(Image3DmatrixRGB );
% Convert to grays keeping only luminance (Y) and discard chrominance (IQ)
Image2DmatrixBW  = Image3DmatrixYIQ(:,:,1);
% Get the size of your image
oldSize = size(Image2DmatrixBW以上是关于机器学习- 吴恩达Andrew Ng Week5 神经网络学习Neural Networks Learning知识总结的主要内容,如果未能解决你的问题,请参考以下文章

机器学习- 吴恩达Andrew Ng Coursera学习总结合集,编程作业技巧合集

机器学习- 吴恩达Andrew Ng Coursera学习总结合集,编程作业技巧合集

Machine Learning|Andrew Ng|Coursera 吴恩达机器学习笔记

机器学习- 吴恩达Andrew Ng 编程作业技巧

机器学习- 吴恩达Andrew Ng - week3-1 Classification

机器学习- 吴恩达Andrew Ng Week8 知识总结 Clustering