时间序列预测(六)——循环神经网络(RNN)

目录

一、RNN的基本原理

1、正向传播(Forward Pass):

2、计算损失(Loss Calculation)

3、反向传播——反向传播通过时间(Backpropagation Through Time,BPTT)

4、梯度更新:

二、RNN的常用结构

 1、N——N结构

2、N——1结构

3、1——N结构

4、N——M结构(Encoder-Decoder,也称Seq2Seq)

三、RNN的优缺点

四、在Python中的代码解释

1、模型定义

(1)类定义:RNNModel

(2)实例化模型

2、参数形状转化(注意)

五、梯度消失与梯度爆炸

六、RNN的改进模型

七、具体代码实现

1、选择道路曲率、车速和历史方向盘转角(这里取了五个时刻的历史方向盘转角)这三个(7个)作为特征,采用RNN训练

2、使用更长的序列来捕捉历史信息,而不需要手动构造历史特征

1、绘制平均值

​2、绘制第一个未来时间步的对比


往期文章:

时间序列预测(一)——线性回归(linear regression)-CSDN博客

时间序列预测(二)——前馈神经网络(Feedforward Neural Network, FNN)-CSDN博客

前面有提到前馈神经网络,下图是两者的区别对比

特性前馈神经网络(FNN)循环神经网络(RNN)
结构无循环连接,数据单向流动有循环连接,数据可流过多个时间步
适用任务静态任务,无时间依赖动态任务,包含时间依赖
记忆能力无法记忆前一时刻信息通过隐藏状态记忆前一时刻信息
梯度计算反向传播(BP)反向传播通过时间(BPTT)
常见问题无梯度消失或爆炸问题易出现梯度消失或爆炸问题
适用场景图像分类、静态预测时间序列预测、文本生成、语音识别

循环神经网络(Recurrent Neural Network,RNN)是一种专门用于处理序列数据的神经网络结构,它能够处理时间序列数据,并预测未来的数据变化趋势。RNN能够处理序列中的时间依赖性,因而非常适合时间序列预测。以下是对RNN在时间序列预测中的详细分析:

一、RNN的基本原理

RNN的基本原理是在神经网络中引入时间的概念,使得网络可以处理序列数据。RNN的基本结构是一个循环单元,它包含一个输入层、一个隐藏层和一个输出层。在每一个时间步上,网络接收一个输入向量和一个隐藏状态向量,通过一个非线性函数对它们进行组合,然后产生一个输出向量和一个新的隐藏状态向量,作为下一个时间步的输入和隐藏状态。这种反馈机制可以使得网络记忆之前的信息,并在处理序列数据时考虑到历史信息。​

1、正向传播(Forward Pass)
  • 输入层

    • RNN的输入是一个序列,表示为 X=[x1,x2,…,xT],其中 T 是序列长度,xt 表示在时间 t 的输入值。
  • 隐藏层:

    • RNN 的特殊之处在于隐藏层具有循环连接,使得每个时刻的隐藏层状态都能从前一时刻的状态(隐状态)中获得信息。具体来说,RNN 会在每个时间步更新隐藏状态 ht:
  • 输出层

RNN 的输出 yt依赖于当前隐藏状态 ht:

2、计算损失(Loss Calculation)

选择合适的损失函数,计算每个时间步 ttt 的损失值 Lt,将所有时间步上的损失求和,得到整个序列的总损失 L:

3、反向传播——反向传播通过时间(Backpropagation Through Time,BPTT)

在计算总损失后,通过BPTT算法沿时间维度反向传播误差,计算每个时间步上的梯度。

因为隐藏状态在每个时间步都传递到下一个时间步,所以需要在时间上展开 RNN,形成一个“展开的计算图”,并在这个图上逐步反向传播。对于每个时间步的参数(如 Wh和 Wx),需要计算梯度:

(注意:由于隐藏状态 hth_tht​ 依赖于所有之前的状态,所以当前时间步的梯度受多个时间步的误差影响。)

4、梯度更新

计算出参数的梯度后,通常使用优化器(如 SGD、Adam 等)来更新模型参数。随着每个时间步梯度的反向传播,BPTT算法会依次更新所有权重,以最小化损失。

为了减小计算量,提出了截断 BPTT,它 是一种优化的 BPTT 方法,通过限制反向传播的时间步数来减少计算量。它按固定长度(如 10 或 20 步)的窗口,将长序列分成若干个较短的子序列,每个子序列独立进行正向和反向传播。在每个子序列结束时,重置梯度,但隐藏状态在各子序列间保持连续,以保留长程依赖信息。

最后,需要注意在PyTorch中,RNN的输入数据通常是一个形状为(batch_size, sequence_length, input_size)的张量,输出数据通常是一个二维张量,其形状为(batch_size, output_size)或是三维张量(batch_size, sequence_length, output_size)(对于序列输出)。

其中,

  • batch_size:表示批次中样本的数量。
  • sequence_length:表示序列的长度。
  • input_size和output_size:表示每个时间步骤的输入和输出的特征数量

所以要将数据进行转化。这里是与FNN是不一样的,多了一个序列长度,所以RNN 可以一次性输入和输出多个时间步的特征和目标,RNN 才是真正可以处理序列数据的,而 FNN 处理的是单个独立样本。

因此,当 sequence_length=1 时,RNN 变得和 FNN 类似,但仍保持了 RNN 的结构。在这种情况下,使用 RNN 可能会显得有些多余,因为 FNN 可以实现相同的功能,而不需要引入 RNN 的复杂性。

二、RNN的常用结构

 1、N——N结构

输入与输出:输入是x1,x2,.....xn,输出为y1,y2,...yn。输入和输出序列是等长的。

应用场景:由于这种结构的输入输出长度一致,因此它适用于生成等长度的序列,如合辙的诗句等。此外,它还可用于计算视频中每一帧的分类标签,因为要对每一帧进行计算,所以输入和输出序列等长。

  

2、N——1结构

输入与输出:输入是一个序列,而输出是一个单独的值,不是序列。

处理方式:这种结构通常在最后一个隐层输出h上进行线性变换,以得到所需的输出值。为了更明确地表示结果,还可以使用sigmoid或softmax函数进行处理。

应用场景:这种结构经常被应用在文本分类问题上,如输入一段文字判别它所属的类别,或输入一个句子判断其情感倾向等。  

3、1——N结构

输入与输出:输入不是序列,而输出为序列。

应用场景:这种结构可以处理从非序列数据生成序列数据的问题,如从图像生成文字(image caption)。此时,输入X是图像的特征,而输出的y序列就是一段句子,就像看图说话一样。  或是  

4、N——M结构(Encoder-Decoder,也称Seq2Seq)

输入与输出:输入和输出为不等长的序列。

结构组成:这种结构由编码器和解码器两部分组成,两者的内部结构都是某类RNN。输入数据首先通过编码器,最终输出一个隐含变量c(上下文语义向量)。之后,使用这个隐含变量c作用在解码器解码的每一步上,以保证输入信息被有效利用。

应用场景:这是RNN的一个重要变种,也是应用最广的RNN模型结构。由于其输入输出不受限制,它被广泛应用于机器翻译、阅读理解、文本摘要等众多领域。在机器翻译中,源语言和目标语言的句子往往没有相同的长度,因此N——M结构特别适用于此类任务。  或是  

局限性:编码和解码之间的唯一联系是固定长度的语义向量c。编码时,整个序列的信息需要被压缩进一个固定长度的语义向量c中,这可能导致信息丢失或覆盖。因此,对于较长的输入序列,解码效果可能会受到影响。

改进:为了弥补N——M结构的局限性,提出了注意力(Attention)机制。注意力机制通过在每个时间输入不同的c来解决问题,它允许解码器在解码时能够关注输入序列的不同部分,从而提高了解码的准确性和灵活性。 

三、RNN的优缺点

优点:RNN具有记忆功能,能够处理变长的序列数据,并捕捉到序列中的时序信息。同时,RNN的权重参数是共享的,这有助于减少模型的参数数量并提高计算效率。RNN可以根据输入和输出的不同结构进行灵活调整。

缺点:在长序列任务中,RNN容易出现梯度消失或梯度爆炸的问题,导致模型难以训练。RNN的计算效率相对较低,因为需要在每个时间步都进行前向传播和反向传播的计算。

四、在Python中的代码解释

1、模型定义
class RNNModel(nn.Module):def __init__(self, input_size, hidden_size, num_layers):super(RNNModel, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)  # 使用RNNself.fc = nn.Linear(hidden_size, 1)  # 输出层def forward(self, x):# 初始化隐藏状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# 前向传播out, _ = self.rnn(x, h0)  # RNN输出形状为 (batch_size, seq_length, hidden_size)out = self.fc(out[:, -1, :])  # 只取最后一个时间步的输出return out# 实例化模型
input_size = window_size + 2  # 输入特征维度
hidden_size = 64  # 隐藏层大小
num_layers = 2  # RNN层数
model = RNNModel(input_size, hidden_size, num_layers)
(1)类定义:RNNModel

RNNModel类继承自nn.Module,这是PyTorch中所有神经网络模块的基类。

a、初始化__init__

调用父类的__init__方法外,还定义了模型的一些关键属性:

  • input_size:输入特征的大小(维度)。
  • hidden_size:RNN隐藏层的大小(即隐藏层中神经元的数量)。
  • num_layers:RNN的层数(即堆叠的RNN单元的数量)。
  • self.rnn:这是模型中的RNN层,batch_first=True意味着输入张量的第一个维度是批次大小(batch size)。
  • self.fc:这是一个全连接层(也称为线性层),将RNN的最后一个时间步的输出映射到模型的最终输出。这里,输出层的大小被设置为1,这意味着模型将输出一个标量值。

b、前向传播forward

首先初始化隐藏状态h0。隐藏状态是一个零张量,其形状为(num_layers, batch_size, hidden_size),并且被发送到与输入x相同的设备上(CPU或GPU)。

接着,使用RNN层处理输入x和初始隐藏状态h0。RNN层的输出out是一个形状为(batch_size, seq_length, hidden_size)的张量,其中seq_length是序列的长度。

然后,只取RNN输出的最后一个时间步(out[:, -1, :]),并通过全连接层self.fc进行处理,得到模型的最终输出。

(2)实例化模型

指定输入特征维度input_size,隐藏层大小hidden_size,和RNN层数num_layers来实例化RNNModel类。用于训练、验证和测试,以处理序列数据并预测目标值。

2、参数形状转化(注意)

x_train、 x_test 、y_train 和 y_test本身是从excel表格读取的一维数组,但在PyTorch中,RNN的输入数据形状为(batch_size, sequence_length, input_size)的张量,输出数据形状为(batch_size, output_size)(batch_size, sequence_length, output_size)(对于序列输出)。因此x_train 和 x_test 被转换为形状为 [batch_size, 1, window_size + 2] 的三维张量,而 y_train 和 y_test 被转换为形状为 [batch_size, 1] 的二维张量。

(1)数据类型转换

使用 torch.tensor() 将数据转换为 PyTorch 张量,并指定数据类型为 torch.float32。这是为了确保数据格式与 PyTorch 模型兼容。

(2)形状重塑

.view(-1, 1, window_size + 2) 和 .view(-1, 1) 是用于重塑张量的方法。

-1 在 .view() 方法中是一个特殊值,表示该维度的大小将自动计算,以确保总元素数量保持不变。

对于 x_train 和 x_test,重塑后的形状为 [batch_size, seq_len, input_size]。其中:

batch_size 是自动计算的,基于原始数据的总元素数量和后面两个维度的大小。

seq_len 是 1,表示每个样本被视为一个序列,表示每个样本只包含一个时间步的数据

input_size 是 window_size + 2,表示每个时间步的输入特征数量。

对于 y_train 和 y_test,重塑后的形状为 [batch_size, 1],其中 batch_size 是自动计算的,1表示每个样本目标值被视为一个序列,只包含一个时间步的数据。具体如下:

五、梯度消失与梯度爆炸

时间序列预测(七)——梯度消失(Vanishing Gradient)与梯度爆炸-CSDN博客

六、RNN的改进模型

为了克服RNN的缺点并提高其性能,研究人员提出了多种改进模型,其中最具代表性的是长短期记忆(LSTM)和门控循环单元(GRU)。

具体看下面这两篇文章:

后面补齐

七、具体代码实现

同之前的文章一样,根据一个包含道路曲率(Curvature)、车速(Velocity)、侧向加速度(Ay)和方向盘转角(Steering_Angle)真实的数据集,去预测未来的方向盘转角。

1、选择道路曲率、车速和历史方向盘转角(这里取了五个时刻的历史方向盘转角)这三个(7个)作为特征,采用RNN训练

(但这样其实就如上文所说的,会显得有些多余,正常应该直接输入多个时间步的特征,按下一种方法,这一个可以直接跳过)。

# RNN网络
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error as mae, r2_score
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
import numpy as np# 1. 数据预处理
# 读取数据
data = pd.read_excel('input_data_20241010160240.xlsx')  # 替换为你的数据文件路径  # 提取特征和标签
labels = data['Steering_Angle'].values
features = data[['Curvature',  'Velocity']].values  # 使用 NumPy 数组# 添加历史方向盘转角作为特征 (假设历史窗口长度为5)
window_size = 5
history_features = []
for i in range(window_size, len(data)):past_angles = labels[i - window_size:i]history_features.append(list(past_angles))
features = features[window_size:]
labels = labels[window_size:]# 合并特征
features = np.hstack((features, history_features))# 归一化
scaler_x = StandardScaler()
scaler_y = StandardScaler()
features = scaler_x.fit_transform(features)
labels = scaler_y.fit_transform(labels.reshape(-1, 1))# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.2)# 将特征转换为三维张量,形状为 [样本数, 时间序列长度, 特征数]
x_train_tensor = torch.tensor(x_train, dtype=torch.float32).view(-1, 1, window_size + 2)  # [batch_size, seq_len, input_size]
y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, 1)
x_test_tensor = torch.tensor(x_test, dtype=torch.float32).view(-1, 1, window_size + 2)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32).view(-1, 1)# 2. 创建RNN模型
class RNNModel(nn.Module):def __init__(self, input_size, hidden_size, num_layers):super(RNNModel, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)  # 使用RNNself.fc = nn.Linear(hidden_size, 1)  # 输出层def forward(self, x):# 初始化隐藏状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# 前向传播out, _ = self.rnn(x, h0)  # RNN输出形状为 (batch_size, seq_length, hidden_size)out = self.fc(out[:, -1, :])  # 只取最后一个时间步的输出return out# 实例化模型
input_size = window_size + 2  # 输入特征维度
hidden_size = 64  # 隐藏层大小
num_layers = 2  # RNN层数
model = RNNModel(input_size, hidden_size, num_layers)# 3. 设置损失函数和优化器
criterion = nn.MSELoss()  # 均方误差损失
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam优化器# 4. 训练模型
num_epochs = 1000
for epoch in range(num_epochs):model.train()# 前向传播outputs = model(x_train_tensor)loss = criterion(outputs, y_train_tensor)# 后向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 5. 预测
model.eval()
with torch.no_grad():y_pred_tensor = model(x_test_tensor)y_pred = scaler_y.inverse_transform(y_pred_tensor.numpy())  # 将预测值逆归一化
y_test = scaler_y.inverse_transform(y_test_tensor.numpy())  # 逆归一化真实值# 评估指标
r2 = r2_score(y_test, y_pred)
mae_score = mae(y_test, y_pred)
print(f"R^2 score: {r2:.4f}")
print(f"MAE: {mae_score:.4f}")# 支持中文
plt.rcParams['font.sans-serif'] = ['SimSun']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 绘制实际值和预测值的对比图
plt.figure(figsize=(10, 6))
plt.plot(range(len(y_test)), y_test, label='实际值', color='blue')
plt.plot(range(len(y_pred)), y_pred, label='预测值', color='red')
plt.xlabel('样本索引')
plt.ylabel('Steering Angle')
plt.title('实际值与预测值对比图')
plt.legend()
plt.grid(True)
plt.show()

结果;

2、使用更长的序列来捕捉历史信息,而不需要手动构造历史特征

提取前5个历史曲率、速度、方向盘转角作为输入特征,同时添加后5个未来曲率(由于车辆的预瞄距离)。目标输出则为未来5个方向盘转角。

# 1. 数据预处理
# 读取数据
data = pd.read_excel('input_data_20241010160240.xlsx')  # 替换为你的数据文件路径  # 提取特征和标签
curvature = data['Curvature'].values
velocity = data['Velocity'].values
steering = data['Steering_Angle'].values# 定义历史和未来的窗口大小
history_size = 5
future_size = 5features = []
labels = []
for i in range(history_size, len(data) - future_size):# 提取前5个历史的曲率、速度和方向盘转角history_curvature = curvature[i - history_size:i]history_velocity = velocity[i - history_size:i]history_steering = steering[i - history_size:i]# 提取后5个未来的曲率(用于预测)future_curvature = curvature[i:i + future_size]# 输入特征:历史 + 未来曲率feature = np.hstack((history_curvature, history_velocity, history_steering, future_curvature))features.append(feature)# 输出标签:未来5个方向盘转角label = steering[i:i + future_size]labels.append(label)# 转换为 NumPy 数组
features = np.array(features)
labels = np.array(labels)# 归一化
scaler_x = StandardScaler()
scaler_y = StandardScaler()features = scaler_x.fit_transform(features)
labels = scaler_y.fit_transform(labels)# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.2)# 将特征转换为三维张量,形状为 [样本数, 时间序列长度, 特征数]
input_feature_size = history_size * 3 + future_size  # 历史曲率、速度、方向盘转角 + 未来曲率
x_train_tensor = torch.tensor(x_train, dtype=torch.float32).view(-1, 1, input_feature_size)  # [batch_size, seq_len=1, input_size]
y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, future_size)  # 输出未来的5个方向盘转角
x_test_tensor = torch.tensor(x_test, dtype=torch.float32).view(-1, 1, input_feature_size)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32).view(-1, future_size)

由于现在输出的是未来5个方向盘转角,需要调整模型的输出层以匹配新的标签维度。

# 2. 创建RNN模型
class RNNModel(nn.Module):def __init__(self, input_size, hidden_size, num_layers, output_size):super(RNNModel, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)self.fc = nn.Linear(hidden_size, output_size)  # 修改输出层以输出未来5个方向盘转角def forward(self, x):# 初始化隐藏状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# 前向传播out, _ = self.rnn(x, h0)out = self.fc(out[:, -1, :])  # 只取最后一个时间步的输出return out# 实例化模型
input_size = input_feature_size  # 输入特征数
hidden_size = 64  # 隐藏层大小
num_layers = 2  # RNN层数
output_size = future_size  # 输出5个未来方向盘转角
model = RNNModel(input_size, hidden_size, num_layers, output_size)

更新损失函数来适应未来5个方向盘转角的多维输出。

# 3. 设置损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 4. 训练模型
num_epochs = 1000
for epoch in range(num_epochs):model.train()# 前向传播outputs = model(x_train_tensor)loss = criterion(outputs, y_train_tensor)# 后向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 5. 预测
model.eval()
with torch.no_grad():y_pred_tensor = model(x_test_tensor)y_pred = scaler_y.inverse_transform(y_pred_tensor.numpy())  # 将预测值逆归一化
y_test = scaler_y.inverse_transform(y_test_tensor.numpy())  # 逆归一化真实值# 评估指标
r2 = r2_score(y_test, y_pred, multioutput='uniform_average')  # 多维输出下的R^2
mae_score = mae(y_test, y_pred)
print(f"R^2 score: {r2:.4f}")
print(f"MAE: {mae_score:.4f}")# 绘制未来5个方向盘转角的预测和真实值对比
plt.figure(figsize=(10, 6))
for i in range(future_size):plt.plot(range(len(y_test)), y_test[:, i], label=f'真实值 {i+1} 步', color='blue')plt.plot(range(len(y_pred)), y_pred[:, i], label=f'预测值 {i+1} 步', color='red')
plt.xlabel('样本索引')
plt.ylabel('Steering Angle')
plt.title('未来5个方向盘转角的实际值与预测值对比图')
plt.legend()
plt.grid(True)
plt.show()

此时输出结果:

可以看到,最后的输出应该是预测的5个未来方向盘转角真实的5个未来方向盘转角之间的对比

下面用两种方法来优化图像输出:

1、绘制平均值

将每个样本的5个预测方向盘转角和真实方向盘转角的平均值绘制在一条线图中,展示总体的变化趋势。

# 计算预测和真实方向盘转角的平均值
y_pred_mean = np.mean(y_pred, axis=1)  # 每个样本的5个预测值取平均
y_test_mean = np.mean(y_test, axis=1)  # 每个样本的5个真实值取平均# 绘制平均值的实际值与预测值对比图
plt.figure(figsize=(10, 6))
plt.plot(range(len(y_test_mean)), y_test_mean, label='真实值(平均)', color='blue')
plt.plot(range(len(y_pred_mean)), y_pred_mean, label='预测值(平均)', color='red')
plt.xlabel('样本索引')
plt.ylabel('Steering Angle (平均)')
plt.title('未来5个方向盘转角的平均值对比图')
plt.legend()
plt.grid(True)
plt.show()

输出结果:

2、绘制第一个未来时间步的对比
# 绘制第1个时间步的实际值与预测值对比图
plt.figure(figsize=(10, 6))
plt.plot(range(len(y_test)), y_test[:, 0], label='真实值 (第1步)', color='blue')
plt.plot(range(len(y_pred)), y_pred[:, 0], label='预测值 (第1步)', color='red')
plt.xlabel('样本索引')
plt.ylabel('Steering Angle')
plt.title('未来第1步方向盘转角的实际值与预测值对比图')
plt.legend()
plt.grid(True)
plt.show()

输出结果

参考文献:

《动手学深度学习》 — 动手学深度学习 2.0.0 documentation (d2l.ai)

神经网络算法 - 一文搞懂RNN(循环神经网络)-CSDN博客

完全图解RNN、RNN变体、Seq2Seq、Attention机制 - 知乎 (zhihu.com)

别忘了给这篇文章点个赞哦,非常感谢。我也正处于学习的过程,如果有问题,欢迎在评论区留言讨论,一起学习!

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

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

相关文章

Flink时间语义和时间窗口

前言 在实际的流计算业务场景中,我们会发现,数据和数据的计算往往都和时间具有相关性。 举几个例子: 直播间右上角通常会显示观看直播的人数,并且这个数字每隔一段时间就会更新一次,比如10秒。电商平台的商品列表&a…

MySQL-15.DQL-分页查询

一.DQL-分页查询 -- 分页查询 -- 1. 从 起始索引0 开始查询员工数据,每页展示5条记录 select * from tb_emp limit 0,5; -- 2.查询 第1页 员工数据,每页展示5条记录 select * from tb_emp limit 0,5; -- 3.查询 第2页 员工数据,每页展示5条记…

6.计算机网络_UDP

UDP的主要特点: 无连接,发送数据之前不需要建立连接。不保证可靠交付。面向报文。应用层给UDP报文后,UDP并不会抽象为一个一个的字节,而是整个报文一起发送。没有拥塞控制。网络拥堵时,发送端并不会降低发送速率。可以…

Chromium 前端window对象c++实现定义

前端中window.document window.alert()等一些列方法和对象在c对应定义如下: 1、window对象接口定义文件window.idl third_party\blink\renderer\core\frame\window.idl // https://html.spec.whatwg.org/C/#the-window-object// FIXME: explain all uses of [Cros…

git 报错 SSL certificate problem: certificate has expired

git小乌龟 报错 SSL certificate problem: certificate has expired 场景复现: 原因: 这个错误表明你在使用Git时尝试通过HTTPS进行通信,但是SSL证书已经过期。这通常发生在使用自签名证书或证书有效期已到期的情况下。 解决方法: 1.如果是…

【思维导图】C语言—常见概念

hello,友友们,今天我们进入一个新的专栏——思维导图! 思维导图帮助我们复习知识的同时建构出一个清晰的框架,我往后会不断更新各个专栏的思维导图,关注我,一起加油! 今天我们回顾C语言中的常见…

智慧社区服务平台:基于Spring Boot的实现

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理基于web的智慧社区设计与实现的相关信息成…

意外发现!AI写作这样用,热点文章轻松超越同行90%!

做自媒体,写热点文章很重要。 热点自带流量,能很快吸引不少读者。 可很多自媒体新手很犯愁。 干货文还能勉强写出来,碰到热点文就不知咋办了。 为啥写热点文章这么难呢? 关键是得找个新颖角度切入。 要是只在网上反复复制粘贴那些…

R语言机器学习算法实战系列(九)决策树分类算法 (Decision Trees Classifier)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型模型的决策树预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性保存模…

Spring Boot技术栈的电影评论网站设计与实现

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…

基于手机模拟器开发游戏辅助的技术选择

开发基于手机模拟器的游戏辅助工具是一项复杂且具有挑战性的任务。为了帮助开发人员选择适合的技术方案并提供详尽的开发指导,我们将从以下几个方面进行分析:发展背景、技术选型、实现原理、实际案例和相关的法律与道德考量。 1. 发展背景 随着智能手机…

Android--第一个android程序

写在前边 ※安卓开发工具常用模拟器汇总Android开发者必备工具-常见Android模拟器(MuMu、夜神、蓝叠、逍遥、雷电、Genymotion...)_安卓模拟器-CSDN博客 ※一般游戏模拟器运行速度相对较快,本文选择逍遥模拟器_以下是Android Studio连接模拟器实现(先从以上博文中…

C++初阶(五)--类和对象(中)--默认成员函数

目录 一、默认成员函数(Default Member Functions) 二、构造函数( Constructor) 1.构造函数的基本概念 2.构造函数的特征 3.构造函数的使用 无参构造函数 和 带参构造函数 注意事项: 4.默认构造函数 隐式生成的…

Node-RED开源项目的modbus通信(TCP)

一、Modbus 通信协议 Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De fact…

重庆大学软件工程考研,难度如何?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 重大软件专业可谓是最好上岸的985院校!重庆大学24考研各大学院复试录取情况已出, 我们先说学硕部分: 招生人数: 重庆大学软件工程学硕近几年计划统招人数都不多&#xf…

【 截稿倒计时 | JPCS独立出版 | 检索快速稳定】第三届能源与动力工程国际学术会议(EPE 2024)

第三届能源与动力工程国际学术会议(EPE 2024) 2024 3rd International Conference on Energy and Power Engineering 2024年10月18日 线上会议 往届平均会后3个月完成见刊及EI检索,检索快速稳定~ EPE 2023 EI检索 EPE 2023 Scopus检索 …

Git_GitHub

Git_GitHub 创建远程仓库 远程仓库操作 创建远程仓库别名 基本语法 案例实操 推送本地分支到远程仓库 基本语法 案例实操 拉取代码 基本语法 案例实操 克隆远程仓库到本地 基本语法 案例实操 邀请加入团队 选择邀请合作者 填入想要合作的人 复制邀请函 接受邀…

C语言笔记(数据的存储篇)

目录 1.数据类型的详细介绍 2.整型在内存中的存储:原码、反码、补码 3.大小端字节序介绍及判断 4.浮点型的内存中的存储解析 1.数据类型的详细介绍 下述是内置类型: char // 字符数据类型 short // 短整型 int // 整型 long …

MySQL-事务Transaction详解

文章目录 事务概述事务基本概念事务四大特性(ACID)演示MySQL事务手动开启事务MySQL默认事务机制 事务的隔离级别隔离级别基本概述三种现象脏读不可重复读幻读 查看和设置隔离级别四种隔离级别及演示读未提交(read uncommitted)读提交(read committed)可重复读(repeatable read)…

sql-labs靶场第十八关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①寻找注入方法 ②爆库,查看数据库名称 ③爆表,查看security库的所有表 ④爆列,查看users表的所有列 ⑤成功获取用户名…