机器学习- 吴恩达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);
% 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));
% 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); 
% 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));
% Copy just the indexed values from old image to get new image
newImage = croppedImage(rowIndex,colIndex,:);
% 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;
% Normalize grays between 0 and 1
normImage = (invertedImage - minValue) / delta;
% Add contrast. Multiplication factor is contrast control.
contrastedImage = sigmoid((normImage -0.5) * 5);
% Show image as seen by the classifier
imshow(contrastedImage, [-1, 1] );
% Output the matrix as a unrolled vector
vectorImage = reshape(contrastedImage, 1, newSize(1)*newSize(2));
end

7.12 照片库

数字 2
在这里插入图片描述
数字 6
在这里插入图片描述
倒转的数字 6 是数字 9。这是一张 6 的同一张照片,但旋转了。此外,将对比度乘数从 5 更改为 20。您可以注意到灰色背景更平滑。
在这里插入图片描述
数字 3
在这里插入图片描述

8. 反向传播中使用的导数解释 Explanation of Derivatives Used in Backpropagation

  • 我们知道,对于逻辑回归分类器(即神经网络中的所有输出神经元),我们使用成本函数,
    在这里插入图片描述
    并将其应用于 K 个输出神经元,以及所有 m 个示例。
  • 计算输出神经元中 theta 项的偏导数的方程:

在这里插入图片描述

  • 以及计算 [last] 隐藏层神经元(L-1 层)中 theta 项的偏导数的方程:

在这里插入图片描述

  • 很明显,它们有一些共同点,所以增量项 δ^(L)可用于输出层和紧接其之前的隐藏层之间的公共部分(如果我们愿意,可能有很多隐藏层):

在这里插入图片描述

  • 我们可以继续使用另一个增量项 δ^(L−1) 对于最终隐藏层和之前的隐藏层共享的部分,如果我们有的话。无论如何,这个增量项仍将有助于使数学和实现更加简洁。
    在这里插入图片描述
  • 有了这些增量项,我们的方程变为:
    在这里插入图片描述
  • 现在,是时候评估这些衍生品了:
    让我们从输出层开始:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • 请注意,这是我们的注释中给出的正确等式。

在这里插入图片描述

  • 把它放在一起输出层:
    在这里插入图片描述
  • 让我们继续隐藏层(假设我们只有 1 个隐藏层):

在这里插入图片描述

  • 让我们弄清楚 δ(L−1).
  • 再一次,给定 z=θ∗input,偏导数为:
    在这里插入图片描述
    在这里插入图片描述
  • 因此,对于 3 层网络,
    在这里插入图片描述
  • 将其放在 [最后一个] 隐藏层中:
    在这里插入图片描述

9. 用于线性系统的神经网络

9.1 介绍

我们为分类创建的 NN 可以很容易地修改为具有线性输出。首先解决第四个编程练习。您可以创建一个具有以下特征的新函数脚本 nnCostFunctionLinear.m

  • 只有一个输出节点,因此您不需要 ‘num_labels’ 参数。
  • 由于只有一个线性输出,因此您无需将 y 转换为逻辑矩阵。
  • 您仍然需要隐藏层中的非线性函数。
  • 非线性函数通常是 tanh() 函数 - 它的输出范围从 -1+1,并且它的梯度很容易实现。设 g(z)=tanh(z)
  • tanh 的梯度是 g'(z) = 1 - g(z)^2. 在反向传播中使用它来代替 sigmoid 梯度。
  • 从输出层移除 sigmoid 函数(即不使用 sigmoid 函数计算 a3),因为我们想要一个线性输出。
  • 成本计算:对于非正则化部分,使用 J(来自 ex1ex5)的线性成本函数。对于正则化部分,使用与ex4相同的方法。
  • reshape() 用于形成 Theta 矩阵的地方,将 'num_labels' 替换为 '1'

您仍然需要随机初始化 Theta 值,就像任何 NN 一样。您将需要尝试不同的 epsilon 值。您还需要创建一个 predictLinear() 函数,使用隐藏层中的 tanh() 函数和一个线性输出。

9.2 测试您的线性神经网络

这是您的 nnCostFunctionLinear() 的测试用例

% inputs
nn_params = [31 16 15 -29 -13 -8 -7 13 54 -17 -11 -9 16]'/ 10;
il = 1;
hl = 4;
X = [1; 2; 3];
y = [1; 4; 9];
lambda = 0.01;

% command
[j g] = nnCostFunctionLinear(nn_params, il, hl, X, y, lambda)

% results
j =  0.020815
g =
    -0.0131002
    -0.0110085
    -0.0070569
     0.0189212
    -0.0189639
    -0.0192539
    -0.0102291
     0.0344732
     0.0024947
     0.0080624
     0.0021964
     0.0031675
    -0.0064244

现在创建一个使用 ex5 中的“ex5data1.mat”的脚本,但不创建多项式项。隐藏层中有 8 个单元,MaxIter 设置为 200,您应该能够获得 0.30.4 的最终成本值。由于随机 Theta 初始化,结果会有所不同。如果你绘制训练集和训练集的预测值(使用你的 predictLinear() 函数),你应该有一个很好的匹配。

10. 推导 Sigmoid 梯度函数 Deriving the Sigmoid Gradient Function

在这里插入图片描述
反向传播的其他资源

11. 神经网络实现自动驾驶: Backpropagation example: Autonomous driving - Neural Networks: Learning

自动驾驶的实现是,先采集路线经纬度和汽车轨迹的数据。当数据比较多的时候,就可以比较准确计算经纬度和轨迹的。这就是神经网络的很好应用。当然这里面如果还要加入别的车,过马路,红绿灯的话,要求的参数就会更多了,这个例子仅仅是看到了如何自动驾驶。
在这里插入图片描述

参考

https://www.coursera.org/learn/machine-learning/resources/EcbzQ

https://www.coursera.org/learn/machine-learning/supplement/FklyY/lecture-slides

https://d3c33hcgiwev3.cloudfront.net/_1afdf5a2e2e24350ec9bad90aefd19fe_Lecture9.pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值