如何理解 RNN ?LSTM 又是啥?

是啥? RNN 就像一个有短期记忆的学习者,它能记住最近的信息,但时间越长,记忆越模糊。 通俗来说,RNN(循环神经网络) 可以类比成一个有记忆的“学习者”。假设这个学习者在读一篇文章,他每读完一个词就会暂时记住这个词的意思,再去读下一个词。在传统神经网络中,每次处理的输入都是独立的(像每次都从零开始阅读),但在RNN中,它会“记住”之前的信息(之前的词),并将这些记忆传递给下一步处理,让整个句子有上下文的联系。 但是,RNN 有一个非常明显的问题:短期记忆强,长期记忆弱。就像你记得刚刚读到的几个词,但越往前回忆,记忆就会越来越模糊。这种现象在处理长文本或长序列时尤为明显,它“记住”早期信息的能力会随着时间推移迅速衰减,这被称为 梯度消失 问题。 那 LSTM(长短期记忆网络) 为 RNN 解决了什么问题呢? 可以想象 LSTM 是一个“有着更加聪明记忆能力的学习者”。它不仅仅像 RNN 那样简单地记住最近的信息,还学会了如何挑选重要的记忆保留下来,并抛弃不重要的内容。LSTM 通过 “遗忘门”和“记忆门” 等机制,决定哪些信息应该忘掉,哪些应该长期记住,从而解决了 RNN 无法很好地记住长时间信息的问题。 举个例子:想象你在读一本小说,刚开始时提到的某个人物情节对故事发展很关键,但过了一段时间你可能就不需要记住每个不重要的细节了。LSTM 就好比你的大脑,它有能力判断哪些信息应该记住很久(比如关键的主线人物)而哪些可以随时忘记(比如不重要的细节)。这样它就可以更好地处理那些时间跨度较大的信息,而不会像 RNN 那样迅速遗忘。 一些细节 1. RNN 的技术细节 RNN 的核心在于它的“循环”,即网络的输出不仅依赖于当前输入,还依赖于上一时刻的隐藏状态。这是它“记忆”的来源。 数学表达: 在 RNN 中,隐藏状态 \( h_t \) 是通过当前输入 \( x_t \) 和前一个时刻的隐藏状态 \( h_{t-1} \) 共同计算的: \[ h_t = \tanh(W_h h_{t-1} + W_x x_t + b) \] \( W_h \) 是连接隐藏状态的权重矩阵(负责记住过去的信息)。 \( W_x \) 是输入层的权重矩阵(负责处理当前输入)。 \( \tanh \) 是激活函数(可以替换为其他如 ReLU,但常用的是 \( \tanh \))。 \( b \) 是偏置项。 RNN 的梯度消失问题 在训练 RNN 的过程中,我们会使用反向传播算法来更新权重。在长序列中,隐藏状态 \( h_t \) 会不断地被传递下去。这意味着,越早的输入对当前状态的影响需要经过多次链式计算。随着序列长度增加,隐藏状态的梯度会逐渐接近于零,这就是梯度消失。...

九月 20, 2024 · 2 分钟

如何理解交叉熵?

是啥? 在深度学习中,“交叉熵”是一个用来衡量两个概率分布之间差异的函数,通常用于分类任务。 比喻:猜糖果的颜色 想象你有一袋糖果,里面有红色、绿色和蓝色三种颜色。你猜这袋糖果的颜色分布是红色 50%,绿色 30%,蓝色 20%。但实际上,这袋糖果的真实分布是红色 60%,绿色 20%,蓝色 20%。 交叉熵的作用就是告诉你,你的猜测(预测)和糖果袋的真实分布有多接近。如果你的猜测和真实情况差别很大,交叉熵的值会很大;如果你猜得很接近,交叉熵的值就会很小。 数学解释 交叉熵的数学公式可以写成: \[ H(p, q) = - \sum p(x) \log(q(x)) \] 其中: \( p(x) \) 是真实的概率分布(比如糖果袋的真实颜色分布)。 \( q(x) \) 是你预测的概率分布(比如你猜测的颜色分布)。 这个公式的意思是:对于每种可能的糖果颜色,真实的概率 \( p(x) \) 和你预测的概率 \( q(x) \) 之间的差异,乘上 \( \log(q(x)) \),然后取负号,最后对所有颜色的可能性求和。 直观解释: 如果你猜得很对:比如你猜红色糖果有 60%,而真实也是 60%,那么交叉熵的值就会很小,表示你预测得很准确。 如果你猜得不对:比如你猜红色糖果只有 20%,而真实是 60%,那么交叉熵的值就会很大,表示你的预测与真实情况差距很大。 交叉熵的计算 例子: 假设我们有一个简单的分类问题,只有两个类别,比如“猫”和“狗”。 真实的标签是“猫”,所以真实概率 \( p(x) \) 是: 猫:1.0 狗:0.0 模型预测的概率 \( q(x) \) 是: 猫:0.8 狗:0.2 逐步计算: 根据公式,交叉熵计算会涉及每个类别。我们带入这两个类别的概率: \[ H(p, q) = - \left( p(\text{猫}) \cdot \log(q(\text{猫})) + p(\text{狗}) \cdot \log(q(\text{狗})) \right) \] 计算“猫”部分:...

九月 18, 2024 · 1 分钟

升级到 macOS 15 之后,我的 nix 怎么没了?!

咋回事? 昨天快乐地把 macOS 升级到了 15 ,结果今天用 hugo 建站的时候,发现 hugo 没了?! 1 2 (base) BdimMacBook-Pro:~ bdim404$ hugo -bash: hugo: command not found 我一想,我也没卸载 hugo 啊。 我的 hugo 是 nixpkgs 安装的,于是我尝试了一哈 nix 还在不在。 1 2 (base) BdimMacBook-Pro:~ bdim404$ nix -bash: nix: command not found 我靠, nix 没了?! 发生了啥? 问了一哈群友,原来每次 macOS 升级, nix 的 $PATH 都会消失。这个 issues 有提。 I have done a few days before the upgrade to Catalina 10.15.6… and today I wanted to install something to discover that my nix installation was gone!...

九月 17, 2024 · 1 分钟

如何理解嵌入层

想象你在学校里,班级里有很多学生,每个学生都有自己的名字。老师想根据学生的名字来决定他们做什么工作,但名字本身是无意义的,直接用名字没法帮老师做决定。 于是,老师把每个学生的名字转化成一个编号,比如小明是1号,小红是2号,这些编号就像学生的“标签”,让老师能更好地进行安排。但这个编号也不能直接用,因为它太简单了,不能表达更多的信息。 于是老师给每个学生分配了一些“特征”,比如: 小明(1号):聪明,运动能力好,喜欢数学。 小红(2号):细心,擅长绘画,喜欢语文。 这些“特征”就像嵌入层做的工作。它把原本没有太多意义的“名字”变成了有特定含义的“特征向量”(数值向量),然后老师(神经网络)就可以根据这些特征进行更复杂的决策,比如安排小明去参加数学比赛,安排小红去绘画比赛。 嵌入层的作用: 它把原本像“名字”这种离散的数据,转换成能表达更多特征的数值向量,帮助神经网络更好地理解数据的含义。这种转换让机器能“理解”那些原本无法直接使用的信息(比如文本、类别)。 上面的内容我觉得能够解释得清楚嵌入层大概的原理和作用是什么了。 接下来,我再结合一个深度学习的实际例子来深入解释。 例子:自然语言处理(NLP)中的词嵌入 假设我们正在构建一个文本分类器,这个分类器的目标是根据一篇文章的内容来判断它的类别(比如是体育、科技、新闻等)。在这个任务中,输入的数据是文本(比如一句话),而神经网络不能直接处理文字,它只能处理数值。所以我们需要把这些文字转换成模型可以理解的形式——这就是嵌入层的任务。 1. 文本的数值化 首先,假设我们有以下一句话作为输入: “苹果是一家科技公司。” 我们要让模型理解这句话,首先要把每个词(如“苹果”、“科技”、“公司”)转化为数字。可以使用词典方法,比如给每个词分配一个独特的编号: 苹果 -> 1 是 -> 2 一家 -> 3 科技 -> 4 公司 -> 5 这就将原句转换成了一个数字序列: [1, 2, 3, 4, 5] 2. 嵌入层的工作 单纯的数字序列是没有实际意义的,它只是词的编号,没有表达出词与词之间的关系。嵌入层的作用就是将这些编号转化为可以表达词语“特征”的向量。 假设我们有一个嵌入层,它将每个词的编号转化为一个3维向量(实际应用中,维度通常更高,比如100维或300维)。嵌入层会学到每个词在特征空间中的表示,比如: “苹果” -> [0.7, 0.1, 0.9] (可能表示它是一个具体的公司名) “科技” -> [0.3, 0.9, 0.4] (可能表示它与技术相关) “公司” -> [0.6, 0.2, 0.8] (可能表示它是一个组织) 这些向量不仅仅是随机的,而是嵌入层在训练过程中学到的,能够捕捉每个词的语义信息。比如,“苹果”这个词的向量可能会接近其他公司名称的向量,而“科技”会接近与技术相关的词汇。 3. 嵌入层的好处 嵌入层不仅能让模型处理文本,还能让模型自动学到词与词之间的语义关系。例如,经过训练后,模型可以学到: “苹果”和“微软”有相似的向量表示,因为它们都是科技公司; “科技”和“创新”也会有相似的向量,因为它们在语义上相关。 这意味着模型不仅仅看懂了字面意思,还能理解更深层次的语义信息。这种表示方法能显著提升模型的准确性。 总结 嵌入层在这个例子中的作用是:将原本简单的词的编号转化为包含语义信息的向量表示,这样神经网络就可以学习到词与词之间的关系,提升模型对文本的理解能力。 通过这个实际例子,你可以看到嵌入层是如何在深度学习中将“离散”的信息(如单词)变成“连续”的数值表示,帮助模型更好地学习和推理。

九月 13, 2024 · 1 分钟

Andrej Karpathy 的 Neural Networks: Zero to Hero 系列视频笔记:2 - Makemore

原视频: The spelled-out intro to language modeling: building makemore 注意,可以透过将代码复制到 colab 或 jupyter notebook 运行, 部分生图的输出结果本文贴图效果不佳,所以建议亲自动手跟着视频操作理解。本文的笔记仅作参考。 目标 Makemore 接收一个文本文件(例如提供的 names.txt),其中每一行都假定为一个训练“对象”。 然后,它生成更多类似的东西。 在内部,Makemore 是一个字符级语言模型。每一行都包含一个示例,即模型中的一系列单个字符。 这是Makemore操作的层面,试图预测序列/单词中的下一个字符。 Makemore 是一个以现代方式实现的字符级语言建模工具。 我们的目标是从零开始构建Makemore,并理解其工作原理。 1 2 3 4 5 6 import torch import torch.nn.functional as F import matplotlib.pyplot as plt %matplotlib inline device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # Use GPU if available (faster calculations with PyTorch) 1 2 3 4 5 6 words = open('names.txt', 'r')....

九月 12, 2024 · 23 分钟