奇技淫巧:RNN 求解常微分方程组

一、前言 前一段时间接触常微分方程组拟合的时候,发现了使用 RNN 求解常微分方程组的办法。感觉很有意思,于是记录一下。 参考: 貌离神合的RNN与ODE:花式RNN简介 基于RNN的微分方程拟合 二、常微分方程组和欧拉法 所谓常微分方程,指的是只具有单一自变量的微分方程,如假设加速度 $a$ 一定,则速度 $v$ 满足微分方程 $$ \frac{dv}{dt} = a $$ 速度 $v$ 只与时间 $t$ 有关,那么该微分方程即常微分方程。与之对应的是偏微分方程,不过不在本文的讨论范围内。 类似的,路程 $s$ 也满足微分方程 $$ \frac{ds}{dt} = v $$ 那么关于 $v, s$ 的两个常微分方程就可以组成常微分方程组 $$ \begin{cases} \frac{dv}{dt} = a \\ \frac{ds}{dt} = v \end{cases} $$ 虽然上面的方程组很容易求出解析解,但许多常微分方程组却难以找到解析解,甚至解析解根本不存在。这种情况就需要求出数值解。 还举上面那个简单的物理问题为例,我们设 $t$ 时刻速度和路程为 $v_t, s_t$,那么可以令 $$ \begin{cases} v_{t_m} &= v_{t_{m-1}} + a \Delta t \\ s_{t_m} &= s_{t_{m-1}} + v_{t_m} \Delta t \end{cases} $$ 其中 $t_{m-1} < t_{m}, \Delta t = t_{m} - t_{m-1}$,这样就近似得到了速度和路程随时间变化的数值解。此种方法也是游戏物理引擎中进行运动学模拟的基本方法。因为是欧拉发明的,所以也叫做欧拉法。...

五月 11, 2023 · 5 分钟 · 873 字 · Wokron

使用 Transformer 进行机器翻译

一、transformer 简介 transformer 是 Google 在 2017 年发表的文章 Attention Is All You Need 中提出的网络架构。transformer 中只使用了注意力,实现了序列数据的处理,而未使用之前常用的 RNN 或 CNN。 对 nlp 问题,我们希望的是尽可能的获取句子的整体含义。使用 RNN,我们必须逐词获取语义,因此容易导致开头词汇词义的遗忘;使用 CNN,我们必须通过增加层数来扩大获取信息的范围。这两种方法都有很大的局限。 注意力方法则可以直接获得全局信息。方法是对一条序列,求其对于本身的注意力,这被称为自注意力。 transformer 的原理和模型较为复杂,在这里只是简单说明。 二、数据集 此为训练模型所用的数据集。设定英文为源语言,中文为要翻译成的语言。 (1)Dataset 类编写 我们根据路径打开文件,获取中英文序列和单词表。并将序列直接转化为 tensor,方便读取。 class TranslateDataset(Dataset): def __init__(self, en_path, zh_path): en_seqs, self.en_vocab = get_seq_and_vocab(en_path, get_tokenizer("basic_english")) zh_seqs, self.zh_vocab = get_seq_and_vocab(zh_path, zh_simple_tokenizer) self.items = [] for i in range(len(en_seqs)): en_seq = en_seqs[i] zh_seq = zh_seqs[i] src = en_seq tgt = zh_seq[:-1] pdt = zh_seq[1:] self....

三月 12, 2023 · 4 分钟 · 667 字 · Wokron

ESIM 网络的搭建和训练

一、前言 最近半年多的时间里学了许多人工智能,尤其是深度学习的知识,但是一直没有搭建过一个较为复杂的神经网络,最多也只是一个简单的 rnn。这主要是因为自己的笔记本没有训练较大模型的能力。 因为对nlp比较感兴趣,因此最近开始尝试跟着复旦大学邱锡鹏老师的NLP入门练习搭建网络。但到任务三时自己的笔记本就无法继续训练了,于是这次我下定决心找到训练一个比较好的训练模型的方法。最终找到了 Colab。 因为使用了Colab,本次模型的构建和训练比较成功,因而做此记录。 二、任务 本次任务是输入两个句子,判断它们之间的关系。具体来说,我们需要实现论文中提出的 ESIM 网络,并通过 SNLI数据集 进行训练,以学习预测两个句子间的关系。 三、数据集 SNLI数据集包含57万行英文句子对,并被标注了句子间的关系,包括蕴含(Entailment),矛盾(Contradiction),中立/不冲突(Neutral),未知(-)。 例如 输入文本: A man inspects the uniform of a figure in some East Asian country. 输入假设: The man is sleeping. 输出: 矛盾(C) 输入文本: A smiling costumed woman is holding an umbrella. 输入假设:A happy woman in a fairy costume holds an umbrella. 输出: 中立(N) 输入文本: A soccer game with multiple males playing. 输入假设: Some men are playing a sport....

三月 5, 2023 · 4 分钟 · 755 字 · Wokron

利用 Colab 训练神经网络

一、算力从哪里来? 曾听到过这样一种说法,深度学习 “自学 + 没经费 = 天坑”。不幸的是我似乎正处于这种状态中。自学的方面还比较好克服,可没有 gpu 进行训练就 “难为无米之炊” 了。就算理论学得再好,自己构建的模型电脑带不动,没有实践的机会,也是难以学好这门学科的。 最近我正开始学着实现更大的模型,我的笔记本此前的小模型还可以勉强撑住,可现在却完全带不动了。一方面,训练的时间太长,挤占了我使用笔记本做其他事的时间;另一方面,我的 gpu 显存太小,不能调大参数,可参数较小时又无法收敛。这就是我面临的双重两难问题。 我希望找到一处租用算力的平台。它应该同时满足如下的条件 算力丰富,能快速训练模型 对用户友好,和本机环境差别不大,能够迅速上手训练模型 费用便宜,最好有免费的算力 综合以上各点,通过搜索,我找到了 Colab。Colab(oratory) 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果。它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行。Colab 笔记本存储在 Google 云端硬盘中,并且可以共享。利用Colaboratory ,可以方便的使用Keras, TensorFlow, PyTorch, OpenCV 等框架进行深度学习应用的开发。最重要的是,Colab 可免费使用。 二、Colab基本操作 (1)创建笔记本 在正式介绍 Colab 之前需要说明一点,使用 Colab 需要科学上网。 要新建 Colab 需要创建笔记,笔记是 Colab 编辑文本、代码和运行程序的地方。使用过 jupyter notebook 的人应该很了解。不同笔记之间内容互不相通,可以把每一个笔记看做一台独立运行的虚拟机。 Colab 是谷歌的产品,因此需要实现注册好一个谷歌账号。 通过 Google Drive 创建笔记本 Google Drive 是 Google 的一款云端硬盘,操作与其他云盘,如百度网盘、阿里云盘,类似。 通过 Google Drive 可以创建 Colab 笔记。方式是:点击左上角的“新建”按钮或右击背景 => 在弹出的窗口中选择“更多” => 选择 “Google Colaboratory” 选项。...

三月 4, 2023 · 2 分钟 · 267 字 · Wokron

用 Pytorch 实现简单循环神经网络

一、歌词生成项目 想要在 nlp 方面深入,于是选择训练生成一个 RNN 网络,主要目标是自动生成歌词。在这里受到了 最浅显易懂的 PyTorch 深度学习入门 的启发,并利用 up 主提供的 源码 中的数据集。 相关代码的编写也有参考该 up 主的部分,但均为在理解内容的基础上自行编写的。另外也有对该 up 主代码中的疏漏进行修改的地方。 二、数据的获取 (1)编写数据集 原作者用爬虫获取的歌词数据被保存在 lyrics.txt 文件中。我们要将数据按可供训练的模型加载。具体来说 我们希望每一次获取数据,都能得到输入和目标输出(对本项目来说就是两段有一个文字偏差的序列) 并且将文字数字化,即 nlp 的 tokenize 为了实现批量训练,需要每次获取定长的序列 为了实现第一点,我们要继承 dataset;实现第二点,需要根据数据建立字符表;实现第三点,需要定长截取歌词句子的一部分。 另外,为了减少每次加载数据所用的时间,还需要将数据集的信息持久化。 我们的 LyricsDataset 具体实现如下。首先,我们在构造函数中通过传入的路径加载数据,判断是否已经存在处理过后的数据,如存在则加载;如不存在则读入原始数据并处理 class LyricsDataset(Dataset): def __init__(self, root_path, seq_size): self.seq_size = seq_size processed_name = "/processed/lyrics.pth" raw_name = "/raw/lyrics.txt" if os.path.exists(root_path + processed_name): print("find processed data") self.__load_processed_data(root_path + processed_name) else: print("processed data not found, will process raw data") self....

一月 17, 2023 · 4 分钟 · 642 字 · Wokron

机器学习 NLP 基本知识

一、自然语言处理(nlp)简介 一份思绪奔驰的前言: 语言的边界就是思想的边界。如果从人类所具有的一切中挑出一个事物,让它来显示出人与其他生物的不同之处,那一定是语言。语言是我们用来思考和交流的方式,我们的一切文明都构筑在这简单的一维序列中,可我们却几乎不曾深入了解过它。 有人说,我们不曾真正的理解语言,我们所有对语言的运用和理解,不过建立在婴儿及此后对他人的声音与书本上符号的猜测上。或许正是如此,但是我们依旧要做出猜测,向着语言的神秘进发,这是我们的信念,是我们认识我们的认识的开始。 (1)作为语言学的 nlp 早在计算机的上古时代,深度学习还未诞生的时候,自然语言处理作为语言学的一个领域就已诞生了,这个领域也被语言学家们称为计算机语言学。两个名称在一起,才表达出 nlp 的真正含义——通过机器处理语言。nlp 最早的研究方向是机器翻译,那时人们人为地总结语言的规律,对词汇进行标注,对语句进行句法分析。结果是人为的规则覆盖面不足,所设计的系统无法扩展。 (2)作为机器学习研究领域的 nlp 随着计算机的发展,出现了基于传统统计学习模型的自然语言处理方式。这些原始的模型较之之前有所进步,但受限于计算机性能,统计方法也遭遇了瓶颈。 直到近年来算力的发展,使得深度神经网络成为可能。深度神经网络结构中潜在的学习能力,在 nlp 领域发挥了作用。通过多维数据表示语言和含义,深度学习以高效且与人类认知过程相似的方式发挥了巨大的效果。 二、词向量 词汇作为符号,其形象是离散的;但词汇的所指作为定义,其含义却是丰富而连续的。比如说“母亲”这个词汇,既表示了这个概念所对应的事物是在一种血缘关系中的一方(她是孩子的母亲);又表示了这个事物是能繁殖者(母鸡);在一定程度上,同样表示了非血缘关系,但具有类似血缘关系的行为的个体(大地是母亲)。 偏个题,《来自深渊》中有对生骸语的类似的描述. 因此,我们就不能再将词汇只作为离散的符号看待了,不能认为词汇之间是相互排斥的关系了。我们需要将词汇看做某些元含义在不同程度下的集合,或者从机器学习的角度,把这些元含义称作特征。那么也就是说,我们将每个词汇都看成一定维度的向量。 但是我们要如何确定特征呢?特征的数量又有多少?如果人工地确定特征为“存在、含义、物质、精神”等等,这一过程将耗费精力且永无止境。实际上按照机器学习的一般策略,我们只需要通过统计文本,自发的构建词汇向量即可。 这一方面有许多算法,如 N-gram 算法,GloVe 算法等等。另外也可以在深度学习的过程中利用反向传播自发的调整词向量,在 pytorch 中这通过 Embedding 层来实现。 三、循环神经网络(RNN)及其变体 (1)朴素 RNN 考虑我们说话或写作时的基本逻辑。对于一段语言序列,在之后的词汇总是和之前的词汇有关,未表达的部分总是已表达部分的补全或补充。循环神经网络的机制类似,我们需要用一个或多个隐藏变量作为对之前语句含义的表示,在输出下一个词汇时,会让隐藏变量参与决策;同时每多说完一个词汇,这个词汇也会更新隐藏变量,以实现表达含义的更新。 具体来说,我们用 $t$ 表示时间序列,对某一时间 $t$,$x_t$ 表示输入,$y_t$ 表示输出,$h_t$ 表示隐含状态。那么朴素的 RNN 网络即: $$ h_t = tanh(W^{(hx)} x_t + W^{(hh)} h_{t-1}) $$ $$ y_t = W^{(S)} h_t $$ 容易看出 RNN 和 Moore 自动机有相似之处。 其中 $W^{(hx)}, W^{(hh)}, W^{(S)} h_t$ 分别为三个不同的矩阵。RNN 的激活函数也可以选择 ReLU。同时可以为激活函数中的部分添加偏置(bias)$b^{(hx)}, b^{(hh)}$ 等。...

一月 17, 2023 · 2 分钟 · 328 字 · Wokron