rnn/lstm 项目实战

tip:本项目用到的数据和代码在https://pan.baidu.com/s/1Cw6OSSWJevSv7T1ouk4B6Q?pwd=z6w2 

1. RNN : 预测股价

任务:基于zgpa_train.csv数据,建立RNN模型,预测股价

1.完成数据预处理,将序列数据转化为可用于RNN输入的数据

2.对新数据zgpa_test.csv进行预测,可视化结果

3.存储预测结果,并观察局部预测结果

备注:模型结构:单层RNN,输出有5个神经元,每次使用前8个数据预测第9个数据

1.1 数据准备

下面是一个预测股票的一个项目实战。

任务:基于zgpa_train.csv数据,建立RNN模型,预测股价

1.完成数据预处理,将序列数据转化为可用于RNN输入的数据

2.对新数据zgpa_test.csv进行预测,可视化结果

3.存储预测结果,并观察局部预测结果

备注:模型结构:单层RNN,输出有5个神经元,每次使用前8个数据预测第9个数据。

数据内容大致如下:

开始项目,代码如下: 

import pandas as pd
import numpy as np
data = pd.read_csv('zgpa_train.csv')
data.head()# 加载收盘价
price = data.loc[:, 'close']
price.head()# 归一化处理
price_norm = price/max(price)
print(price_norm)# 归一化之前的数据可视化
%matplotlib inline
from matplotlib import pyplot as plt
fig1 = plt.figure(figsize=(8,5))
plt.plot(price)
plt.title('close_price')  # 归一化之前的数据
plt.xlabel('time')
plt.ylabel('price')
plt.show()

%matplotlib inline的作用:

%matplotlib inline 是一个 IPython 魔法命令,用于在 Jupyter Notebook 中将 matplotlib 绘图直接嵌入到输出单元中。这样可以使绘图在 Notebook 中显示,而无需调用 plt.show() 方法。此外,它可以确保每次执行绘图代码时,图形都能在相应的输出单元显示,而不是在外部窗口中弹出。

inline:表示图像“在线”显示,意思是在 Jupyter Notebook 的输出单元中直接显示图像,而不是在单独的窗口中弹出。

# 对 X 与 y 进行赋值
# 定义方法去提取 X 与 y
def extract_data(data, time_step):X = []  # listy = []  # list# 例如,10个样本;time_step=8;# 第一组样本,0,1,2,...7# 第二组样本,1,2,3,...8# 第三组样本,2,3,4,...9# 共有2组样本可供观测for i in range(len(data)-time_step):X.append([a for a in data[i:i+time_step]])y.append(data[i+time_step])X = np.array(X)X = X.reshape(X.shape[0], X.shape[1], 1)return X, y

上面是设计数组X、y的函数,即X是因,y是果,用X的一个数组得到y的一个对应值;这里把X处理成了最后一个维度只有一个元素的维度,即X.shape =(*,*,...,1)。 

# 定义 X 与 y
time_step = 8
X, y = extract_data(price_norm, time_step)
print(X.shape) # 723个样本,每个样本有8个数据,每个样本对应1个单独数值,(723,8,1)
print(X[0, :, :]) # 第一个样本数据

这里使用刚才的函数,提供data和time_step,创建出X,y。

jupyter里可以不需要用那么多print,直接在单元格输入X.shape,X[0]就能得到相应的结果。

---------------------------------------------------------------------------------------------------------------------------

1.2 模型建立

下面是建立模型的主要代码,这段代码使用 Keras 构建了一个简单的 循环神经网络(RNN)模型,它适合用于 回归任务。以下是代码中各个步骤的解释::

from keras.models import Sequential        
from keras.layers import Dense, SimpleRNN  # 引入层相关,输出层与 RNN 层model = Sequential() # 创建实例
model.add(SimpleRNN(units=5, input_shape=(time_step, 1), activation='relu')) # RNN 层
model.add(Dense(units=1, activation='linear')) # 输出层,回归任务直接使用 linear 激活函数
model.compile(optimizer='adam', loss='mean_squared_error') # 回归使用mse评测
model.summary() 

逐步解析代码:

1. 导入模块
from keras.models import Sequential        
from keras.layers import Dense, SimpleRNN
  • Sequential:用于构建 Keras 的顺序模型,可以按顺序堆叠各层。
  • DenseSimpleRNN:分别代表全连接层和简单循环神经网络(RNN)层。
2. 创建模型实例
model = Sequential()

使用 Sequential() 创建一个顺序模型实例 model,可以层层堆叠神经网络层。

3. 添加 SimpleRNN 层
model.add(SimpleRNN(units=5, input_shape=(time_step, 1), activation='relu'))
  • SimpleRNN:一种简单的循环神经网络层。
  • units=5:表示 RNN 层有 5 个隐藏单元(Hidden Units)。
  • input_shape=(time_step, 1):输入的形状。假设时间步为 time_step,每步有一个特征。
  • activation='relu':使用 ReLU 激活函数。

1. 这一步就对应理论部分的由x到h,这里 units=5 表示 RNN 层有 5 个隐藏单元h,每个单元可以理解为负责捕捉某一方面的特征,这些单元共同作用,从输入数据中提取序列信息,并将提取到的特征传递到下一层或输出层。在这个RNN 模型中,每个时间步都会产生 5 个隐藏单元的输出

隐藏单元越多,模型能够捕捉的特征就越多,模型也会更复杂,适合处理高维和复杂数据。

2. input_shape=(time_step, 1):说明输入序列的长度和每个时间步的特征数量,用来告诉模型输入数据的形状。这里的特征指的是,描述了每个时间步的输入信息量,比如传感器数据流中每个时间步可能有多个传感器特征(例如温度、湿度、压力等)。这个模型只用到了一个特征,即close收盘价,对应之前数据准备只取了那一列。

3. activation='relu':指定了隐藏状态计算中的激活函数,即计算由x到h的激活函数。

4. 添加 Dense 输出层
model.add(Dense(units=1, activation='linear'))
  • 是在给模型添加一个 全连接层(Dense 层),该层有如下配置:

  • units=1:表示该层包含一个神经元,输出为一个值。对于回归任务(例如预测一个连续值),输出层通常只需一个神经元,因为只需输出一个预测结果。

  • activation='linear':激活函数设置为 linear,即线性激活函数。线性激活函数的作用是直接输出该层计算的值,不做任何非线性变换,这非常适合回归任务,因为回归问题中预测的目标值是连续的,需要直接输出真实值的估计。

即上面的隐藏状态h到这里的y,一个时间步对应只有一个y的输出,具体来说就是一个时间步里,刚才得到的5个隐藏状态h到输出的y,用到的激活函数是 linear。

5. 编译模型
model.compile(optimizer='adam', loss='mean_squared_error')
  • optimizer='adam':使用 Adam 优化器,适合多种神经网络优化。
  • loss='mean_squared_error':使用均方误差(MSE)作为损失函数,MSE 常用于回归问题评估模型预测的误差。

Adam 是一种自适应优化算法,具有以下特点:

  1. 自适应学习率:Adam 会为每个参数动态调整学习率,使得每个参数都能有合适的更新步长。
  2. 结合动量和 RMSProp 的优势:Adam 使用动量(Momentum)来平滑梯度的更新,同时利用 RMSProp 的方法来控制梯度的变化幅度,从而加速收敛。
 6. 模型结构总结
model.summary()

输出模型的层次结构、参数数量等信息,便于了解模型的总体结构和参数情况。 

总结

  • 该模型是一个用于回归任务的简单 RNN 模型,包含一个 RNN 层和一个全连接输出层。
  • 使用 ReLU 激活函数在隐藏层,线性激活函数在输出层,以适应回归任务。

--------------------------------------------------------------------------------------------------------------------------------

1.3 模型层数介绍

在深度学习模型中,层数概念指的是网络结构中的不同计算层,它们共同完成数据的逐步抽象和特征提取。一般来说,一个模型的层可以分为 输入层隐藏层输出层。这些层共同构成了模型的数据流动路径和特征提取结构。

(1). 输入层
  • 作用:接收输入数据并将其传递给模型的第一层。输入层本身不进行任何计算操作,仅定义输入数据的形状。
  • 表示方式:在 Keras 中,输入层是通过指定第一层的 input_shape 参数来隐式定义的,不会单独显示在 model.summary() 中。
  • 例子:在你的模型中,input_shape=(time_step, 1) 就定义了输入层,表示输入数据是一个具有 time_step 个时间步且每个时间步有 1 个特征的序列。
(2). 隐藏层
  • 作用:模型中真正进行特征提取、模式识别和学习的层。隐藏层可以是各种类型的神经网络层,例如全连接层(Dense)、卷积层(Conv2D)、循环层(SimpleRNN、LSTM)等。
  • 数量和类型:一个模型可以有多个隐藏层,这些层负责将输入数据逐步转换为更高层次的特征。
  • 例子:在你的模型中,SimpleRNN 层就是一个隐藏层。它接受输入数据的时间序列,并通过 5 个隐藏单元来提取时序特征。
(3). 输出层
  • 作用:生成最终的模型输出。输出层的形状和激活函数通常根据具体任务(如分类或回归)进行设置。
  • 设置:输出层通常是一个全连接层(Dense),其单元数量和激活函数会根据任务调整。例如,分类任务会使用 softmax 激活函数,而回归任务则使用 linear 激活函数。
  • 例子:在你的模型中,Dense(units=1, activation='linear') 是输出层,用于回归任务,输出一个连续值。

在深度学习模型中,层数包括输入层(逻辑上存在)、隐藏层(特征提取层)和输出层(生成预测结果)。在大多数框架中,输入层是隐式的,所以模型的“层数”通常只统计显式的隐藏层和输出层。

Dense 层可以同时作为 隐藏层输出层,它的角色取决于其在模型中的位置和任务。

  • 作为隐藏层:如果 Dense 层在模型的中间部分,用于进一步处理和转换特征,那么它就是隐藏层。例如,在一个深层神经网络中,前几层 Dense 层可以作为隐藏层,以提取输入数据的特征。

  • 作为输出层:如果 Dense 层是模型的最后一层,用于生成最终的输出(如分类概率或回归值),那么它就是输出层。例如,在分类任务中,最后一个 Dense 层通常会使用 softmax 激活函数作为输出层;在回归任务中,通常使用 linear 激活函数作为输出层。

上面提到的模型有 2 个显式的计算层(SimpleRNNDense):

  • 输入层(隐式):指定输入的形状 (time_step, 1),传入 SimpleRNN 层。
  • SimpleRNN 层:接收输入数据并生成 5 个隐藏状态的输出,作为时序特征。
  • Dense 输出层:接收 5 维的隐藏状态,将它转化为一个数值输出,用于回归任务。

--------------------------------------------------------------------------------------------------------------------------

1.4 训练模型

# 训练模型
model.fit(X, np.array(y), batch_size = 30, epochs = 200)

这一步使用 fit() 方法来训练模型,参数说明如下:

  • X:训练数据的输入特征。
  • y:训练数据的标签(目标值),这里先转换为 NumPy 数组 np.array(y)
  • batch_size=30:批量大小,每次更新模型权重时使用 30 个样本的数据,这样可以加快训练速度。
  • epochs=200:训练的轮数,将整个数据集训练 200 次,模型会在每个 epoch 后更新权重以逐步优化性能。

在训练过程中,模型会通过前向传播计算预测结果,通过反向传播调整权重,逐步减小预测值与真实值之间的误差。

在训练模型时,使用批量大小(batch_size=30)而不是全部样本进行权重更新,主要是为了在效率和性能上做出平衡。选择 batch_size=30,可以加快训练速度、减少内存占用,同时还可以引入一定的随机性,使得训练过程更稳定,减少陷入局部最优的风险。

------------------------------------------------------------------------------------------------------------------------------

1.5 基于训练数据做预测


# 基于训练数据做预测
y_train_predict = model.predict(X)*max(price) # 预测结果:去除归一化
y_train = [i * max(price) for i in y] # 训练数据真实结果

这部分代码进行基于训练数据的预测,并将预测结果“去归一化”,即将预测值和真实值还原到原始价格范围。详细说明如下:

  • y_train_predict:使用 model.predict(X) 基于训练数据 X 进行预测,得到归一化状态下的预测结果。之后通过 * max(price) 将预测结果恢复到原始数据范围,因为在数据预处理时可能将 price 归一化过,所以这里乘以 max(price) 还原到真实价格范围。

  • y_train:真实的训练数据 y 也被还原到原始数据范围。代码 [i * max(price) for i in y] 中,将归一化状态下的 y 乘以 max(price),以得到真实的训练数据价格。

tip:model.predict(X) 的详细过程

  1. 前向传播predict() 方法会将输入数据 X 逐层传递,通过网络结构中的每一层(如 RNN 层、Dense 层),并应用层中的权重和激活函数计算输出。

  2. 生成预测值:经过前向传播后,predict() 会输出每个输入样本的预测结果。这些结果的形状取决于模型的输出层结构。在你的模型中,输出层是一个 Dense 层,有一个神经元,所以 predict() 将返回每个输入样本的单一预测值。

--------------------------------------------------------------------------------------------------------------------------------

1.6 展示真实值和预测值

fig2 = plt.figure(figsize=(8, 5))
plt.plot(y_train, label='real price')
plt.plot(y_train_predict, label='predict price')
plt.title('close_price')  # 归一化之前的数据
plt.xlabel('time')
plt.ylabel('price')
plt.legend()
plt.show()

1.7 对测试数据进行预测

最后把测试数据放到刚才训练的模型,得到相应的预测值。

现预处理数据

# 对测试数据进行预测
data_test = pd.read_csv('zgpa_test.csv')
data_test.head()
price_test = data_test.loc[:, 'close']
price_test.head()# extract X_test and y_test
price_test_norm = price_test/max(price)
X_test_norm, y_test_norm = extract_data(price_test_norm, time_step)
print(X_test_norm.shape, len(y_test_norm))

拿训练好的模型,做预测,并画图做对比,比较预测值和真实值:

# make prediction based on the test data
y_test_predict = model.predict(X_test_norm)*max(price)
y_test = [i*max(price) for i in y_test_norm]fig3 = plt.figure(figsize=(8, 5))
plt.plot(y_test, label='real price_test')
plt.plot(y_test_predict, label='predict price_test')
plt.title('close_price')  # 归一化之前的数据
plt.xlabel('time')
plt.ylabel('price')
plt.legend() # 展示图例
plt.show()

把预测的数据存储起来:

# 存储数据
result_y_test = np.array(y_test).reshape(-1, 1) # 若干行,1列
result_y_test_predict = y_test_predict
print(result_y_test.shape, result_y_test_predict.shape)
result = np.concatenate((result_y_test, result_y_test_predict), axis=1)
print(result.shape)
result = pd.DataFrame(result, columns=['real_price_test', 'predict_price_test'])
result.to_csv('zgpa_predict_test.csv')

--------------------------------------------------------------------------------------------------------------------------------

1.8 pandas的一点知识点

(1) -1在reshape的应用 

这里提到了reshape(-1),那就讲一下其作用。reshape 中只能有一个 -1。如果有多个 -1,NumPy 无法确定数组的形状。当使用 -1 作为 reshape() 参数中的某个维度时,NumPy 会根据数组的总元素数量和指定的其他维度,自动计算 -1 所在维度的大小。举几个例子:

单独一个-1,将数组展平为一维数组。不论原数组的形状是什么,reshape(-1) 会将其拉平成一个一维向量。

arr = np.array([[1, 2, 3], [4, 5, 6]])
arr_reshaped = arr.reshape(-1)
print(arr_reshaped)[1 2 3 4 5 6]

下面将数组转换为二维数组,其中有多行(具体行数由原数组长度决定),每行只有 1 列。-1 表示行数由系统自动计算,而 1 则指定了列数为 1。 

arr = np.array([1, 2, 3, 4, 5, 6])
arr_reshaped = arr.reshape(-1, 1)
print(arr_reshaped)[[1][2][3][4][5][6]]

reshape(3, -1) 告诉 NumPy 重新将数组的形状调整为 3 行,而列数(-1)则由 NumPy 自动计算为 4,以确保元素总数(3x4=12)不变。 

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])arr_reshaped = arr.reshape(3, -1)
print(arr_reshaped)[[ 1  2  3  4][ 5  6  7  8][ 9 10 11 12]]
(2) numpy中concatenate的应用 

把两个长度为n的一维array合并成一个二维shape为(n,2)的array,可以用以下两个方法:

1. 先把一维array用方法reshape(-1,1),转化成[[1][2][3][4][5][6]],这种格式,然后指定axis=1,在里面那层进行合并。

# 将一维数组转换为二维数组,每个数组为一列
# a = np.array([1,2,3,4,5])a1 = a.reshape(-1, 1)
b1 = b.reshape(-1, 1)# 按列方向(axis=1)合并成一个二维数组
result = np.concatenate((a1, b1), axis=1)

2. 或者直接使用np.column_stack()。 

result2 = np.column_stack((a,b))

1.9 总结

这个股票预测rnn模型的局限性:预测结果比实际结果趋势变化较慢。

 如上图所示,实际数据已经开始上升了,而预测的数据还在下降,并在下一个时间点上才开始上升。

2. LSTM:预测序列文字

任务:基于 flare 文本数据,建立 LSTM 模型,预测序列文字

1.完成数据预处理,将文字序列数据转化为可用于LSTM输入的数据

2.查看文字数据预处理后的数据结构,并进行数据分离操作

3.针对字符串输入(" flare is a teacher in ai industry. He obtained his phd in Australia."),预测其对应的后续字符

备注:模型结构:单层LSTM,输出有20个神经元:每次使用前20个字符预测第21个字符

2.1 数据预处理

加载文本数据,把换行符和制表符替换成空格。

# load the data
data = open('flare').read()
data = data.replace('\n','').replace('\r', '') # 替换换行符
print(data)

用set函数对字符数据进行处理,得到去重后的字符。

# 字符去重处理
letters = list(set(data))
print(letters)
num_letters = len(letters)
print(num_letters)           # 进行独热数值编码,23行1列的数组#['A', 'o', 'c', 'h', 'l', 'm', 'p', '.', 's', 'S', ' ', 't', 'n', 'H', 'e', 'b', 'd', 'a', 'u', 'f', 'y', 'r', 'i']
23

利用for循环加上enumerate函数配合得到由序号、字符组成的字典。

# 建立字典
# int to char
int_to_char = {a:b for a,b in enumerate(letters)}
print(int_to_char)
# char to int
char_to_int = {b:a for a,b in enumerate(letters)}
print(char_to_int){0: 'A', 1: 'o', 2: 'c', 3: 'h', 4: 'l', 5: 'm', 6: 'p', 7: '.', 8: 's', 9: 'S', 10: ' ', 11: 't', 12: 'n', 13: 'H', 14: 'e', 15: 'b', 16: 'd', 17: 'a', 18: 'u', 19: 'f', 20: 'y', 21: 'r', 22: 'i'}
{'A': 0, 'o': 1, 'c': 2, 'h': 3, 'l': 4, 'm': 5, 'p': 6, '.': 7, 's': 8, 'S': 9, ' ': 10, 't': 11, 'n': 12, 'H': 13, 'e': 14, 'b': 15, 'd': 16, 'a': 17, 'u': 18, 'f': 19, 'y': 20, 'r': 21, 'i': 22}

设置time_step = 20,即用连续的20个字符预测第21个字符。

2.1.1 构建数据处理函数

然后构建能得到训练数据X、y的函数。

# time_step
time_step = 20# 数据预处理
import numpy as np
from tensorflow.keras.utils import to_categorical # 库发生了迁移# 滑动窗口提取数据
def extract_data(data, slide):x = []y = []for i in range(len(data) - slide):x.append([a for a in data[i : i + slide]])y.append(data[i+slide])return x,y# 字符到数字的批量转化
def char_to_int_Data(x, y, chat_to_int):x_to_int = []y_to_int = []for i in range(len(x)):x_to_int.append([char_to_int[char] for char in x[i]])y_to_int.append([char_to_int[char] for char in y[i]])  return x_to_int, y_to_int# 实现输入字符文章的批量处理,输入整个字符,滑动窗口大小,转化字典
def data_preprocessing(data, slide, num_letters, char_to_int):char_Data = extract_data(data, slide)  int_Data = char_to_int_Data(char_Data[0], char_Data[1], char_to_int)  Input = int_Data[0]Output = list(np.array(int_Data[1]).flatten())Input_RESHAPED = np.array(Input).reshape(len(Input), slide)new = np.random.randint(0, 10, size=[Input_RESHAPED.shape[0], Input_RESHAPED.shape[1], num_letters])  for i in range(Input_RESHAPED.shape[0]):for j in range(Input_RESHAPED.shape[1]):new[i, j, :] = to_categorical(Input_RESHAPED[i, j], num_classes = num_letters)  return new, Output

这里的函数比较复杂,最终data_preprocessing函数嵌套了之前构建的函数,最后要求传入文本数据,time_step(用多少个字符预测下一个), num_letters(文本数据中不重复字符个数), char_to_int(文本-序号字典)。

2.1.2 One-hot 编码

这里从tensorflow.keras.utils 模块中导入 to_categorical 函数。to_categorical 是一个工具函数,主要用于将整数编码的类别标签转换为 One-hot 编码 格式。

One-hot 编码是一种常用的编码方式,主要用于将类别数据转换为数值数据,使其可以用于机器学习或深度学习模型中。它的核心思想是使用一个向量表示每一个类别,其中只有一个位置是 1,其余位置是 0。这个唯一的 1 表示该类别的位置。

假设我们有 4 个类别:苹果香蕉橘子葡萄。我们可以为这 4 个类别进行 One-hot 编码:

类别One-hot 编码
苹果[1, 0, 0, 0]
香蕉[0, 1, 0, 0]
橘子[0, 0, 1, 0]
葡萄[0, 0, 0, 1]

--------------------------------------------------------------------------------------------------------------------------------

2.1.3 得到训练集、测试集

下面传入相应的参数,得到转化成数字的数据X,y。

X、y都只能是数字,其中X转化成了One-hot 编码,y转化成了字符-数字字典里字符对应的数字。

# extract X and y from text data
X, y = data_preprocessing(data, time_step, num_letters, char_to_int) # X 已经被独热编码,y 稍后处理

试着了解下得到的数据是什么样的。

print(X)       # 独热格式
print(X.shape) # 23 个映射[[[0 0 0 ... 0 0 0][0 0 0 ... 0 0 0][0 0 0 ... 0 0 0]...[0 0 0 ... 0 1 0][0 0 0 ... 0 0 0][0 0 0 ... 0 0 1]][[0 0 0 ... 0 0 0][0 0 0 ... 0 0 0][0 0 0 ... 0 1 0]...(44962, 20, 23)print(len(y))44962

首先看shape,这个文本有44962+20个字符,得到44962个组,后面对应的y是一个有44962个元素的列表,和X相对应。后面的(20,23)表示用20个字符来预测下一个字符,这20个字符每一个字符都是用的One-hot 编码来表示的。

大概是这个意思:X[0]得到的20*23二维矩阵,根据One-hot 编码中23个字符对应的位置,得到对应的字符,再用20个字符预测得到y[0],即y的第一个数字,对应的字符。(图里的字符只是举个例子。)

把刚才处理得到的44962组转化成数字类型数据,根据0.1的比例,分90%的数据给训练集,10%的数据给测试集。

# split the data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=10)
print(X_train.shape, len(y_train))  (40465, 20, 23) 40465

把刚才的y也转化成One-hot 编码。

y_train_category = to_categorical(y_train, num_letters)
print(y_train_category)

tip:刚才rnn也分了训练集和测试集,只不过lstm这个项目用一个文件按比例(9:1)拆成训练集和测试集,而rnn模型则是分别用两个文件当成训练集和测试集。 

2.2 构造模型 

和之前构建rnn模型类似,相似的内容不再赘述。

# set up the model
from keras.models import Sequential
from keras.layers import Dense, LSTMmodel = Sequential()
model.add(LSTM(units=20, input_shape=(X_train.shape[1], X_train.shape[2]), activation='relu'))
model.add(Dense(units=num_letters, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()

这里指定的损失函数为categorical_crossentropy,这是多分类任务中常用的损失函数,用于 One-hot 编码格式的标签。 

metrics指定评估指标,评估指标用于在训练和评估时衡量模型的表现。accuracy准确率是最常用的分类评估指标之一,表示模型预测正确的样本占总样本的比例。在训练和验证过程中,模型会输出 accuracy 指标值,以便观察模型的分类性能。

2.3 训练模型

# train the model
model.fit(X_train, y_train_category, batch_size = 1000, epochs = 10)

模型在每次迭代时会从训练数据中随机抽取 1000 个样本进行训练,暂时先训练轮数为10。

2.4 利用模型进行预测(训练值)

# make prediction based on the training data
predict_x = model.predict(X_train)         # 笔者可能与视频使用的keras不是一个版本,故而有所更改
y_train_predict = np.argmax(predict_x, axis=1)  
print(y_train_predict)

 这里得到的predict_x是二维数组:

根据argmax函数,配合axis=1,找出第二层每个中括号中最大值的索引(从0开始)。 得到一维数组y_train_predict(40465):

 把数字数组根据之前的字典转化回字符:

# transform the int to letters
y_train_predict_char = [int_to_char[i] for i in y_train_predict]
print(y_train_predict_char)

计算下训练集的真实值和预测值的准确度: 

from sklearn.metrics import accuracy_score
accuracy_train = accuracy_score(y_train, y_train_predict)
print(accuracy_train)

2.5 测试集的预测 

方法和上面差不多,最后得到测试集的真实值和预测值的准确度。

predict_x = model.predict(X_test)         # 笔者可能与视频使用的keras不是一个版本,故而有所更改
y_test_predict = np.argmax(predict_x, axis=1)
accuracy_test = accuracy_score(y_test, y_test_predict)  
print(accuracy_test)
print(y_test_predict)
print(y_test)

2.6 用模型预测一段其他文本

拿一段另外的文本,用前二十个字符预测第21个字符,这段文本得保证里面的字符都包括在一开始得到的字符集合里。 

# 预测样例
new_letters = "flare is a teacher in ai industry. He obtained his phd in Australia."
X_new, y_new = data_preprocessing(new_letters, time_step, num_letters, char_to_int)
predict_x = model.predict(X_new)         # 笔者可能与视频使用的keras不是一个版本,故而有所更改
y_new_predict = np.argmax(predict_x, axis=1)
print(y_new_predict)# transform the int to letters
y_new_predict_char = [int_to_char[i] for i in y_new_predict]
print(y_new_predict_char)

还是像之前的操作:用数据处理函数先得到X_new三维数组,用模型预测得到二位数组predict_x,然后用argmax配合axis=1得到一维数组y_new_predict,最后把用序号-字符字典把数组转化成字符组,得到预测值。

可以配合下面代码,返回的内容使得预测可视化更加合理:

for i in range(0, X_new.shape[0]-20):print(new_letters[i:i+20], '--predict next letter is--', y_new_predict_char[i])

得到结果如下:

如图,可以看到预测的结果不是很理想。可以再次训练模型,然后重复刚才2.6的操作:

# train the model
model.fit(X_train, y_train_category, batch_size = 1000, epochs = 10)# 预测样例
new_letters = "flare is a teacher in ai industry. He obtained his phd in Australia."
X_new, y_new = data_preprocessing(new_letters, time_step, num_letters, char_to_int)
predict_x = model.predict(X_new)         # 笔者可能与视频使用的keras不是一个版本,故而有所更改
y_new_predict = np.argmax(predict_x, axis=1)
print(y_new_predict)# transform the int to letters
y_new_predict_char = [int_to_char[i] for i in y_new_predict]
print(y_new_predict_char)for i in range(0, X_new.shape[0]-20):print(new_letters[i:i+20], '--predict next letter is--', y_new_predict_char[i])

这次得到的结果就更加满意了:

 2.7 总结

总结一下rnn和lstm两个项目中,训练和预测用到的数据:

rnn:用一个文件做训练集,对模型进行训练;用另外一个文件直接拿来做预测。

lstm:将一个文件按9:1分成训练集和测试集;用另外一个文本拿来做预测。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/464076.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL超大分页怎么优化处理?limit 1000000,10 和 limit 10区别?覆盖索引、面试题

1. limit 100000,10 和 limit 10区别 LIMIT 100000, 10: 这个语句的意思是,从查询结果中跳过前100000条记录,然后返回接下来的10条记录。这通常用于分页查询中,当你需要跳过大量的记录以获取后续的记录时。例如,如果你…

规范:项目、目录、文件、样式、事件、变量、方法、url参数、注释、git提交 命名规范及考证

一、规范命名的重要性 易懂、通用、规范、标准、专业性、是经验积累的体现 1.1、常见命名方法 序号命名方法解释1全小写2全大写3驼峰:小驼峰命名法4驼峰:大驼峰命名法5烤串命名法 / 脊柱命名法6下划线分隔法 二、项目名 采用小写字母和中划线&#…

NumPy Ndarray学习

1.NumPy Ndarray 对象简介 NumPy 最重要的特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。 2.N…

二:MySQL基础---查询专项练习

目录 表结构 1. 数据月表(zbr_data_monthly_data_YYYYMM) 2. 分类表(zbr_category) 3. 用户表(zbr_user) 4. 交易表(zbr_transaction) 查询知识点 1. 基本查询 2. 连接查询 …

C++线程异步

本文内容来自: 智谱清言 《深入应用C11 代码优化与工程级应用》 std::future std::future作为异步结果的传输通道,可以很方便地获取线程函数的返回值。 std::future_status Ready (std::future_status::ready): 当与 std::future 对象关联的异步操作…

Python小游戏19——滑雪小游戏

运行效果 python代码 import pygame import random # 初始化Pygame pygame.init() # 设置屏幕尺寸 screen_width 800 screen_height 600 screen pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("滑雪小游戏") # 定义颜色 WH…

批量删除redis数据【亲测可用】

文章目录 引言I redis客户端基础操作key的命名规则批量查询keyII 批量删除key使用连接工具进行分组shell脚本示例其他方法III 知识扩展:控制短信验证码获取频率引言 批量删除redis数据的应用: 例如缓存数据使用了新的key存储,需要删除废弃的key。RedisTemplate的key序列化采…

04字符串算法/代码随想录

四、字符串 反转字符串 力扣344 遇到数组双指针真是太好用了&#xff0c;左右指针不断逼近即可&#xff0c;代码也很简单 class Solution {public void reverseString(char[] s) {int fast s.length - 1;int slow 0;while (slow < fast) {char temp s[fast];s[fast] s[…

conda找不到对应版本的pytorch,就会自动下载cpu版本的

踩坑一&#xff1a; conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.7 -c pytorch -c nvidia (本人的服务器支持的 且python3.8.20) 先nvidia-smi查看自己cuda支持的最高版本&#xff0c;然后去pytorch官网寻找对应的torch、torchaudio、to…

信息学科平台设计与实现:Spring Boot技术详解

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

二、应用层,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》

文章目录 零、前言一、应用层协议原理1.1 网络应用的体系结构1.1.1 客户-服务器(C/S)体系结构1.1.2 对等体&#xff08;P2P&#xff09;体系结构1.1.3 C/S 和 P2P体系结构的混合体 1.2 进程通信1.2.1 问题1&#xff1a;对进程进行编址&#xff08;addressing&#xff09;&#…

Java面向对象 C语言字符串常量

1. &#xff08;1&#xff09;. package liujiawei;public class Phone {String brand;double price;public void call(){System.out.println("手机打电话");}public void play(){System.out.println("手机打游戏");} } public class phonetest {public…

【逆向基础】十八、PE文件格式(三)

一、简介 文本章主要讲结构体IMAGE_DATA_DIRECTORY数组。它制定了各种数据目录的地址与大&#xff1b;PE装载器可以通过这些信息准确加载PE文件所需的函数&#xff0c;资源等&#xff1b;此外&#xff0c;数据目录表也是设置钩子&#xff0c;注入等逆向的理论基础。所以学习这…

Session条件竞争--理论

条件竞争 多个线程同时访问一个共享变量或文件时&#xff0c;由于线程的执行顺序不符合预期而导致最后的执行结果不符合开发者的预期。 session session,被称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样&#xff0c;当用户在应用程序的Web页之间…

Centos8安装软件失败更换镜像源

问题 在Centos 8上安装git&#xff0c;报错如下&#xff1a; sudo dnf install git -y Repository extras is listed more than once in the configuration CentOS Linux 8 - AppStream 0.0 B/s …

如何让网页中的图片不可下载,让文字不可选中/复制

使用css中的伪属性来完成这个操作. 效果展示 文字不可复制: 图中这几个中文字符无法被选中,双击前面这几个字也只能选中后面的英文内容,无法选中也就无法复制. 既然常规方式无法选中,那打开浏览器开发者工具总能复制吧! 我经常这样干, 但是很遗憾,页面检查中根本就没那些内容…

Linux 之 信号概念、进程、进程间通信、线程、线程同步

学习任务&#xff1a; 1、 信号&#xff1a;信号的分类、进程对信号的处理、向进程发送信号、信号掩码 2、 进程&#xff1a;进程与程序的概念、进程的内存布局、进程的虚拟地址空间、fork创建子进程、wait监视子进程 3、 学习进程间通信&#xff08;管道和FIFO、信号、消息队列…

Jmeter——结合Allure展示测试报告

在平时用jmeter做测试时&#xff0c;生成报告的模板&#xff0c;不是特别好。大家应该也知道allure报告&#xff0c;页面美观。 先来看效果图&#xff0c;报告首页&#xff0c;如下所示&#xff1a; 报告详情信息&#xff0c;如下所示&#xff1a; 运行run.py文件&#xff0c;…

ElasticSearch - Bucket Script 使用指南

文章目录 官方文档Bucket Script 官文1. 什么是 ElasticSearch 中的 Bucket Script&#xff1f;2. 适用场景3. Bucket Script 的基本结构4. 关键参数详解5. 示例官方示例&#xff1a;计算每月 T 恤销售额占总销售额的比率百分比示例计算&#xff1a;点击率 (CTR) 6. 注意事项与…

java、excel表格合并、指定单元格查找、合并文件夹

#创作灵感# 公司需求 记录工作内容 后端&#xff1a;JAVA、Solon、easyExcel、FastJson2 前端&#xff1a;vue2.js、js、HTML 模式1&#xff1a;合并文件夹 * 现有很多文件夹 想合并全部全部的文件夹的文件到一个文件夹内 * 每个部门发布的表格 合并全部的表格为方便操作 模…