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.mzph.cn/news/884518.shtml

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

相关文章

jenkins 构建报错 mvn: command not found

首先安装过 maven,并且配置过环境变量 win r ,输入 cmd 键入 mvn -v 出现上图输出,则证明安装成功。 原因 jenkins 没有 maven 配置全局属性, 导致无法找到 mvn 命令。 解决方案 找到全局属性,点击新增,配置 MAVEN_HOME 路…

轮廓图【HTML+CSS+JavaScript】

给大家分享一个很好看的轮播图,这个也是之前看到别人写的效果感觉很好看,所以后面也自己实现了一下,在这里分享给大家,希望大家也可以有所收获 轮播图效果: 视频效果有点浑浊,大家凑合着看,大家…

ChatGPT变AI搜索引擎!以后还需要谷歌吗?

前言 在北京时间11月1日凌晨,正值ChatGPT两岁生日之际,OpenAI宣布推出最新的人工智能搜索体验!具备实时网络功能!与 Google 展开直接竞争。 ChatGPT搜索的推出标志着ChatGPT成功消除了即时信息这一最后的短板。 这项新功能可供 …

Linux系统性能调优

在Linux系统中,性能调优是确保系统高效运行的重要任务。优化可以涵盖多个方面,包括文件系统、内存管理、网络和进程管理等。以下是一些常用的Linux性能调优策略: 1. 系统监控工具 在开始优化之前,首先需要监控系统的性能&#x…

Netty 组件介绍 - ByteBuf

直接内存&堆内存 ByteBuf buffer ByteBufAllocator.DEFAULT.heapBuffer(10);ByteBuf byteBuf ByteBufAllocator.DEFAULT.directBuffer(10); 组成 ByteBuf维护了两个不同的索引,一个用于读取,一个用于写入。 写入 内存回收 堆内存使用的是JVM内…

都快2025年了,来看看哪个编程语言才是时下热门吧

早上好啊,大佬们,今天咱们不讲知识,今天我们来看看时下热门的编程语言都是哪些,大佬们又都是在学哪些语言呢。 最近一些朋友和我在讨论哪个编程语言是现在 最好用 最厉害 的编程语言。 有人说,Python简单好用&#xf…

【雷达信号数据集】雷达脉冲活动分段的多级学习算法【附下载链接】

摘要 无线电信号识别是电子战中的一项重要功能。电子战系统需要精确识别和定位雷达脉冲活动,以产生有效的对抗措施。尽管这些任务很重要,但基于深度学习的雷达脉冲活动识别方法在很大程度上仍未得到充分探索。虽然之前已经探索了用于雷达调制识别的深度…

vscode php Launch built-in server and debug, PHP内置服务xdebug调试,自定义启动参数配置使用示例

在vscode中,当我们安装了插件 PHP Debug(xdebug.php-debug)或者 xdebug.php-pack 后 我们通过内置默认的 php xdebug配置启动php项目后,默认情况下我们在vscode中设置断点是不会生效的,因为我们的内置php服务默认启动时…

(二 上)VB 2010 设计初步

目录 一、常用类应用 1.Console类控制台 2.窗体基本控件 二、面向对象程序设计 1.类和对象 2.对象的属性、方法、事件属 1.属性 2.方法 3.事件、事件过程 1.事件 2.事件过程 3.对象浏览器 三、.NET类库与命名空间 1.命名空间 常用命名空间 1.System命名空间 2.…

[CARLA系列--01]CARLA 0.9.15 在Windows下的安装教程(一)

Carla是一款开源的自动驾驶仿真器,它基本可以用来帮助训练自动驾驶的所有模块,包括感知系统,Localization, 规划系统等等.Carla这个产品目前已经更新到了最新的0.9.15版本,目前遇到好多人在windows系统上如何安装可编辑版的Carla遇到了好多问…

禾川HCQ1控制器程序编译报错如何解决

1、第一次打开用户程序 2、提示库未安装 3、安装库文件 4、脉冲轴库未安装 5、没有错误 去禾川自动化官网,把可以安装的包和库都安装下,程序编译就没有错误了。 6、下载相关包文件

Go语言sync.WaitGroup与errgroup.Group用法详解

errgroup.Group 和 sync.WaitGroup 的主要区别在于它们的错误处理和协程管理方式。 errgroup.Group 专为并发操作中的错误捕获设计,任意goroutine返回错误时,会立即终止其他goroutine的执行。 而 sync.WaitGroup 主要用于等待多个 goroutine 完成&…

ubuntu20安装opencv3.2记录

系统环境 ubuntu20安装了ros-noetic,所以系统默认装了opencv4.2.0,但是跑fastlivo推荐的是opencv3.2.0,而且海康相机别人写的ros驱动(海康相机ros驱动)也是需要opencv3.2.0,最终还是选择安装多版本的openc…

基于NVIDIA NIM平台实现盲人过马路的demo(一)

前言:利用NVIDIA NIM平台提供的大模型进行编辑,通过llama-3.2-90b-vision-instruct模型进行初步的图片检测 step1: 部署大模型到本地,引用所需要的库 import os import requests import base64 import cv2 import time from datetime import datetimestep2: 观看官方使用文…

MATLAB下的四个模型的IMM例程(CV、CT左转、CT右转、CA四个模型),附源代码可复制

文章目录 基于IMM算法的目标跟踪概述源代码运行结果代码结构与功能1. 初始化2. 仿真参数设置3. 模型参数设置4. 生成量测数据5. IMM算法初始化6. IMM迭代7. 绘图8. 辅助函数总结基于IMM算法的目标跟踪 概述 该MATLAB代码实现了基于交互式多模型(IMM)算法的目标跟踪,旨在估…

Redis-README官方入门文档

文章目录 Redis是什么?什么是Redis社区版?构建Redis修复依赖项或缓存构建选项的构建问题修复构建32位二进制文件的问题分配器单调时钟详细构建运行Redis运行支持TLS的Redis玩转Redis安装Redis代码贡献Redis商标Redis内部结构源代码布局server.hserver.cc…

Netty 组件介绍 - Future Promise

在异步处理时,经常用到这两个接口 netty 中的 Future 继承 jdk 中的 FutuFuture,而Promise 又对 netty Future 进行了扩展。 idk Future 只能同步等待任务结束(或成功或失败)才能得到结果netty Future 可以同步等待任务结束得到结也可以异…

cordova android 内嵌vue页面 启动页之后白屏问题处理

困扰很久的问题 一直都用splash 做延迟加载 但在 一些android机器上还是会有 这短暂的白屏其实就是vue页面尚未完全渲染的间隙 处理方案 在html中添加 <body><div id"splash-screen" style"position: fixed; top: 0; left: 0; width: 100%; height: 1…

ai数字人分身123口播克隆数字人小程序源码_博纳软云

功能配置 一、用户 用户管理小黑屋用户反馈登录设置短信参数 二、作品 视频作品背景音乐库背景音乐分类 三、形象分身 上传记录视频要求参数配置 四、声音克隆 克隆记录参数配置声音要求文案示例 五、AI文案 生成记录创作模型模型分类Al配置 六、充值 充值订单积分套…

Elasticsearch Interval 查询:为什么它们是真正的位置查询,以及如何从 Span 转换

作者&#xff1a;来自 Elastic Mayya Sharipova 解释 span 查询如何成为真正的位置查询以及如何从 span 查询过渡到它们。 长期以来&#xff0c;Span 查询一直是有序和邻近搜索的工具。这些查询对于特定领域&#xff08;例如法律或专利搜索&#xff09;尤其有用。但相对较新的 …