训练神经网络时出现极小或 NaN 值

2024-01-19

我正在尝试在 Haskell 中实现神经网络架构,并在 MNIST 上使用它。

我正在使用hmatrix线性代数包。 我的训练框架是使用pipes包裹。

我的代码可以编译并且不会崩溃。但问题是,层大小(例如 1000)、小批量大小和学习率的某些组合会产生NaN计算中的值。经过一番检查后,我发现非常小的值(顺序1e-100)最终出现在激活中。但是,即使这种情况没有发生,培训仍然不起作用。其损失或准确性没有任何改善。

我检查并重新检查了我的代码,但我不知道问题的根源可能是什么。

这是反向传播训练,它计算每层的增量:

backward lf n (out,tar) das = do
    let δout = tr (derivate lf (tar, out)) -- dE/dy
        deltas = scanr (\(l, a') δ ->
                         let w = weights l
                         in (tr a') * (w <> δ)) δout (zip (tail $ toList n) das)
    return (deltas)

lf是损失函数,n是网络(weight矩阵和bias每层的向量),out and tar是网络的实际输出target(期望的)输出,以及das是每层的激活导数。

在批处理模式下,out, tar是矩阵(行是输出向量),并且das是矩阵列表。

这是实际的梯度计算:

  grad lf (n, (i,t)) = do
    -- Forward propagation: compute layers outputs and activation derivatives
    let (as, as') = unzip $ runLayers n i
        (out) = last as
    (ds) <- backward lf n (out, t) (init as') -- Compute deltas with backpropagation
    let r  = fromIntegral $ rows i -- Size of minibatch
    let gs = zipWith (\δ a -> tr (δ <> a)) ds (i:init as) -- Gradients for weights
    return $ GradBatch ((recip r .*) <$> gs, (recip r .*) <$> squeeze <$> ds)

Here, lf and n与上面相同,i是输入,并且t是目标输出(均为批处理形式,作为矩阵)。

squeeze通过对每一行求和将矩阵转换为向量。那是,ds是增量矩阵列表,其中每一列对应于小批量的一行的增量。因此,偏差的梯度是所有小批量的增量的平均值。同样的事情对于gs,它对应于权重的梯度。

这是实际的更新代码:

move lr (n, (i,t)) (GradBatch (gs, ds)) = do
    -- Update function
    let update = (\(FC w b af) g δ -> FC (w + (lr).*g) (b + (lr).*δ) af)
        n' = Network.fromList $ zipWith3 update (Network.toList n) gs ds
    return (n', (i,t))

lr是学习率。FC是层构造函数,并且af是该层的激活函数。

梯度下降算法确保传递学习率的负值。梯度下降的实际代码只是一个围绕以下组合的循环grad and move,具有参数化的停止条件。

最后,这是均方误差损失函数的代码:

mse :: (Floating a) => LossFunction a a
mse = let f (y,y') = let gamma = y'-y in gamma**2 / 2
          f' (y,y') = (y'-y)
      in  Evaluator f f'

Evaluator只是捆绑了一个损失函数及其导数(用于计算输出层的增量)。

其余代码位于 GitHub 上:神经网络 https://github.com/DrPyser/NeuralNetwork.

任何人都对这个问题有深入的了解,甚至只是对我是否正确实现了算法进行了健全性检查?


你知道反向传播中的“消失”和“爆炸”梯度吗?我对 Haskell 不太熟悉,所以我无法轻易看出你的反向传播到底在做什么,但它看起来确实像你正在使用逻辑曲线作为你的激活函数。

如果您查看该函数的绘图,您会发现该函数的梯度在末端接近 0(当输入值变得非常大或非常小时,曲线的斜率几乎是平坦的),因此乘法或除法在反向传播过程中,这将导致一个非常大或非常小的数字。当您穿过多个层时重复执行此操作会导致激活值接近零或无穷大。由于反向传播通过在训练期间执行此操作来更新您的权重,因此最终您的网络中会出现大量零或无穷大。

解决方案:您可以搜索大量方法来解决梯度消失问题,但尝试的一件简单的事情是将您使用的激活函数类型更改为非饱和函数。 ReLU 是一个流行的选择,因为它可以缓解这个特定问题(但可能会引入其他问题)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

训练神经网络时出现极小或 NaN 值 的相关文章

  • 带有元数据的 scipy kdtree

    我目前正在寻找一种方法来构建几个 kd 树以快速查询一些 n 维数据 但是 我对 scipy KD 树算法有一些问题 我的数据包括id gt data somedata coordinate x y 我希望能够基于坐标和 k 最近邻居的 i
  • 算法:找到圆中的峰值

    Given n排列成圆圈的整数显示了一种可以找到一个峰值的有效算法 峰值是不小于它旁边的两个数字的数字 一种方法是遍历所有整数并检查每个整数以查看它是否是峰值 这产生O n 时间 似乎应该有某种方法来分而治之 以提高效率 EDIT 好吧 基
  • 你将如何在 Haskell 中(重新)实现迭代?

    iterate a gt a gt a gt a 你可能知道 iterate是一个接受函数和起始值的函数 然后它将函数应用于起始值 然后将相同的函数应用于最后的结果 依此类推 Prelude gt take 5 iterate 2 2 2
  • 如何确定字符串的最小公约数?

    我在面试时被问到以下问题 并被它难住了 我遇到的部分问题是要下定决心要解决什么问题 起初我并不认为这个问题在内部是一致的 但后来我意识到它要求你解决两个不同的问题 第一个任务是弄清楚一个字符串是否包含另一个字符串的倍数 但第二个任务是在两个
  • 随机排列

    我无法找到一种随机洗牌元素的好方法std vector经过一些操作后 恢复原来的顺序 我知道这应该是一个相当简单的算法 但我想我太累了 由于我被迫使用自定义随机数生成器类 我想我不能使用std random shuffle 无论如何这没有帮
  • 如何计算一组字符串的最短唯一前缀?

    这是一个非常常见的算法命令行解析 给定一组预定义的长选项名称 计算唯一标识这些选项之一的最短前缀 例如 对于以下选项 help hostname portnumber name polymorphic 这将是输出 he ho por n p
  • 查找两个大小为 n 的数组中第 n 大数的算法

    我有这个问题 给定两个大小为 n 的排序列表 存储在数组中 找到 O log n 计算并集中第 n 大元素的算法 两个列表 我可以看到这里可能有一个技巧 因为它需要第 n 个最大的元素 并且数组的大小也是 n 但我不知道它是什么 我在想我可
  • 算法 - 树中所有节点的最大距离

    所以 找到树中两个节点之间的最长路径相当容易 但我想要的是找到从节点出发的最长路径x到树中的另一个节点 对于所有x 这个问题也可以用以下方式表达 计算从给定的树中可以生成的所有有根树的高度 One way of course is to j
  • 如何从具有函数依赖关系的类型类中获取和使用依赖类型?

    如何从具有函数依赖关系的类型类中获取和使用依赖类型 为了澄清并给出我最近的尝试的一个例子 从我正在编写的实际代码中最小化 class Identifiable a b a gt b where if you know a you know
  • 这是 unsafeCoerce 的安全使用吗?

    我遇到的情况是 我目前正在使用极其可怕的函数 unsafeCoerce 幸运的是 这并不是为了任何重要的事情 但我想知道这是否是该函数的安全使用 或者是否有其他方法可以解决其他人知道的这个特定问题 我的代码类似于以下内容 data Toke
  • 广度优先搜索:检查访问状态的时机

    在有向图的广度优先搜索中 可能循环 当一个节点出队时 其所有尚未访问的子节点都会入队 并且该过程将继续 直到队列为空 有一次 我以相反的方式实现它 将节点的所有子节点排队 并在节点出队时检查访问状态 如果正在出队的节点之前已被访问过 则该节
  • RNG 技术的可移植性和可重复性

    我可以使用两种方法之一来创建一个伪随机数序列 该序列具有两个重要特征 1 它可以在不同的机器上重现 2 该序列永远不会重复范围内的数字 直到所有数字都被发出 我的问题是 这两种方法在可移植性 操作系统 Python 版本等 方面是否存在潜在
  • 如何从列中创建对称矩阵?

    例如 我想转动以下列 90 175 600 650 655 660 代入矩阵 90 175 600 650 655 660 175 600 650 655 660 655 600 650 655 660 655 650 650 655 66
  • Python 将字符串组合成尽可能短的字符串?

    如果我有一个字符串列表 我想将它们组合成一个具有重叠字符的字符串 如果没有剩余的重叠字符串 请将其添加到末尾 这是一个过于简化的版本 input one two output twone 我正在寻找一种方法来对输入列表中的任意数量的字符串执
  • 如何使用类型系统编码和强制执行合法的 FSM 状态转换?

    假设我有一个类型Thing拥有国有财产A B C 合法的状态转换是A gt B A gt C C gt A 我可以写 transitionToA Thing gt Maybe Thing 这会返回Nothing if Thing处于无法转换
  • 如何与更高级别的类型合作

    玩弄教堂的数字 我遇到了无法指导 GHC 类型检查器处理高阶类型的情况 首先我写了一个版本 没有任何类型签名 module ChurchStripped where zero z z inc n z s s n z s natInteger
  • 找到一个恰好出现了 N/2 次的数字

    这是我的面试问题之一 给定一个包含 N 个元素的数组以及元素出现的位置正好 N 2次 其余 N 2 个元素是unique 您如何找到运行时间更好的元素 请记住 元素未排序 您可以假设 N 是偶数 例如 input array 10 2 3
  • 为每个英文单词生成唯一序列号的算法

    对于应用程序 我需要为每个英语单词生成唯一的序列号 最好的方法是什么 一个限制是序列号生成算法应该在普通台式计算机中非常有效 Thanks 你有所有可能的单词的列表吗 如果是 则从第一个字的 0 开始 每个字将序列号加 1 如果不是 那么保
  • Haskell 中的内部爆炸模式是否总是强制使用外部构造函数?

    在 Haskell 中 是否存在对于数据类型 LANGUAGE BangPatterns import Control DeepSeq data D D Int 实例 instance NFData D where rnf D 与具有另一个
  • 在 Haskell 中调试时打印时间戳

    我仍在学习 Haskell 并调试一些函数 并且通常有一个时间戳函数来了解某些操作何时开始和停止 doSomeAction String gt IO doSomeAction arg1 do putStrLn lt lt makeTime

随机推荐

  • Excel,将一个范围附加到一列中另一个范围的末尾

    我的 Excel 中有两列数据 我想添加结合第一列和第二列的第三列 如何使用公式执行此操作 以便可以在 A 列和 B 列中添加或删除数据 而无需接触 C 列 Column A Column B Column C Bob Mary Bob J
  • 是否可以使用一行将流收集到两个不同的集合?

    我有以下代码 为了勇敢而简化 public void search Predicate
  • Jenkins 使用 Git 和 Deploy Key 进行构建

    我将 git 插件添加到 Jenkins 中 我已经作为构建服务器上的 jenkins 用户生成了一个公钥 我将此密钥作为部署密钥添加到 github 我添加了带有 jenkins 名称和电子邮件的全局 git 属性 并且电子邮件与公钥末尾
  • 在 Rails 模型中;保存到数据库时,符号会自动转换为 YAML。正确的做法是什么?

    在我的模型示例游戏中 有一个状态列 但我通常通过使用符号来设置状态 例子 self status active MATCH STATUS betting on gt Betting is on home team won gt Home t
  • Firefox 的 execCommand 复制异步替代方案

    document execCommand copy 可以在 Promise 的解析函数中使用 Firefox 除外 Chrome Opera 甚至 Safari 等所有现代浏览器都允许最多 1 秒的异步复制 我想改善用户体验并在剪贴板中计算
  • 使用 HDFS 更改更新 Hive 外部表

    可以说 我从文件 myFile csv 位于 HDFS 中 创建了 Hive 外部表 myTable myFile csv 每天都会更改 那么我也有兴趣每天更新一次 myTable 是否有任何 HiveQL 查询告诉每天更新表 谢谢 P S
  • AddEntityFrameworkStores 只能由派生自 IdentityUser 的用户调用

    我正在尝试为我的网络应用程序创建一些角色 但由于以下原因它并没有真正起作用Tkey exception 如果您投赞成票 我很高兴 这样其他需要帮助的人就可以更多地看到它 我不知道如何解决它 我认为我的 Startup cs 有问题 无论我尝
  • 将其他计费注册字段与 WooCommerce 中的默认 Wordpress 字段同步

    我已将以下代码添加到 Woocommerce 用户注册表中 以获取注册页面上的账单详细信息 现在当新用户注册时会发生什么 名字和姓氏将在账单详细信息数据库以及默认 WordPress 用户帐户中注册 如果用户更新其帐户 wordpress
  • Git 强制覆盖本地跟踪文件,但不覆盖本地未跟踪文件

    我正在一个名为的本地目录中工作p1其中包含一个 git 存储库 添加分支并对添加的分支进行提交后 我制作了目录的副本p1并称之为p2 我的目的是在目录中尝试合并和变基 只是为了学习 p2 同时从p1当我决定如何合并 重新调整我的更改时 但是
  • 插入符号交叉验证中的预处理

    我有一个关于数据预处理的问题需要澄清 据我了解 当我们通过交叉验证调整超参数并估计模型性能时 我们需要在交叉验证中进行 而不是预处理整个数据集 换句话说 在交叉验证中 我们对训练折叠进行预处理 然后使用相同的预处理参数来处理测试折叠并进行预
  • .NET 示例 VCF 阅读器

    有谁知道使用 C NET 从 VCF 文件中提取数据的好示例 内联回复或网络教程 现在还有人用VCF文件吗 对于联系人管理系统来说 这值得吗 让我有点惊讶的是 它没有内置到 NET Framework 的任何地方 但我确实找到了本教程 我计
  • 将 ExpandoObject 持久保存到 MongoDB

    我有一个具有任意数量属性的 ExpandoObject 我想将这些属性作为 BsonDocument 保存到 MongoDB 数据库 我尝试使用以下代码来执行此操作 private BsonDocument GetPlayerDocumen
  • 如何在 onStart() 方法中从 Firebase 远程配置实现 fetch() ?

    我正在尝试实现调用 Firebase 远程配置fetch 中的方法onStart 我以为这会很容易 但经过几次尝试后却发现并非如此 首先 我想尽快检查新的配置值用户打开应用程序 and 超出缓存过期时间 这就是我选择的原因onStart 方
  • 如何禁用/关闭/刷新 couchdb 缓存

    我有一个列表 其中对文档进行了一些基本身份验证 我遇到的问题是列表正在缓存 因此除非我更新修订 ID 否则用户将看不到他们具有访问权限 如何显示非缓存列表 if req userCtx name doc permissions owner
  • 最小化二分图中的交叉数

    在为不相关的东西绘制图表时 我遇到了以下算法问题 我们有一个二部图的平面图 其中不相交的集合按列排列 如图所示 我们如何重新排列每列内的节点以使边缘交叉的数量最小化 我知道这个问题对于一般图来说是 NP 困难的 link http en w
  • 调试使用 ES6 模块的 JavaScript 代码

    TL DR 如何从调试器访问 ES 模块中定义的变量 函数 名称 更多背景信息 我是一位经验相对丰富的 JavaScript 程序员 但对模块还是个新手 我已经按照 MDN 上的教程进行操作 https developer mozilla
  • CUDA 就地转置错误

    我正在实现一个 CUDA 程序来转置图像 我创建了 2 个内核 第一个内核进行了异位转置 并且适用于任何图像尺寸 然后我创建了一个用于方形图像就地转置的内核 但是 输出不正确 图像的下三角形被转置 但上三角形保持不变 生成的图像在对角线上有
  • 如何在 android room 和 rxjava 2 中插入数据并获取 id 作为输出参数?

    插入查询 Insert onConflict OnConflictStrategy REPLACE long insertProduct Product product product id is auto generated 查看模型 p
  • tvos UISegmentedControl 焦点样式不改变

    我想在 tvOS 中突出显示 UISegmentedControl 时更改其背景颜色 Normally Segment display like following When change focus for change selected
  • 训练神经网络时出现极小或 NaN 值

    我正在尝试在 Haskell 中实现神经网络架构 并在 MNIST 上使用它 我正在使用hmatrix线性代数包 我的训练框架是使用pipes包裹 我的代码可以编译并且不会崩溃 但问题是 层大小 例如 1000 小批量大小和学习率的某些组合