numpy手写NLP模型(四)———— RNN

2023-10-28

1. 模型介绍

首先介绍一下RNN,RNN全程为循环神经网络,主要用来解决一些序列化具有顺序的输入的问题。普通的前馈神经网络的输入单一决定输出,输出只由输入决定,比如一个单调函数的拟合,一个x决定一个y,前馈神经网络可以直接拟合出一条曲线并得到不错的拟合效果。再举一个例子,给出sin(x)的值,假设x属于[0, 2π),让你输出x的值是多少,前馈神经网络还能直接做到吗?显然是不可以的,因为一个sin(x)在一个周期内对应着多个值,单一的信息是不能直接确定x的值的,因此无法简单地通过前馈神经网络做到很好的拟合。那么这个时候要推测x的值,就不仅需要sin(x)的值,还需要sin(x)的值在前几个时刻的值来共同确定,放在连续函数中来说就是不仅需要函数在这个点的,还需要函数在这个点的导数才行。而RNN正是一个可以解决这样问题的神经网络,它不仅考虑当前的输入,还同时考虑之前多个时刻的输入,并由多个时刻的状态共同决定输出。

2. 模型

2.1 模型的输入

首先看看这个模型的结构图:

在这里插入图片描述
假设模型的原始输入是一段文本,这段文本显然是由一个一个单词挨个连接而成的,是有序的,比如一句话"I love you"和另一句话"You love me",意思就是不同的,尽管组成这两句话的单词是完全一样的。而RNN网络的输入就是这样一个有序的序列输入。同时每一个状态的输出不仅由当前节点的输入决定,同时还受上一时刻的状态所影响,这个理念和理解一句话中的某个单词很相似,当前单词的意思不仅由这个单词本身决定,还要受到之前的词,也就是当前单词所处的语境的影响。回到之前的例子,

2.2 模型的前向传播

首先,前文一直提到当前状态的输出不仅和当前的输入有关,还和上一个状态有关,体现在公式上就是:
在这里插入图片描述
在这里插入图片描述

2.3 模型的反向传播

模型的反向传播部分的话我就不多加阐述了,我参考的仍然是刘建平老师的博客,原博客讲得很好。其实自己也完完全全推导了一遍RNN的反向传播求导的公式,求出了最后每个元素求导的公式,奈何数学功底不够,没能强行变换成一个整体的公式,因为这个diag(1-h(t)^2)之前完全没想到可以这么整,可能你现在已经听不懂我在说啥了,但是如果你先自己推导一遍,然后卡住了之后再去看那个博客,你就会懂的(斜眼笑)

3. 模型的代码实现

目前代码还存在一些问题(也可能是很多问题),后续会修改

首先我们来看初始化部分:
window_size:表示输入单词的个数,也可以理解成 t
hidden_size:就是每个节点隐藏层的维数
embed_size:就是每个单词embedding的维数
n_class:就是分类的类数,比如单词预测中问题中,n_class就是词典的大小

# model.py
class RNN:
    def __init__(self, window_size, hidden_size, embed_size, n_class):
        self.hidden_size = hidden_size
        self.window_size = window_size
        self.n_classs = n_class
        self.embed_size = embed_size

        self.w = np.random.random((hidden_size, hidden_size))
        self.u = np.random.random((hidden_size, embed_size))
        self.v = np.random.random((n_class, hidden_size))
        self.b = np.random.random((hidden_size, 1))
        self.c = np.random.random((n_class, 1))
        self.x = []

        self.hidden_node_list = []
        # window_size means how many words in each input batch
        # for example, if i input "I love apple" into the network, then the window_size is 3
        for i in range(window_size):
            # initialize all the nodes in the hidden layer
            # then the net will calculate some related value in the forward part
            new_node = np.random.random((hidden_size, 1))
            self.hidden_node_list.append(new_node)

然后看一下前向传播:

# model.py
    def forward(self, x):
        self.x = x

        # default h0 = 0
        h0 = np.zeros((self.hidden_size, 1))

        # before calculate, we need to clear the node list of the net
        self.hidden_node_list.clear()

        # calculate some intermediate variables
        for i in range(self.window_size):
            new_node = Node()
            if i == 0:
                new_node.h = np.tanh(np.dot(self.u, x[0]) + np.dot(self.w, h0) + self.b)
            else:
                new_node.h = np.tanh(np.dot(self.u, x[i]) + np.dot(self.w, self.hidden_node_list[i - 1].h))
            new_node.d_tanh = 1 - new_node.h ** 2
            new_node.o = np.dot(self.v, new_node.h) + self.c
            self.hidden_node_list.append(new_node)

明白了RNN前向传播的公式的话,forward这部分应该很好懂。

接着看RNN的反向传播,建议数学推导搞明白后再看代码,那样会很明了:

# model.py
    
    def backward(self, target_output, lr):
        h0 = np.zeros((self.hidden_size, 1))

        # then calculate the gradient in each hidden layer
        predict = softmax(self.hidden_node_list[-1].o)
        for i in range(self.window_size):
            j = self.window_size - i - 1
            if i == 0:
                self.hidden_node_list[j].e = np.dot(self.v.T, predict - target_output)
            else:
                temp = np.dot(self.w.T, diag(self.hidden_node_list[j + 1].d_tanh))
                self.hidden_node_list[j].e = np.dot(temp, self.hidden_node_list[j + 1].e)
        dloss_w = np.zeros((self.hidden_size, self.hidden_size))
        dloss_u = np.zeros((self.hidden_size, self.embed_size))
        dloss_b = np.zeros((self.hidden_size, 1))

        dloss_c = predict - target_output
        dloss_v = np.dot(predict-target_output, self.hidden_node_list[-1].h.T)

        for i in range(self.window_size):
            temp = np.dot(diag(self.hidden_node_list[i].d_tanh), self.hidden_node_list[i].e)
            if i == 0:
                # seem unnecessary~
                dloss_w += 0
            else:
                dloss_w += np.dot(temp, self.hidden_node_list[i - 1].h.T)
            dloss_b += temp
            dloss_u += np.dot(temp, self.x[i].T)

        self.w -= lr * dloss_w
        self.u -= lr * dloss_u
        self.v -= lr * dloss_v
        self.b -= lr * dloss_b
        self.c -= lr * dloss_c

最后附上本博客的github代码

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

numpy手写NLP模型(四)———— RNN 的相关文章

  • Blenderbot 微调

    我一直在尝试微调 HuggingFace 的对话模型 Blendebot 我已经尝试过官方拥抱脸网站上给出的传统方法 该方法要求我们使用 trainer train 方法来完成此操作 我使用 compile 方法尝试了它 我尝试过使用 Py
  • 生成易于记忆的随机标识符

    与所有开发人员一样 我们在日常工作中不断处理某种标识符 大多数时候 它与错误或支持票有关 我们的软件在检测到错误后 会创建一个包 该包的名称由时间戳和版本号格式化 这是创建合理唯一标识符以避免混淆包的一种廉价方法 例子 错误报告 20101
  • 语音识别中如何处理同音词?

    对于那些不熟悉什么是同音字 https en wikipedia org wiki Homophone是的 我提供以下示例 我们的 是 嗨和高 到 太 二 在使用时语音API https developer apple com docume
  • 用于估计(一元)困惑度的 NLTK 包

    我正在尝试计算我所拥有的数据的困惑度 我正在使用的代码是 import sys sys path append usr local anaconda lib python2 7 site packages nltk from nltk co
  • NLTK 中的无监督 HMM 训练

    我只是想进行非常简单的无监督 HMM 训练nltk http www nltk org 考虑 import nltk trainer nltk tag hmm HiddenMarkovModelTrainer from nltk corpu
  • 是否可以使用 Google BERT 来计算两个文本文档之间的相似度?

    是否可以使用 Google BERT 来计算两个文本文档之间的相似度 据我了解 BERT 的输入应该是有限大小的句子 一些作品使用 BERT 来计算句子的相似度 例如 https github com AndriyMulyar semant
  • AttributeError:类型对象“Word2Vec”没有属性“load_word2vec_format”

    我正在尝试实现 word2vec 模型并收到属性错误 AttributeError 类型对象 Word2Vec 没有属性 load word2vec format 下面是代码 wv Word2Vec load word2vec format
  • PHP 和 NLP:嵌套括号(解析器输出)到数组?

    想要将带有嵌套括号的文本转换为嵌套数组 以下是 NLP 解析器的输出示例 TOP S NP PRP I VP VBP love NP NP DT a JJ big NN bed PP IN of NP NNS roses 原文 我喜欢一大床
  • 举例解释bpe(字节对编码)?

    有人可以帮忙解释一下背后的基本概念吗BPE模型 除了这张纸 https arxiv org abs 1508 07909 目前还没有那么多解释 到目前为止我所知道的是 它通过将罕见和未知的单词编码为子词单元序列来实现开放词汇表上的 NMT
  • 斯坦福 CoreNLP:使用部分现有注释

    我们正在尝试利用现有的 代币化 句子分割 和命名实体标记 同时我们希望使用斯坦福 CoreNlp 额外为我们提供 词性标注 词形还原 和解析 目前 我们正在尝试以下方式 1 为 pos lemma parse 创建一个注释器 Propert
  • 用于词性标记的优秀 Java 库是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用“自然”语言编写代码更好吗?

    我最近看到一种编程语言叫做超新星 http supernova sourceforge net 他们在网页上说 超新星编程语言是 现代脚本语言和 第一个提出了概念 用直接虚构进行编程 描述使用 纯人类语言的清晰子集 你可以编写如下代码 i
  • 如何使用动词时态/语气制作稀疏匹配器模式?

    我一直在尝试使用动词时态和情绪为 spacy 匹配器创建一个特定的模式 我发现了如何使用 model vocab morphology tag map token tag 访问使用 spacy 解析的单词的形态特征 当动词处于虚拟语气模式
  • 如何从 Pandas DataFrame 转换为 Tensorflow BatchDataset 以进行 NLP?

    老实说 我想弄清楚如何转换数据集 格式 pandasDataFrame或 numpy 数组 转换为简单文本分类张量流模型可以训练用于情感分析的形式 我使用的数据集类似于 IMDB 包含文本和标签 正面或负面 我看过的每个教程要么以不同的方式
  • 从 Penn Treebank 格式的文本中提取子句

    说我有一句话 After he had eaten the cheese Bill went to the grocery 在我的程序中 我得到以下输出 PARSE TREE ROOT S SBAR IN After S NP PRP he
  • 获取 NLTK 索引的所有结果

    我正在使用 NLTK 来查找单词的一致性 但我不知道如何获取所有结果并将它们放入list or set 例如 text concordance word 仅打印前 25 个结果 TL DR text concordance lines 10
  • Java文本输出中的UTF-8编码问题

    我一直致力于测试高棉语 Unicode Wordbreaker 的各种解决方案 高棉语单词之间没有空格 这使得拼写检查和语法检查变得困难 以及从旧高棉语转换为高棉语 Unicode 我得到了一些源代码 现在在线 http www white
  • nltk 标记化和缩写

    我用 nltk 对文本进行标记 只是将句子输入到 wordpunct tokenizer 中 这会拆分缩写 例如 don t 到 don t 但我想将它们保留为一个单词 我正在改进我的方法 以实现更精确的文本标记化 因此我需要更深入地研究
  • R 中带有变音符号的字符列表

    我试图将字符串中的电话 字符 出现次数制成表格 但变音符号单独作为字符制成表格 理想情况下 我有一个国际音标的单词列表 其中包含大量变音符号以及它们与基本字符的几种组合 我在这里给出了仅包含一个单词的 MWE 但对于单词列表和更多类型的组合
  • 有人可以简单解释一下自然语言处理的要素吗?

    我是自然语言处理的新手 对所使用的术语感到困惑 什么是代币化 POS 标签 实体识别 标记化只是将文本分割成可以有意义的部分或为这些部分赋予含义 以及含义 当我确定某物是名词 动词或形容词时 它的名字是什么 如果我想分为日期 姓名 货币呢

随机推荐

  • Mac电脑-mysql密码忘了怎么处理

    1 关闭mysql服务 老版本 sudo usr local mysql support files mysql server stop mac新版本 sudo usr local bin mysql server stop 或者 系统偏好
  • CSS盒子模型-01-优先级-基本测试

    3 1优先级的介绍 特性 不同选择器具有不同的优先级 优先级高的选择器样式会覆盖优先级低选择器样式 优先级公式 继承 lt 通配符选择器 lt 标签选择器 lt 类选择器 lt id选择器 lt 行内样式 lt important 注意点
  • C#基础知识

    快捷键 占位符 Console WriteLine 第一个数字是 0 第二个数字是 1 第三个数字是 3 n1 n2 n3 能取消斜线的转义作用 将字符串按照编辑的原格式输出 string str 11 n11 System IO File
  • Spring事务详解与使用

    Spring事务核心对象 J2EE开发使用分层设计的思想进行 对于简单的业务层转调数据层的单一操作 事务开启在业务层或者数据层并无太大差别 当业务中包含多个数据层的调用时 需要在业务层开启事务 对数据层中多个操作进行组合并归属于同一个事务进
  • Unity接入IAP、服务器验单(Google Play)

    Unity接入IAP 服务器验单 Google Play 最近因为项目需要 被分配来做项目SDK接入以及上架相关事宜 搞了好几天关于Unity接入支付的SDK 接入很简单 卡的最久的就是服务器验单 google相关文档也不是很全 走通之后觉
  • eclipse的Toggle Block Selection Mode功能---列模式

    快捷键 Alf Shift A Toggle Block Selection Mode 块选择模式开关 用法 首先用快捷键或者toolbar打开选择模式 会出现一个十字 表明块选择模式已开启 选中要统一修改的块 可以从 剪贴板ctrl v替
  • 2020大数据技术体系结构图,你值得拥有

    大数据技术体系结构图 JAVA JAVAEE核心 hadoop生态体系及各种框架 spark生态体系 Flink生态体系 JAVA JAVAEE核心 hadoop生态体系及各种框架 spark生态体系 Flink生态体系 希望对大家有所帮助
  • [设计模式] GoF 23种经典设计模式

    原文链接 https www yuque com cppdev patterns zainii GOF设计模式 Gang of Four 四人帮 设计模式的经典书籍 设计模式 可复用面向对象软件的基础 是由四个人共同完成 故GOF设计模式特
  • Spring Boot学习笔记

    文章目录 Spring Boot Spring Boot 整合 JSP Spring Boot HTML Thymeleaf 常用语法 Spring Boot 数据校验 Spring Boot 整合 JDBC Spring Boot 整合
  • Python中创建Dataframe的方法

    介绍4种在Python中创建Dataframe的方法 1 由数组 list组成的字典创建DataFrame import pandas as pd import numpy as np In 1 data pd DataFrame name
  • 【图卷积神经网络】1-入门篇:为什么使用图神经网络(上)

    在本节中 将涵盖以下主要内容 为什么使用图 为什么学习图 为什么使用图神经网络 为什么使用图 首先需要回答的问题是 为什么对图感兴趣 图论是对图进行数学研究的学科 它已经成为理解复杂系统和关系的基本工具 图是一种将节点 也称为顶点 和连接这
  • 03.1-常见端口及攻击汇总

    常用端口号及攻击方向汇总 文件共享服务端口 端口号 端口说明 攻击方向 21 22 69 Ftp Tftp 文件传输协议 允许匿名的上传 下载 爆破和嗅探操作 2049 Nfs 服务 配置不当 139 Samba 爆破 未授权访问 远程代码
  • 利用Qt的pro文件中DEFINES实现条件宏

    想利用宏定义实现不同的代码功能 但不想每次都去代码里注释或者不注释相关的宏定义变量 在这种情况下 就可以在pro里面利用DEFINES字段实现相关宏的定义 例如pro里面加上 DEFINES MYTEST 在代码里就可以使用 ifdef M
  • 服务发现框架选型,Consul还是Zookeeper还是etcd

    背景 本文并不介绍服务发现的基本原理 除了一致性算法之外 其他并没有太多高深的算法 网上的资料很容易让大家明白上面是服务发现 想直接查看结论的同学 请直接跳到文末 目前 市面上有非常多的服务发现工具 Open Source Service
  • LLVM Cookbook

    链接 https blog csdn net qq 23599965 article details 88344459 https github com zy445566 llvm guide zh 万花筒 用LLVM实现语言 备注 万花筒
  • 【Linux】性能优化-linux命令nicstat 网络性能监控

    文章目录 1 概述 1 概述 Unix 里一个受欢迎的命令行工具就是 nicstat 它可以显示每个网络接口的流量概要 包括网络接口的使用度 nicstat 5 Time Int rKB s wKB s rPk s wPk s rAvs w
  • Git_回退到上一次commit与pull

    git 回退到上个版本 rollback 回滚 git reset HEAD git 回退到上一版本
  • Cocos2d-x3.2 Sprite精灵类的创建与设置

    3 0版本以后 sharedXXX方法改成了getInstance方法 Director getInstance gt getVisibleSize 1 2 3 4 5 6 7
  • CSS网页页面图像灰色滤镜写法示例

    阿酷TONY 原创 2022 12 1 长沙 grayscale 函数是一个内置函数 用于对图像应用滤镜以设置图像的灰度 用法 grayscale amount 参数 此函数接受包含灰度值的单个参数量 灰度值根据数量和百分比设置 值0 表示
  • numpy手写NLP模型(四)———— RNN

    numpy手写NLP模型 四 RNN 1 模型介绍 2 模型 2 1 模型的输入 2 2 模型的前向传播 2 3 模型的反向传播 3 模型的代码实现 1 模型介绍 首先介绍一下RNN RNN全程为循环神经网络 主要用来解决一些序列化具有顺序