精华内容
下载资源
问答
  • 【Pytorch神经网络实战案例】11 循环神经网络结构训练语言模型并进行简单预测
    千次阅读
    2022-03-20 16:58:47

    1 语言模型步骤

    简单概述:根据输入内容,继续输出后面的句子。

    1.1 根据需求拆分任务

    • (1)先对模型输入一段文字,令模型输出之后的一个文字。
    • (2)将模型预测出来的文字当成输入,再放到模型里,使模型预测出下一个文字,这样循环下去,以使RNN完成一句话的输出。

    1.2 根据任务设计功能模块

    • (1)模型能够记住前面文字的语义;
    • (2)能够根据前面的语义和一个输入文字,输出下一个文字。

    1.3 根据功能模块设计实现方案

    RNN模型的接口可以输出两个结果:预测值和当前状态

    1. 在实现时,将输入的序列样本拆开,使用循环的方式,将字符逐个输入模型。模型会对每次的输入预测出两个结果,一个是预测字符,另一个是当前的序列状态。
    2. 在训练场景下,将硕测字骑用于计算损失,列状动用于传入下一次循环计算。
    3. 在测试场景下,用循环的方式将输入序列中的文字一个个地传入到模型中,得到最后一个时刻的当前状态,将该状态和输入序列中的最后一个文字转入模型,生成下一个文字的预测结果。同时,按照要求生成的文字条件,重复地将新生成的文字和当前状态输入模型,来预测下一个文字。

    2 语言模型的代码实现

    2.1 准备样本数据

    样本内容:
    在尘世的纷扰中,只要心头悬挂着远方的灯光,我们就会坚持不懈地走,理想为我们灌注了精神的蕴藉。所以,生活再平凡、再普通、再琐碎,我们都要坚持一种信念,默守一种精神,为自己积淀站立的信心,前行的气力。

    2.1.1定义基本工具函数---make_Language_model.py(第1部分)

    首先引入头文件,然后定义相关函数:get_ch_lable()从文件中获取文本,get_ch._able_v0将文本数组转方向量,具体代码如下:

    import numpy as np
    import torch
    import torch.nn.functional as F
    import time
    import random
    from collections import Counter
    
    # 1.1 定义基本的工具函数
    RANDOM_SEED = 123
    torch.manual_seed(RANDOM_SEED)
    DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    def elapsed(sec): # 计算时间函数
        if sec < 60:
            return str(sec) + "sec"
        elif sec<(60*60):
            return str(sec/60) + "min"
        else:
            return str(sec/(60*60)) + "hour"
    
    training_file = 'csv_list/wordstest.txt' # 定义样本文件
    
    #中文字
    def get_ch_label(txt_file): # 提取样本中的汉字
        labels = ""
        with open(txt_file,'rb') as f :
            for label in f:
                labels = labels + label.decode("gb2312",errors = 'ignore')
        return labels
    
    #中文多文件
    def readalltxt(txt_files): # 处理中文
        labels = []
        for txt_file in txt_files:
            target = get_ch_label(txt_file)
            labels.append(target)
        return labels
    
    # 将汉子转化成向量,支持文件和内存对象里的汉字转换
    def get_ch_label_v(txt_file,word_num_map,txt_label = None):
        words_size = len(word_num_map)
        to_num = lambda word:word_num_map.get(word,words_size)
        if txt_file != None:
            txt_label = get_ch_label(txt_file)
        # 使用to_num()实现单个汉子转成向量的功能,如果没有该汉字,则将返回words_size(值为69)
        labels_vector = list(map(to_num,txt_label)) # 将汉字列表中的每个元素传入到to_num()进行转换
        return labels_vector

    2.1.2 样本预处理---make_Language_model.py(第2部分)

    样本预处理这个一套指读取整个样本,将其放入training_data里,获取全部的字表words,并生成样本向量wordlabel与向量有对应关系的word_num_map,代码如下:

    # 1.2 样本预处理
    training_data = get_ch_label(training_file)
    print("加载训练模型中")
    print("该样本长度:",len(training_data))
    counter = Counter(training_data)
    words = sorted(counter)
    words_size = len(words)
    word_num_map = dict(zip(words,range(words_size)))
    print("字表大小:",words_size)
    wordlabel = get_ch_label_v(training_file,word_num_map)
    # 加载训练模型中
    # 该样本长度: 75
    # 字表大小: 41(去重)

        上述结果表示样本文件里一共有75个文字,其中掉重复的文字之后,还有41个。这41个文字将作为字表词典,建立文字与索引值的对应关系。
        在训练模型时,每个文字都会被转化成数字形式的索引值输入模型。模型的输出是这41个文字的概率,即把每个文字当成一类。

    2.2 代码实现:构建循环神经网络模型---make_Language_model.py(第3部分)

    使用GRU构建RNN模型,令RNN模型只接收一个序列的喻入字符,并预测出下一个序列的字符。
    在该模型里,所需要完成的步骤如下:

    1. 将输入的字索引转为词嵌入;
    2. 将词嵌入结果输入GRU层;
    3. 对GRU结果做全连接处理,得到维度为69的预测结果,这个预测结果代表每个文字的概率。

    2.2.1 代码实现

    # 1.3 构建循环神经网络(RNN)模型
    class GRURNN(torch.nn.Module):
        def __init__(self,word_size,embed_dim,hidden_dim,output_size,num_layers):
            super(GRURNN, self).__init__()
            self.num_layers = num_layers
            self.hidden_dim = hidden_dim
    
            self.embed = torch.nn.Embedding(word_size,embed_dim)
            # 定义一个多层的双向层:
            #               预测结果:形状为[序列,批次,维度hidden_dim×2],因为是双向RNN,故维度为hidden_dim
            #               序列状态:形状为[层数×2,批次,维度hidden_dim]
            self.gru = torch.nn.GRU(input_size=embed_dim,
                                    hidden_size=hidden_dim,
                                    num_layers=num_layers,bidirectional=True)
            self.fc = torch.nn.Linear(hidden_dim *2,output_size)# 全连接层,充当模型的输出层,用于对GRU输出的预测结果进行处理,得到最终的分类结果
    
        def forward(self,features,hidden):
            embeded = self.embed(features.view(1,-1))
            output,hidden = self.gru(embeded.view(1,1,-1),hidden)
            # output = self.attention(output)
            output = self.fc(output.view(1,-1))
            return output,hidden
    
        def init_zero_state(self): # 对于GRU层状态的初始化,每次迭代训练之前,需要对GRU的状态进行清空,因为输入的序列是1,故torch.zeros的第二个参数为1
            init_hidden = torch.zeros(self.num_layers*2,1,self.hidden_dim).to(DEVICE)
            return init_hidden

    2.3 代码实现:实例化,训练模型--make_Language_model.py(第3部分)

    # 1.4 实例化模型类,并训练模型
    EMBEDDING_DIM = 10 # 定义词嵌入维度
    HIDDEN_DIM = 20 # 定义隐藏层维度
    NUM_LAYERS = 1 # 定义层数
    # 实例化模型
    model = GRURNN(words_size,EMBEDDING_DIM,HIDDEN_DIM,words_size,NUM_LAYERS)
    model = model.to(DEVICE)
    optimizer = torch.optim.Adam(model.parameters(),lr=0.005)
    
    # 定义测试函数
    def evaluate(model,prime_str,predict_len,temperature=0.8):
        hidden = model.init_zero_state().to(DEVICE)
        predicted = ""
        # 处理输入语义
        for p in range(len(prime_str) -1):
            _,hidden = model(prime_str[p],hidden)
            predicted = predicted + words[predict_len]
        inp = prime_str[-1] # 获得输入字符
        predicted = predicted + words[inp]
        #按照指定长度输出预测字符
        for p in range(predict_len):
            output,hidden = model(inp,hidden) # 将输入字符和状态传入模型
            # 从多项式中分布采样
            # 在测试环境下,使用温度的参数和指数计算对模型的输出结果进行微调,保证其数值是大于0的数,小于0,torch.multinomial()会报错
            # 同时,使用多项式分布的方式进行采样,生成预测结果
            output_dist = output.data.view(-1).div(temperature).exp()
            inp = torch.multinomial(output_dist,1)[0] # 获取采样结果
            predicted = predicted + words[inp] # 将索引转化成汉字保存在字符串中
        return predicted
    
    # 定义参数并训练
    training_iters = 5000
    display_step = 1000
    n_input = 4
    step = 0
    offset = random.randint(0,n_input+1)
    end_offset = n_input + 1
    
    while step < training_iters: # 按照迭代次数训练模型
        start_time = time.time() # 计算起始时间
        #随机取一个位置偏移
        if offset > (len(training_data)-end_offset):
            offset = random.randint(0,n_input+1)
        # 制作输入样本
        inwords = wordlabel[offset:offset+n_input]
        inwords = np.reshape(np.array(inwords),[n_input,-1,1])
        # 制作标签样本
        out_onehot = wordlabel[offset+1:offset+n_input+1]
        hidden = model.init_zero_state() # RNN的状态清零
        optimizer.zero_grad()
    
        loss = 0.0
        inputs = torch.LongTensor(inwords).to(DEVICE)
        targets = torch.LongTensor(out_onehot).to(DEVICE)
        for c in range(n_input): # 按照输入长度将样本预测输入模型并进行预测
            outputs,hidden = model(inputs[c],hidden)
            loss = loss + F.cross_entropy(outputs,targets[c].view(1))
        loss = loss / n_input
        loss.backward()
        optimizer.step()
        # 输出日志
        with torch.set_grad_enabled(False):
            if (step+1)%display_step == 0 :
                print(f'Time elapesd:{(time.time() - start_time)/60:.4f}min')
                print(f'step {step + 1}|Loss {loss.item():.2f}\n\n')
                with torch.no_grad():
                    print(evaluate(model,inputs,32),'\n')
                print(50*'=')
        step = step +1
        # 每次迭代结束,将偏移值相后移动n_input+1个距离单位,可以保证输入数据的样本相互均匀,否则会出现文本两边的样本训练次数较少的情况。
        offset = offset + (n_input+1)
    print("Finished!")

    2.4 代码实现:运行模型生成句子--make_Language_model.py(第4部分)

    # 1.5 运行模型生成句子
    while True:
        prompt = "输入几个文字:"
        sentence = input(prompt)
        inputword = sentence.strip()
        try:
            inputword = get_ch_label_v(None,word_num_map,inputword)
            keys = np.reshape(np.array(inputword),[len(inputword),-1,1])
            # get_ch_label_v()中,如果在字典中找不到对应的索引,就会为其分配一个无效的索引值,
            # 进而在 evaluate()函数中调用模型的时,差不多对应对的有效词向量而终止报错
            model.eval()
            with torch.no_grad():
                sentence = evaluate(model,torch.LongTensor(keys).to(DEVICE),32)
            print(sentence)
        except: # 异常处理,当输入的文字不在模型字典中时,系统会报错,有意设置,防止输入超范围的字词
            print("还没学会")

    3 代码总览--make_Language_model.py

    import numpy as np
    import torch
    import torch.nn.functional as F
    import time
    import random
    from collections import Counter
    
    # 1.1 定义基本的工具函数
    RANDOM_SEED = 123
    torch.manual_seed(RANDOM_SEED)
    DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    
    def elapsed(sec): # 计算时间函数
        if sec < 60:
            return str(sec) + "sec"
        elif sec<(60*60):
            return str(sec/60) + "min"
        else:
            return str(sec/(60*60)) + "hour"
    
    training_file = 'csv_list/wordstest.txt' # 定义样本文件
    
    #中文字
    def get_ch_label(txt_file): # 提取样本中的汉字
        labels = ""
        with open(txt_file,'rb') as f :
            for label in f:
                labels = labels + label.decode("gb2312",errors = 'ignore')
        return labels
    
    #中文多文件
    def readalltxt(txt_files): # 处理中文
        labels = []
        for txt_file in txt_files:
            target = get_ch_label(txt_file)
            labels.append(target)
        return labels
    
    # 将汉子转化成向量,支持文件和内存对象里的汉字转换
    def get_ch_label_v(txt_file,word_num_map,txt_label = None):
        words_size = len(word_num_map)
        to_num = lambda word:word_num_map.get(word,words_size)
        if txt_file != None:
            txt_label = get_ch_label(txt_file)
        # 使用to_num()实现单个汉子转成向量的功能,如果没有该汉字,则将返回words_size(值为69)
        labels_vector = list(map(to_num,txt_label)) # 将汉字列表中的每个元素传入到to_num()进行转换
        return labels_vector
    
    # 1.2 样本预处理
    training_data = get_ch_label(training_file)
    print("加载训练模型中")
    print("该样本长度:",len(training_data))
    counter = Counter(training_data)
    words = sorted(counter)
    words_size = len(words)
    word_num_map = dict(zip(words,range(words_size)))
    print("字表大小:",words_size)
    wordlabel = get_ch_label_v(training_file,word_num_map)
    # 加载训练模型中
    # 该样本长度: 75
    # 字表大小: 41(去重)
    
    # 1.3 构建循环神经网络(RNN)模型
    class GRURNN(torch.nn.Module):
        def __init__(self,word_size,embed_dim,hidden_dim,output_size,num_layers):
            super(GRURNN, self).__init__()
            self.num_layers = num_layers
            self.hidden_dim = hidden_dim
    
            self.embed = torch.nn.Embedding(word_size,embed_dim)
            # 定义一个多层的双向层:
            #               预测结果:形状为[序列,批次,维度hidden_dim×2],因为是双向RNN,故维度为hidden_dim
            #               序列状态:形状为[层数×2,批次,维度hidden_dim]
            self.gru = torch.nn.GRU(input_size=embed_dim,
                                    hidden_size=hidden_dim,
                                    num_layers=num_layers,bidirectional=True)
            self.fc = torch.nn.Linear(hidden_dim *2,output_size)# 全连接层,充当模型的输出层,用于对GRU输出的预测结果进行处理,得到最终的分类结果
    
        def forward(self,features,hidden):
            embeded = self.embed(features.view(1,-1))
            output,hidden = self.gru(embeded.view(1,1,-1),hidden)
            # output = self.attention(output)
            output = self.fc(output.view(1,-1))
            return output,hidden
    
        def init_zero_state(self): # 对于GRU层状态的初始化,每次迭代训练之前,需要对GRU的状态进行清空,因为输入的序列是1,故torch.zeros的第二个参数为1
            init_hidden = torch.zeros(self.num_layers*2,1,self.hidden_dim).to(DEVICE)
            return init_hidden
    
    # 1.4 实例化模型类,并训练模型
    EMBEDDING_DIM = 10 # 定义词嵌入维度
    HIDDEN_DIM = 20 # 定义隐藏层维度
    NUM_LAYERS = 1 # 定义层数
    # 实例化模型
    model = GRURNN(words_size,EMBEDDING_DIM,HIDDEN_DIM,words_size,NUM_LAYERS)
    model = model.to(DEVICE)
    optimizer = torch.optim.Adam(model.parameters(),lr=0.005)
    
    # 定义测试函数
    def evaluate(model,prime_str,predict_len,temperature=0.8):
        hidden = model.init_zero_state().to(DEVICE)
        predicted = ""
        # 处理输入语义
        for p in range(len(prime_str) -1):
            _,hidden = model(prime_str[p],hidden)
            predicted = predicted + words[predict_len]
        inp = prime_str[-1] # 获得输入字符
        predicted = predicted + words[inp]
        #按照指定长度输出预测字符
        for p in range(predict_len):
            output,hidden = model(inp,hidden) # 将输入字符和状态传入模型
            # 从多项式中分布采样
            # 在测试环境下,使用温度的参数和指数计算对模型的输出结果进行微调,保证其数值是大于0的数,小于0,torch.multinomial()会报错
            # 同时,使用多项式分布的方式进行采样,生成预测结果
            output_dist = output.data.view(-1).div(temperature).exp()
            inp = torch.multinomial(output_dist,1)[0] # 获取采样结果
            predicted = predicted + words[inp] # 将索引转化成汉字保存在字符串中
        return predicted
    
    # 定义参数并训练
    training_iters = 5000
    display_step = 1000
    n_input = 4
    step = 0
    offset = random.randint(0,n_input+1)
    end_offset = n_input + 1
    
    while step < training_iters: # 按照迭代次数训练模型
        start_time = time.time() # 计算起始时间
        #随机取一个位置偏移
        if offset > (len(training_data)-end_offset):
            offset = random.randint(0,n_input+1)
        # 制作输入样本
        inwords = wordlabel[offset:offset+n_input]
        inwords = np.reshape(np.array(inwords),[n_input,-1,1])
        # 制作标签样本
        out_onehot = wordlabel[offset+1:offset+n_input+1]
        hidden = model.init_zero_state() # RNN的状态清零
        optimizer.zero_grad()
    
        loss = 0.0
        inputs = torch.LongTensor(inwords).to(DEVICE)
        targets = torch.LongTensor(out_onehot).to(DEVICE)
        for c in range(n_input): # 按照输入长度将样本预测输入模型并进行预测
            outputs,hidden = model(inputs[c],hidden)
            loss = loss + F.cross_entropy(outputs,targets[c].view(1))
        loss = loss / n_input
        loss.backward()
        optimizer.step()
        # 输出日志
        with torch.set_grad_enabled(False):
            if (step+1)%display_step == 0 :
                print(f'Time elapesd:{(time.time() - start_time)/60:.4f}min')
                print(f'step {step + 1}|Loss {loss.item():.2f}\n\n')
                with torch.no_grad():
                    print(evaluate(model,inputs,32),'\n')
                print(50*'=')
        step = step +1
        # 每次迭代结束,将偏移值相后移动n_input+1个距离单位,可以保证输入数据的样本相互均匀,否则会出现文本两边的样本训练次数较少的情况。
        offset = offset + (n_input+1)
    print("Finished!")
    
    # 1.5 运行模型生成句子
    while True:
        prompt = "输入几个文字:"
        sentence = input(prompt)
        inputword = sentence.strip()
        try:
            inputword = get_ch_label_v(None,word_num_map,inputword)
            keys = np.reshape(np.array(inputword),[len(inputword),-1,1])
            # get_ch_label_v()中,如果在字典中找不到对应的索引,就会为其分配一个无效的索引值,
            # 进而在 evaluate()函数中调用模型的时,差不多对应对的有效词向量而终止报错
            model.eval()
            with torch.no_grad():
                sentence = evaluate(model,torch.LongTensor(keys).to(DEVICE),32)
            print(sentence)
        except: # 异常处理,当输入的文字不在模型字典中时,系统会报错,有意设置,防止输入超范围的字词
            print("还没学会")
    
    
    

    模型结果:训练的并不好,但是还能用

    更多相关内容
  • 因此,就了现在的循环神经网络,他的本质是:拥有记忆的能力,并且会根据这些记忆的内容来进行推断。因此,他的输出就依赖于当前的输入和记忆。 网络结构及原理 循环神经网络的基本结构特别简单,就是将网络的输出...
  • 主流的循环神经网络就是以RNN为基础的各种变体模型 人工神经网络: 卷积神经网络: 循环神经网络: 三种基本类型总览: RNN: 每个序列索引位置t都一个隐藏状态h(t)。 进一步简化: ...

    主流的循环神经网络就是以RNN为基础的各种变体模型

    人工神经网络:

    卷积神经网络:

     循环神经网络:

     

     

    三种基本类型总览:

    RNN:

    每个序列索引位置t都有一个隐藏状态h(t)。

     

    进一步简化:

    由于RNN梯度消失的问题,就对于序列索引位置t的隐藏结构做了改进,可以说通过一些技巧让隐藏结构复杂了起来,来避免梯度消失的问题,这样的特殊RNN就是我们的LSTM。

    LSTM:

    细化讲解:

     

     除了细胞状态,LSTM图中还有了很多奇怪的结构,这些结构一般称之为门控结构(Gate)。LSTM在在每个序列索引位置t的门一般包括遗忘门,输入门和输出门三种。下面我们就来研究上图中LSTM的遗忘门,输入门和输出门以及细胞状态。

    LSTM之遗忘门:

    遗忘门(forget gate)顾名思义,是控制是否遗忘的,在LSTM中即以一定的概率控制是否遗忘上一层的隐藏细胞状态。遗忘门子结构如下图所示:

     其中Wf,Uf,bf为线性关系的系数和偏倚,和RNN中的类似。σ为sigmoid激活函数。

    LSTM之输入门:

    输入门(input gate)负责处理当前序列位置的输入,它的子结构如下图:

     

     

    LSTM之细胞状态更新:

    在研究LSTM输出门之前,我们要先看看LSTM之细胞状态。前面的遗忘门和输入门的结果都会作用于细胞状态C(t)。我们来看看从细胞状态C(t−1)如何得到C(t)。如下图所示:

     

     

    LSTM之输出门:

    有了新的隐藏细胞状态C(t),我们就可以来看输出门了,子结构如下:

     

     

     

     

     

     

    BiLSTM:

    前向的LSTM与后向的LSTM结合成BiLSTM。
    我们对“我爱中国”这句话进行编码:

     

     

     GRU:

    GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆和反向传播中的梯度等问题而提出来的。

    GRU和LSTM在很多情况下实际表现上相差无几,那么为什么我们要使用新人GRU(2014年提出)而不是相对经受了更多考验的LSTM(1997提出)呢。

    下图1-1引用论文中的一段话来说明GRU的优势所在。

    图1-1 R-NET: MACHINE READING COMPREHENSION WITH SELF-MATCHING NETWORKS(2017)

    简单译文:我们在我们的实验中选择GRU是因为它的实验效果与LSTM相似,但是更易于计算。

    简单来说就是贫穷限制了我们的计算能力...

    相比LSTM,使用GRU能够达到相当的效果,并且相比之下更容易进行训练,能够很大程度上提高训练效率,因此很多时候会更倾向于使用GRU。

    LSTM上一个稍显显著的变化是门控循环单元(GRU)。它将遗忘门和输入门组合成一个“更新门”,还将细胞状态和隐藏状态合并,并进行一些其他更改。由此产生的模型比标准的LSTM模型更简单,并且越来越流行。

     

     

    内部细化结构及流程请参阅人人都能看懂的GRU - 知乎

    GRU输入输出的结构与普通的RNN相似,其中的内部思想与LSTM相似。

    与LSTM相比,GRU内部少了一个”门控“,参数比LSTM少,但是却也能够达到与LSTM相当的功能。考虑到硬件的计算能力时间成本,因而很多时候我们也就会选择更加”实用“的GRU

    BiGRU
    在单向的神经网络结构中,状态总是从前往后输出的。然而,在文本情感分类中,如果当前时刻的输出能与前一时刻的状态和后一时刻的状态都产生联系。如对这样一个句子进行选词 填空 The sea water in the deep sea is so____ that the sun does not shine.通过在 The sea water in the deep sea 和 the sun does not shine 两部分内容,我们可以更加确信此处选填 deep,这样更 有利于文本深层次特征的提取,这就需要 BiGRU 来建立这种 联系。

    BiGRU 是由单向的、方向相反的、输出由这两个 GRU 的状态共同决定的 GRU 组成的神经网络模型。在每一时刻, 输入会同时提供两个方向相反的 GRU,而输出则由这两个单向 GRU 共同决定。BiGRU 的具体结构如图 4 所示。

     

     

    其中:GRU( )函数表示对输入的词向量的非线性变换,把词向量编码成对应的 GRU 隐层状态。 wt 、 vt 分别表示 t 时刻双向 GRU 所对应的前向隐层状态 h t 和反向隐状态 ht  所对应的权重, t b 表示 t 时刻隐层状态所对应的偏置。

    参考文献:

    人人都能看懂的GRU - 知乎

    【神经网络】综合篇——人工神经网络、卷积神经网络、循环神经网络、生成对抗网络_黎国溥-CSDN博客

    RNN LSTM GRU Attention transformer公式整理总结(超详细图文公式)_Luoyingfeng的博客-CSDN博客LSTM与BI-LSTM_lgy54321的博客-CSDN博客_bi lstm

    展开全文
  • 循环神经网络模型在腹膜透析临床预后预测中的初步应用.pdf
  • 深度学习神经网络之循环神经网络(RNN)Matlab实现循环神经网络RNN
  • 2021年中国神经网络模型系列研究(二):循环神经网络.pdf
  • 基于循环神经网络的花儿信息模型建模方法.pdf
  • 基于循环神经网络的找矿模型构建与预测.pdf
  • 基于新型联合循环神经网络(RNN)模型的出水总氮预测.pdf
  • 基于Python的循环神经网络(RNN)实现
  • 利用循环神经网络适合处理连续时间序列样本的特性,构建了一种基于循环神经网络的煤矿工作面瓦斯浓度预测模型。该模型以宽泛策略为原则初步确定预测模型网络结构参数,选取数据量更大、时间跨度更长的瓦斯浓度时间...
  • 嵌入指针网络的深度循环神经网络模型求解作业车间调度问题.pdf
  • 基于循环神经网络模型的用户入侵行为检测与管控研究.pdf
  • 循环神经网络(RNN)是一类非常强大的用于处理和预测序列数据的神经网络模型。循环结构的神经网络克服了传统机器学习方法对输入和输出数据的许多限制,使其成为深度学习领域中一类非常重要的模型。RNN及其变体网络已经...
  • 影响模型效果的其他因素三、循环神经网络进阶1.门控循环神经网络/门控循环单元(GRU)2.LSTM:长短期记忆3.深度循环神经网络(Deep RNN)4.双向循环神经网络(BRNN)   一、过拟合欠拟合 1.概念 欠拟合:训练误差(训练集...
  • 基于混合卷积神经网络和循环神经网络的入侵检测模型.pdf
  • 基于循环神经网络的动态模型辨识.pdf
  • 基于循环神经网络的医疗人力资源配置模型设计与仿真.pdf
  • 人工智能,rnn,股票,因子,华泰人工智能系列之九-人工智能选股之循环神经网络模型.,华泰人工智能系列之九-人工智能选股之循环神经网络模型.
  • 循环神经网络模型可以对序列片段进行学习,找到样本间的顺序特征。这个特性非常适合运用在语言处理方向。 1.1 语言模型简介 语言模型包括文法语言模型和统计语言模型,一般指统计语言模型。 1.1.1 统计语言模型...

    1 语言模型

    循环神经网络模型可以对序列片段进行学习,找到样本间的顺序特征。这个特性非常适合运用在语言处理方向。

    1.1 语言模型简介

    语言模型包括文法语言模型和统计语言模型,一般指统计语言模型。

    1.1.1 统计语言模型

    统计语言模型是指:把语言(词的序列)看成一个随机事件,并赋予相应的概率来描述其属于某种语言集合的可能性,衡量一个句子的合理性,概率越高,说明这个句子越像是自然句子。

    统计语言模型的作用是,为一个长度为m的字符串确定一个概率分布P(w1,w2,...,wm),表示其存在的可能性。其中,”w1~wm”依次表示这段文本中的各个词,用这种模型通过这些方法可以保留一定的词序信息,获得一个词的上下文信息。

    2 词表与词向量

    2.1 词表与词向量

        词表是指给每个单词(或字)编码,即用数字来表示单词(或字),这样才能将句子输入到神经网络中进行处理。
        比较简单的词表是为每个单词(或字)按顺序进行编号,或将这种编号用one_hot编码来表示。但是,这种简单的编号方式只能描述不同的单词(或字),无法将单词(或字)的内部含义表达出来。

    于是人们开始用向量来映射单词(或字),可以表达更多信息,这种用来表示每个词的向量就称为词向量(也称词嵌入)。词向量可以理解为one-hot编码的升级版,它使用多维向量更好地描述词与词之间的关系。

    2.2 词向量的原理与实现

    词向量的最大优势在于可以更好地表示上下文语义。

    2.2.1 词向量的含义

    词向量表示词与词之间的远近关系映射为向量间的距离,从而最大限度地保留了单词(或字)原有的特征,建立在分布假说(distributional hypothesis)基础上的,即假设词的语义由其上下文决定,上下文相似的词,其语义也相似。

    2.2.2 词向量的组成

    (1)选择一种方式描述上下文;

    (2)选择一种模型刻画某个目标词与其上下文之间的关系。

    2.3 词向量的原理与实现

      one_hot编码的映射方法本质上也属于词向量,即把每个字表示为一个很长的向量,这个向量的维度是词表大小,并且只有一个维度的值为1,其余的维度都为0。这个为1的度就代表了当前的字。
        one_hot编码与词向量的唯一区别就是仅仅将字符号化,不考虑任何语义信息。如one_hot编码每一个元素由整型改为浮点型,同时再将原来稀疏的巨大维度压缩嵌入到人更小维度的空间,那么它就等同于词向量。

     2.4 词向量的实现

    在神经网络的实现中,词向量更多地被称为词嵌入(word embedding),具体做法是将二维的张量映射到多维空间,即embedding中的元素将不再是、个字,而变成了字所转化的多维向量,所有向量之间是有距离远近关系的。

    3 NLP中多项式的分布

    在自然语言中,一句话中的某个词并不是唯一的。例如,“代码医生工作室真棒”这句话中的最后一个字“棒”,也可以换成“好”,不会影响整句话的语义。

    3.1 RNN模型中存在的问题

    在RNN模型中,将一个使用语言样本训练好的模型用于生成文本时,会发现模型总会将在下一时刻出现概率最大的那个词取出,即仅仅实现一种语言的设计,这种生成文本的方式失去了语言本身的多样性。

    3.2 解决方案

    为了解决这个问题,将RNN模型的最终结果当成一个多项式分布(multinomialdistribution),以分布取样的方式预测出下一序列的词向量。用这种方法所生成的句子更符合语言的特性。

    3.2.1 多项式分布

    多项式分布多项式分布是二项式分布的拓展。

    二项式分布的典型例子是“扔硬币”:硬币正面朝上的概率为P,重复扔n次硬币,所得到k次正面朝上的概率即为一个二项式分布概率。把二项式分布公式拓展至多种状态,就得到了多项式分布。

    3.2.2 多项式分布在RNN模型中的应用

    多项式分布在RNN模型中的应用在RNN模型中,预测的结果不再是下一个序列中出现的具体某一个词,而是这个词的分布情况,这便是在RNN模型中使用多项式分布的核心思想。在获得该词的多项式分布之后,便可以在该分布中进行采样操作,获得具体的词,这种方式更符合NLP任务中语言本身的多样性,即一个句子中的某个词并不是唯一的。

    3.2.3 RNN模型中的实现步骤

        (1)将RNN模型预测的结果通过全连接或卷积,变成与字典维度相同的数组。
        (2)用该数组代表模型所预测结果的多项式分布。
        (3)用torch.multinomial()函数从预测结果中采样,得到真正的预测结果。

    3.3 torch.multinomial()

    torch.multinomial(input, num_samples,replacement=False, out=None) → LongTensor
    • 函数作用:对input的每一行做n_samples次取值,输出的张量是每一次取值时input张量对应行的下标。输入是一个input张量,一个取样数量,和一个布尔值replacement。
    • input:张量可以看成一个权重张量,每一个元素代表其在该行中的权重。如果有元素为0,那么在其他不为0的元素,被取干净之前,这个元素是不会被取到的。
    • n_samples:是每一行的取值次数,该值不能大于每一样的元素数,否则会报错。
    • replacement:指的是取样时是否是有放回的取样,True是有放回,False无放回。

    3.3.1 代码实现(每次多想次分布采样的结果均不同)

    import torch
    # 生成一串0-1的随机数
    data = torch.rand(2,4)
    print("生成的数据列表",data)
    #生成的数据列表 tensor([[0.8998, 0.6512, 0.9156, 0.8575],[0.8455, 0.4838, 0.6859, 0.2629]])
    a = torch.multinomial(data,1)
    print("第一次采样结果:",a)
    # 第一次采样结果: tensor([[0],[0]])
    b = torch.multinomial(data,1)
    print("第二次采样结果:",b)
    # 第二次采样结果: tensor([[0],[1]])

    4 循环神经网络的实现

     4.1 RNN的底层类

    torch.nn.LSTM类与torch..nn.GRU类并不属于单层的网络结构,它本质上是对RNNCell的二次封装,将基本的RNN Cell按照指定的参数连接起来,形成一个完整的RNN。

    在torch.nn.LSTM类与torch.nn.GRU类的内部还会分别调用torch.nn.LSTMCel类与torch.nn.GRUCell类进行具体实现。

    展开全文
  • 这是我论文的示例代码: Khanesar,MA,MA ... “循环模糊神经网络模型的混合训练。” 在机电一体化和自动化,2007 年。ICMA 2007 年。国际会议,第 2598-2603 页。 IEEE,2007 年。 主要代码名为 main_awpso。
  • 基于叠层循环神经网络的语义关系分类模型.pdf
  • 本节介绍循环神经网络,下图展示了如何基于循环神经网络实现语言模型。 •裁剪梯度 循环神经网络中较容易出现梯度衰减或梯度爆炸,这会导致网络几乎无法训练。裁剪梯度(clip gradient)是一种应对梯度爆炸的方法。...
  • 基于语言模型循环卷积神经网络的事件检测.pdf
  • 基于循环神经网络的多源异构大数据融合模型构建.pdf
  • 序列模型是监督学习的一种,也就是其输入数据是带标签的。如语音识别、音乐生成、情感分析、DNA序列分析、机器翻译、视频行为识别、人名实体识别等,其特点是输入或输入或者输入输出是时序的。

    简介
    RNN( Recurrent Neural Network 循环神经网络) 跟人的大脑记忆差不多。RNN通过反向传播和记忆机制,能够处理任意长度的序列,在架构上比前馈神经网络更符合生物神经网络的结构,它的产生也正是为了解决这类问题而应用而生的。RNN及改进的LSTM等深度学习模型都是基于神经网络而发展的起来的认知计算模型。

    RNN的架构有哪些?

    • one to one:
      一个输入(单一标签)对应一个输出(单一标签)。
      在这里插入图片描述
    • one to many:
      一个输入对应多个输出,即这个架构多用于图片的对象识别,即输入一个图片,输出一个文本序列。
      在这里插入图片描述
    • many to one:
      多个输入对应一个输出,多用于文本分类或视频分类,即输入一段文本或视频片段,输出类别。
      在这里插入图片描述
    • many to many 1:
      这种结构广泛的用于机器翻译,输入一个文本,输出另一种语言的文本。
      在这里插入图片描述
    • many to many 2:
      这种广泛的用于序列标注。
      在这里插入图片描述
      RNN原理:
      先介绍RNN最简单的循环神经网络,称为Simple-RNN,它是后面LSTM的基础。从网络架构上,Simple-RNN与BP神经网络一脉相承,两个网络都有前馈层和反馈层,但Simple-RNN引入的基于时间的循环机制,因此而发展了BP网络。下面从整体上考察Simple-RNN的架构和训练运行。
      在这里插入图片描述
      神经网络为A,通过读取某个t时间(状态)的输入Xt,然后输出一个值ht。循环可以使得从当前时间步传递到下一个时间步。这些循环使得RNN可以被看做同一个网络在不同时间步的多次循环,每个神经元会把更新的结果传递到下一个时间步,为了更清楚的说明,将这个循环展开,放大该神经网络A,看一下网络细节:
      在这里插入图片描述
      递归网络的输入是一整个序列,也就是X=[ X0, … , Xt-1, Xt, Xt+1, XT ],对于语言模型来说,每一个Xt将代表一个词向量,一整个序列就代表一句话。ht代表时刻t的隐含状态,yt代表时刻t的输出。
      其中:U是输入层到隐藏层直接的权重;W是隐藏层到隐藏层的权重;V是隐藏层到输出层的权重。
      RNN展开以后,似乎都已经很明白了,正向传播( Forward Propagation ) 依次按照时间的顺序计算一次即可,反向传播( Back Propagation ) 从最后一个时间将累积的残差传递回来即可,跟普通的BP神经网络训练并没有本质上的不同。由于加入了时间顺序,计算的方式有所不同,这称为BPTT ( Back Propagation Through Time ) 算法。
      1.正向传播:
      首先在t=0的时刻,U、V、W都被随机初始化好了,h0通常初始化为0,然后进行如下计算:
      在这里插入图片描述
      其中,f 、g 是激活函数,g通常是Softmax。
      注:RNN有记忆能力,正是因为这个 W,记录了以往的输入状态,作为下次的输出。这个可以简单的理解为:
      在这里插入图片描述
      全局误差为:
      在这里插入图片描述
      E是全局误差,ei是第i个时间步的误差,y是输出层预测结果,d是实际结果。误差函数fe可以为交叉熵 ,也可以是平方误差项等。
      2.反向传播:
      就是利用输出层的误差e,求解各个权重ΔV、ΔU、ΔW,然后梯度下降更新各个权重。各个权重的更新的递归公式:
      在这里插入图片描述
      小结:
      到这里,Simple-RNN原理也就讲解完了。但是实际应用中并不多,原因为:
    • 如果出入越长的话,展开的网络就越深,对于“深度”网络训练的困难最常见的是“梯度爆炸” 和 “梯度消失” 的问题。
    • Simple-RNN善于基于先前的词预测下一个词,但在一些更加复杂的场景中,例如,“我出生在法国…我能将一口流利的法语。”
      “法国”和“法语”则需要更长时间的预测,而随着上下文之间的间隔不断增大时,Simple-RNN会丧失学习到连接如此远的信息的能力。

    系列传送门:
    序列模型汇总__长短期记忆网络(LSTM)(二)
    序列模型汇总__门控循环单元(GRU)(三)

    展开全文
  • 三种循环神经网络模型进行系统性的测试。在月频的多因子选股方面,循 环神经网络具有出色的样本外预测平均正确率,但是样本外平均AUC 值表 现一般。神经网络在年化超额收益率、信息比率上优于线性回归算法,但 是...
  • RNN神经网络模型综述

    千次阅读 2019-05-12 09:32:39
    简单循环神经网络 RNN的基本结构 RNN的运算过程和参数更新 RNN的前向运算 RNN的参数更新 一.前言 前馈神经网络不考虑数据之间的关联性,网络的输出只和当前时刻网络的输入相关。然而在解决很多实际问...
  • 基于深度循环神经网络和改进SMOTE算法的组合式入侵检测模型.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,226
精华内容 25,290
关键字:

循环神经网络的模型有哪些