网站建设 科目,wordpress邮件美化,哪个网站ppt模板免费下载,济南网站建设成之运维先附上这篇文章的一个思维导图什么是RNN按照八股文来说#xff1a;RNN实际上就是一个带有记忆的时间序列的预测模型RNN的细胞结构图如下#xff1a;softmax激活函数只是我举的一个例子#xff0c;实际上得到yt也可以通过其他的激活函数得到其中at-1代表t-1时…先附上这篇文章的一个思维导图什么是RNN按照八股文来说RNN实际上就是一个带有记忆的时间序列的预测模型RNN的细胞结构图如下softmax激活函数只是我举的一个例子实际上得到yt也可以通过其他的激活函数得到其中at-1代表t-1时刻隐藏状态at代表经过Xt这一t时刻的输入之后得到的新的隐藏状态。公式主要是at tanh(Waa * at-1 Wax * Xt b1) 大白话解释一下就是Xt是今天的吊针at-1是昨天的发烧度数39经过今天这一针之后at变成38度。这里的记忆体现在今天的38度是在前一天的基础上通过打吊针来达到第二天的降温状态。1.1 RNN的应用由于RNN的记忆性我们最容易想到的就是RNN在自然语言处理方面的应用譬如下面这张图提前预测出下一个字。除此之外RNN的应用还包括下面的方向语言模型RNN被广泛应用于语言模型的建模中例如自然语言处理、机器翻译、语音识别等领域。时间序列预测RNN可以用于时间序列预测例如股票价格预测、气象预测、心电图信号预测等。生成模型RNN可以用于生成模型例如文本生成、音乐生成、艺术创作等。强化学习RNN可以用于强化学习中例如在游戏、机器人控制和决策制定等领域。1.2 RNN的缺陷想必大家一定听说过LSTM没错就是由于RNN的尿性所以才出现LSTM这一更精妙的时间序列预测模型的设计。但是我们知己知彼才能百战百胜因此我还是决定详细分析一下RNN的缺陷看过一些资料但是只是肤浅的提到了梯度消失和梯度爆炸没有实际的数学推导这可不是一个求学之人应该有的态度主要的缺陷是两个长期依赖问题导致的梯度消失众所周知RNN模型是一个具有记忆的模型每一次的预测都和当前输入以及之前的状态有关但是我们试想如果我们的句子很长他在第1000个记忆细胞还能记住并很好的利用第1个细胞的记忆状态吗答案显然是否定的梯度爆炸1.2.1 梯度消失和梯度爆炸的详细公式推导敲黑板手写公式推导大家最迷糊的地方根据下面图示的例子我手写并反复检查了自己的过程下图请各位看官务必认真看看理解起来并不难对于别的文章随口一提的梯度消失和梯度爆炸实在是透彻太多啦我们假设损失函数 ,Y是实际值O是预测值;首先我们假设只有三层然后通过三层我们就能以此类推找出规律。反向传播我们需要对Wo,Wx,Ws,b四个变量都求偏导在这里我们主要对Wx求偏导其他三个以此类推就很简单了。为了表示更清晰笔者使用紫色的x表示乘法。根据推导的公式我们得到一个指数函数我们在高中时候就学到过指数函数的变化系数是极大的因此在t趋于比较大的时候也就是我们的句子比较长的时候如果比1小不少那么模型的一部分梯度会趋于0因此优化会几乎停止同理如果比1大一些那么模型的部分梯度会极大导致模型和的变化无法控制优化毫无意义。什么是LSTM八股文解释LSTM长短时记忆网络是一种常用于处理序列数据的深度学习模型与传统的 RNN循环神经网络相比LSTM引入了三个门输入门、遗忘门、输出门如下图所示和一个细胞状态cell state这些机制使得LSTM能够更好地处理序列中的长期依赖关系。注意小蝌蚪形状表示的是sigmoid激活函数Ct是细胞状态记忆状态是输入的信息是隐藏状态基于得到的用最朴素的语言解释一下三个门并且用两门考试来形象的解释一下LSTM遗忘门通过x和ht的操作并经过sigmoid函数得到0,1的向量0对应的就代表之前的记忆某一部分要忘记1对应的就代表之前的记忆需要留下的部分 代表复习上一门线性代数所包含的记忆通过遗忘门忘记掉和下一门高等数学无关的内容比如矩阵的秩输入门通过将之前的需要留下的信息和现在需要记住的信息相加也就是得到了新的记忆状态。代表复习下一门科目高等数学的时候输入的一些记忆比如洛必达法则等等那么已经线性代数残余且和高数相关的部分比如数学运算高数的知识新的记忆状态输出门整合得到一个输出代表高数所需要的记忆但是在实际的考试不一定全都发挥出来考到100分。因此则代表实际的考试分数为了便于大家理解附上几张非常好的图供大家理解完整的数据处理的流程遗忘门输入门细胞状态输出门2.1 LSTM的模型结构这里有两张别的博主的很好的图我在初学的时候也是恍然大悟图的出处解释一下pytorch训练lstm所使用的参数这是利用pytorch调用LSTM所使用的参数output,(h_n,c_n) lstm (x, [ht_1, ct_1])一般直接放入x就好后面中括号的不用管这是作为x输入喂给LSTM的参数x:[seq_length, batch_size, input_size],这里有点反人类batch_size一般都是放在开始的位置这是pytorch简历LSTM是所需参数lstm LSTM(input_size,hidden_size,num_layers)2.2 LSTM相比RNN的优势LSTM的反向传播的数学推导很繁琐因为涉及到的变量很多但是LSTM确实是可以在一定程度上解决梯度消失和梯度爆炸的问题。我简单说一下RNN的连乘主要是W的连乘而W是一样的因此就是一个指数函数在梯度中出现指数函数并不是一件友好的事情相反LSTM的连乘是对的偏导的不断累乘如果前后的记忆差别不大那偏导的值就是1那就是多个1相乘。当然也可能出现某一一些偏导的值很大但是一定不会很多换句话说一句话的前后没有逻辑那完全没有训练的必要。2.3 pytorch实现LSTM对股票的预测实战需要安装一下tushare的金融方面的数据集,代码的注解我已经写的很清楚了#!/usr/bin/python3
# -*- encoding: utf-8 -*-import matplotlib.pyplot as plt
import numpy as np
import tushare as ts
import pandas as pd
import torch
from torch import nn
import datetime
import timeDAYS_FOR_TRAIN 10class LSTM_Regression(nn.Module):使用LSTM进行回归参数- input_size: feature size- hidden_size: number of hidden units- output_size: number of output- num_layers: layers of LSTM to stackdef __init__(self, input_size, hidden_size, output_size1, num_layers2):super().__init__()self.lstm nn.LSTM(input_size, hidden_size, num_layers)self.fc nn.Linear(hidden_size, output_size)def forward(self, _x):x, _ self.lstm(_x) # _x is input, size (seq_len, batch, input_size)s, b, h x.shapex x.view(s * b, h)x self.fc(x)x x.view(s, b, -1) # 把形状改回来return xdef create_dataset(data, days_for_train5) - (np.array, np.array):根据给定的序列data生成数据集数据集分为输入和输出每一个输入的长度为days_for_train每一个输出的长度为1。也就是说用days_for_train天的数据对应下一天的数据。若给定序列的长度为d将输出长度为(d-days_for_train1)个输入/输出对dataset_x, dataset_y [], []for i in range(len(data) - days_for_train):_x data[i:(i days_for_train)]dataset_x.append(_x)dataset_y.append(data[i days_for_train])return (np.array(dataset_x), np.array(dataset_y))if __name__ __main__:t0 time.time()data_close ts.get_k_data(000001, start2019-01-01, indexTrue)[close] # 取上证指数的收盘价data_close.to_csv(000001.csv, indexFalse) #将下载的数据转存为.csv格式保存data_close pd.read_csv(000001.csv) # 读取文件df_sh ts.get_k_data(sh, start2019-01-01, enddatetime.datetime.now().strftime(%Y-%m-%d))print(df_sh.shape)data_close data_close.astype(float32).values # 转换数据类型plt.plot(data_close)plt.savefig(data.png, formatpng, dpi200)plt.close()# 将价格标准化到0~1max_value np.max(data_close)min_value np.min(data_close)data_close (data_close - min_value) / (max_value - min_value)# dataset_x# 是形状为(样本数, 时间窗口大小)# 的二维数组用于训练模型的输入# dataset_y# 是形状为(样本数, )# 的一维数组用于训练模型的输出。dataset_x, dataset_y create_dataset(data_close, DAYS_FOR_TRAIN) # 分别是1007,10,11007,1# 划分训练集和测试集70%作为训练集train_size int(len(dataset_x) * 0.7)train_x dataset_x[:train_size]train_y dataset_y[:train_size]# 将数据改变形状RNN 读入的数据维度是 (seq_size, batch_size, feature_size)train_x train_x.reshape(-1, 1, DAYS_FOR_TRAIN)train_y train_y.reshape(-1, 1, 1)# 转为pytorch的tensor对象train_x torch.from_numpy(train_x)train_y torch.from_numpy(train_y)model LSTM_Regression(DAYS_FOR_TRAIN, 8, output_size1, num_layers2) # 导入模型并设置模型的参数输入输出层、隐藏层等model_total sum([param.nelement() for param in model.parameters()]) # 计算模型参数print(Number of model_total parameter: %.8fM % (model_total / 1e6))train_loss []loss_function nn.MSELoss()optimizer torch.optim.Adam(model.parameters(), lr1e-2, betas(0.9, 0.999), eps1e-08, weight_decay0)for i in range(200):out model(train_x)loss loss_function(out, train_y)loss.backward()optimizer.step()optimizer.zero_grad()train_loss.append(loss.item())# 将训练过程的损失值写入文档保存并在终端打印出来with open(log.txt, a) as f:f.write({} - {}\n.format(i 1, loss.item()))if (i 1) % 1 0:print(Epoch: {}, Loss:{:.5f}.format(i 1, loss.item()))# 画loss曲线plt.figure()plt.plot(train_loss, b, labelloss)plt.title(Train_Loss_Curve)plt.ylabel(train_loss)plt.xlabel(epoch_num)plt.savefig(loss.png, formatpng, dpi200)plt.close()# torch.save(model.state_dict(), model_params.pkl) # 可以保存模型的参数供未来使用t1 time.time()T t1 - t0print(The training time took %.2f % (T / 60) mins.)tt0 time.asctime(time.localtime(t0))tt1 time.asctime(time.localtime(t1))print(The starting time was , tt0)print(The finishing time was , tt1)# for testmodel model.eval() # 转换成评估模式# model.load_state_dict(torch.load(model_params.pkl)) # 读取参数# 注意这里用的是全集 模型的输出长度会比原数据少DAYS_FOR_TRAIN 填充使长度相等再作图dataset_x dataset_x.reshape(-1, 1, DAYS_FOR_TRAIN) # (seq_size, batch_size, feature_size)dataset_x torch.from_numpy(dataset_x)pred_test model(dataset_x) # 全量训练集# 的模型输出 (seq_size, batch_size, output_size)pred_test pred_test.view(-1).data.numpy()pred_test np.concatenate((np.zeros(DAYS_FOR_TRAIN), pred_test)) # 填充0 使长度相同assert len(pred_test) len(data_close)plt.plot(pred_test, r, labelprediction)plt.plot(data_close, b, labelreal)plt.plot((train_size, train_size), (0, 1), g--) # 分割线 左边是训练数据 右边是测试数据的输出plt.legend(locbest)plt.savefig(result.png, formatpng, dpi200)plt.close()2.4 小问题为什么采用tanh函数不能都用sigmoid函数吗先放上两个函数的图形Sigmoid函数比Tanh函数收敛饱和速度慢Sigmoid函数比Tanh函数值域范围更窄tanh的均值是0Sigmoid均值在0.5左右均值在0的数据显然更便于数据处理tanh的函数变化敏感区间更大对两者求导发现tanh对计算的压力更小直接是1-原函数的平方不需要指数操作使用该问的图请标明出处创作不易希望收获你的赞赞