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 的相关文章

  • AttributeError:使用 CRF 时“Tensor”对象没有属性“_keras_history”

    我知道关于这个问题有很多问题 我已经阅读了其中的一些问题 但没有一个对我有用 I am trying to build a model with the following architecture 代码如下 token inputs In
  • 日语/字符的编程技巧[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个想法 可以编写一些网络应用程序来帮助我 也许还有其他人 更好地学习日语 因为我正在学习日语 我的问题是该网站主要是英文的 所以
  • IOB 准确度和精密度之间的差异

    我正在使用命名实体识别和分块器对 NLTK 进行一些工作 我使用重新训练了分类器nltk chunk named entity py为此 我采取了以下措施 ChunkParse score IOB Accuracy 96 5 Precisi
  • 如何调整 NLTK 句子标记器

    我正在使用 NLTK 来分析一些经典文本 但我在按句子标记文本时遇到了麻烦 例如 这是我从以下内容中得到的片段莫比迪克 http www gutenberg org cache epub 2701 pg2701 txt import nlt
  • 如何计算两个文本文档之间的相似度?

    我正在考虑使用任何编程语言 尽管我更喜欢 Python 来从事 NLP 项目 我想获取两个文档并确定它们的相似程度 常见的方法是将文档转换为 TF IDF 向量 然后计算它们之间的余弦相似度 任何有关信息检索 IR 的教科书都涵盖了这一点
  • 词干函数错误:词干需要一个位置参数

    这里的stem函数显示错误 指出stem需要循环中的一个位置参数 如所讨论的 from nltk stem import PorterStemmer as ps text my name is pythonly and looking fo
  • BERT - 池化输出与序列输出的第一个向量不同

    我在 Tensorflow 中使用 BERT 有一个细节我不太明白 根据文档 https tfhub dev google bert uncased L 12 H 768 A 12 1 https tfhub dev google bert
  • 生成易于记忆的随机标识符

    与所有开发人员一样 我们在日常工作中不断处理某种标识符 大多数时候 它与错误或支持票有关 我们的软件在检测到错误后 会创建一个包 该包的名称由时间戳和版本号格式化 这是创建合理唯一标识符以避免混淆包的一种廉价方法 例子 错误报告 20101
  • 将单引号替换为双引号并排除某些元素

    我想用双引号替换字符串中的所有单引号 但出现的情况除外 例如 n t ll m 等 input the stackoverflow don t said hey what output the stackoverflow don t sai
  • 从文本文件中提取与输入单词最相似的前 N ​​个单词

    我有一个文本文件 其中包含我使用 BeautifulSoup 提取的网页内容 我需要根据给定的单词从文本文件中找到 N 个相似的单词 流程如下 从中提取文本的网站 https en wikipedia org wiki Football h
  • NLTK 中的无监督 HMM 训练

    我只是想进行非常简单的无监督 HMM 训练nltk http www nltk org 考虑 import nltk trainer nltk tag hmm HiddenMarkovModelTrainer from nltk corpu
  • gensim如何计算doc2vec段落向量

    我正在看这篇论文http cs stanford edu quocle paragraph vector pdf http cs stanford edu quocle paragraph vector pdf 它指出 段落向量和词向量被平
  • 缩短文本并仅保留重要句子

    德国网站 nandoo net 提供了缩短新闻文章的可能性 如果使用滑块更改百分比值 文本会发生变化并且某些句子会被遗漏 您可以在这里看到它的实际效果 http www nandoo net read article 299925 http
  • 如何提取句子中的主语及其各自的从属短语?

    我正在尝试在句子中进行主题提取 以便我能够根据主题获得情感 我在用nltk在 python2 7 中用于此目的 以下面的句子为例 Donald Trump is the worst president of USA but Hillary
  • Fine-Tuning DistilBertForSequenceClassification:不是学习,为什么loss没有变化?权重没有更新?

    我对 PyTorch 和 Huggingface transformers 比较陌生 并对此尝试了 DistillBertForSequenceClassificationKaggle 数据集 https www kaggle com c
  • 使用“自然”语言编写代码更好吗?

    我最近看到一种编程语言叫做超新星 http supernova sourceforge net 他们在网页上说 超新星编程语言是 现代脚本语言和 第一个提出了概念 用直接虚构进行编程 描述使用 纯人类语言的清晰子集 你可以编写如下代码 i
  • 如何从 Pandas DataFrame 转换为 Tensorflow BatchDataset 以进行 NLP?

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

    我一直致力于测试高棉语 Unicode Wordbreaker 的各种解决方案 高棉语单词之间没有空格 这使得拼写检查和语法检查变得困难 以及从旧高棉语转换为高棉语 Unicode 我得到了一些源代码 现在在线 http www white
  • 如何使用FeatureUnion转换PipeLine中的多个特征?

    我有一个 pandas 数据框 其中包含有关用户发送的消息的信息 对于我的模型 我感兴趣的是预测消息的缺失收件人 即给定消息的收件人 A B C 我想预测还有谁应该成为收件人的一部分 我正在使用 OneVsRestClassifier 和
  • nltk 标记化和缩写

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

随机推荐

  • 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全程为循环神经网络 主要用来解决一些序列化具有顺序