循环神经网络(Recurrent Neural Networks,简称RNNs)是一类用于处理序列数据的神经网络。与传统的神经网络(如全连接神经网络或卷积神经网络)不同,RNNs具有记忆能力,能够捕获序列数据中的时间依赖性和模式。这使得RNNs在自然语言处理、语音识别、时间序列预测等领域具有广泛的应用。
一、RNNs的基本结构
RNNs的基本结构包括输入层、隐藏层和输出层。其中,隐藏层是RNNs的核心部分,它通过循环的方式连接,使得每个时间步的隐藏层都能接收上一时间步的隐藏层状态作为输入。这种结构使得RNNs能够捕获序列数据中的时间依赖性。
二、RNNs的工作原理
- 输入层:接收当前时间步的输入数据(如一个单词、一个时间点的观测值等)。
- 隐藏层:根据当前时间步的输入数据和上一时间步的隐藏层状态,计算当前时间步的隐藏层状态。这个状态包含了从序列开始到当前时间步的所有信息。隐藏层状态的计算通常使用非线性激活函数(如tanh或ReLU)进行。
- 输出层:根据当前时间步的隐藏层状态,计算当前时间步的输出。输出层可以是一个简单的全连接层,也可以是更复杂的结构(如softmax层用于分类任务)。
- 循环连接:隐藏层的状态通过循环连接传递给下一个时间步的隐藏层。这种循环连接使得RNNs能够捕获序列数据中的时间依赖性。
三、RNNs的变种
由于RNNs在处理长序列时存在梯度消失和梯度爆炸的问题,研究者们提出了许多RNNs的变种来改进这些问题,包括:
- 长短期记忆网络(Long Short-Term Memory,LSTM):通过引入门控机制(如输入门、遗忘门和输出门)来控制信息的传递和遗忘,从而有效地解决了梯度消失和梯度爆炸的问题。
- 门控循环单元(Gated Recurrent Unit,GRU):GRU是LSTM的一种简化版本,它合并了LSTM中的遗忘门和输入门,使得模型结构更加简单,但性能与LSTM相当。
- 双向循环神经网络(Bidirectional RNNs):双向RNNs同时考虑序列的前向和后向信息,从而能够捕获更丰富的上下文信息。
四、RNNs的应用
RNNs在自然语言处理、语音识别、时间序列预测等领域具有广泛的应用。例如,在机器翻译任务中,RNNs可以将一种语言的句子编码为向量表示,然后解码为另一种语言的句子;在语音识别任务中,RNNs可以将音频信号转换为文本序列;在时间序列预测任务中,RNNs可以利用历史数据来预测未来的趋势。
案例代码实现:
模型训练:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from keras.layers import Dense,LSTM import keras #解决中文显示问题 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False #加载数据 dataset = pd.read_csv("LBMA-GOLD.csv",index_col=[0]) #将第一列作为索引列和标题列 #print(dataset) #设置训练集的长度 training_len = 1056 #获取训练集 training_set = dataset.iloc[0:training_len, [0]] #获取测试集数据 test_set = dataset.iloc[training_len:, [0]] #print(test_set) #对数据集进行归一化 sc = MinMaxScaler(feature_range=(0,1)) train_set_scaled = sc.fit_transform(training_set) test_set = sc.fit_transform(test_set) #设置训练集特征和训练集标签 x_train = [] y_train = [] #设置测试集特征和训练集标签 x_test = [] y_test = [] #利用for循环进行训练集特征和标签的制作,提取数据中连练五天作为特征 for i in range(5,len(train_set_scaled)): x_train.append(train_set_scaled[i-5:i,0]) y_train.append(train_set_scaled[i,0]) #将训练集用list转换为array格式 x_train,y_train = np.array(x_train),np.array(y_train) # 使x_train符合输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。 # 此处整个数据集送入,送入样本数为x_train.shape[0]即训练数据的样本个数; 循环核时间展开步数定位5 x_train = np.reshape(x_train,(x_train.shape[0],5,1)) #print(x_train.shape) # 同理划分测试集数据 for i in range(5, len(test_set)): x_test.append(test_set[i - 5:i, 0]) y_test.append(test_set[i, 0]) # 测试集变array并reshape为符合要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数] x_test, y_test = np.array(x_test), np.array(y_test) x_test = np.reshape(x_test, (x_test.shape[0], 5, 1)) #print(x_test.shape) # # 搭建神经网络模型 model = keras.Sequential() model.add(LSTM(80, return_sequences=True, activation="relu")) model.add(LSTM(100, return_sequences=False, activation="relu")) model.add(Dense(10, activation="relu")) model.add(Dense(1)) # 对模型进行编译,选用学习率为0.01 model.compile(loss='mse', optimizer=keras.optimizers.Adam(0.01)) # 将训练集和测试集放入网络进行训练,每批次送入的数据为32个数据,一共训练50轮,将测试集样本放入到神经网络中测试其验证集的loss值 history = model.fit(x_train, y_train, batch_size=32, epochs=100, validation_data=(x_test, y_test)) model.save('model.h5') # 绘制训练集和测试集的loss值对比图 plt.plot(history.history['loss'], label='train') plt.plot(history.history['val_loss'], label='val') plt.title("LSTM神经网络loss值") plt.legend() plt.show()
数据测试:
# 导入库 import pandas as pd import numpy as np import matplotlib.pyplot from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error from math import sqrt from keras.models import load_model import matplotlib.pyplot as plt # 解决中文显示问题 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 加载历史数据文件 dataset = pd.read_csv('LBMA-GOLD.csv', index_col='Date') # print(dataset) # 设置训练集的长度 training_len = 1256 -200 # 获取测试集数据 test_set = dataset.iloc[training_len:, [0]] # 将数据集进行归一化,方便神经网络的训练 sc = MinMaxScaler(feature_range=(0, 1)) test_set = sc.fit_transform(test_set) # 设置放置测试数据特征和测试数据标签的列表 x_test = [] y_test = [] # 同理划分测试集数据 for i in range(5, len(test_set)): x_test.append(test_set[i - 5:i, 0]) y_test.append(test_set[i, 0]) # 测试集变array并reshape为符合要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数] x_test, y_test = np.array(x_test), np.array(y_test) x_test = np.reshape(x_test, (x_test.shape[0], 5, 1)) # 导入模型 model = load_model('model.h5') # 利用模型进行测试 predicted = model.predict(x_test) # print(predicted.shape) # 进行预测值的反归一化 prediction = sc.inverse_transform(predicted) # print(prediction) # 对测试集的标签进行反归一化 real = sc.inverse_transform(test_set[5:]) # print(real) # 打印模型的评价指标 rmse = sqrt(mean_squared_error(prediction, real)) mape = np.mean(np.abs((real-prediction)/prediction)) print('rmse', rmse) print('mape', mape) # 绘制真实值和预测值的对比 plt.plot(real, label='真实值') plt.plot(prediction, label='预测值') plt.title("基于LSTM神经网络的黄金价格预测") plt.legend() plt.show()
预测结果:
五,相关作品展示
基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目
基于Nodejs、Vue等前端技术开发的前端实战项目
基于微信小程序和安卓APP应用开发的相关作品
基于51单片机等嵌入式物联网开发应用
基于各类算法实现的AI智能应用
基于大数据实现的各类数据管理和推荐系统