基于门控循环单元 GRU 实现股票单变量时间序列预测(PyTorch版)
前言
系列专栏:【深度学习:算法项目实战】✨︎
涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记忆、自然语言处理、深度强化学习、大型语言模型和迁移学习。
近来,机器学习得到了长足的发展,并引起了广泛的关注,其中语音和图像识别领域的成果最为显著。本文分析了深度学习模型——堆叠门控循环单元 Stacked GRU 在股市的表现。论文显示,虽然这种技术在自然语言处理、语音识别等其他领域取得了不错的成绩,但在金融时间序列预测上却表现不佳。事实上,金融数据的特点是噪声信号比高,这使得机器学习模型难以找到模式并预测未来价格。
本文通过对 GRU 时间序列预测模型的介绍,探讨Stacked GRU在股市科技股中的表现。本研究文章的结构如下。第一节介绍金融时间序列数据。第二节对金融时间数进行特征工程。第三节是构建模型、定义参数空间、损失函数与优化器。第四节是训练模型。第五节是评估模型与结果可视化。第六部分是预测下一个时间点的收盘价。
GRU 单变量时间序列预测
- 1. 金融时间序列数据
- 1.1 数据预处理
- 1.2 探索性分析(可视化)
- 1.2.1 股票的日收盘价
- 1.2.2 股票的日收益率
- 1.2.3 股票收益率自相关性
- 2. 时间数据特征工程(APPL)
- 2.1 构造序列数据
- 2.2 特征缩放(归一化)
- 2.3 数据集划分(TimeSeriesSplit)
- 2.4 数据集张量(TensorDataset)
- 3. 构建时间序列模型(Stacked GRU)
- 3.1 构建 GRU 模型
- 3.2 定义模型、损失函数与优化器
- 4. 模型训练与可视化
- 5. 模型评估与可视化
- 5.1 均方误差
- 5.2 反归一化
- 5.3 结果可视化
- 6. 模型预测
- 6.1 转换最新时间步收盘价的数组为张量
- 6.2 预测下一个时间点的收盘价格
1. 金融时间序列数据
金融时间序列数据是指按照时间顺序记录的各种金融指标的数值序列,这些指标包括但不限于股票价格、汇率、利率等。这些数据具有以下几个显著特点:
- 时间连续性:数据按照时间的先后顺序排列,反映了金融市场的动态变化过程。
- 噪声和不确定性:金融市场受到多种复杂因素的影响,因此数据中存在大量噪声和不确定性。
- 非线性和非平稳性:金融时间序列数据通常呈现出明显的非线性和非平稳性特征。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsfrom sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import TimeSeriesSplitimport torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
from torchinfo import summary
from tqdm import tqdm
1.1 数据预处理
pandas.to_datetime
函数将标量、数组、Series 或 DataFrame/dict-like 转换为 pandas datetime 对象。
AAPL = pd.read_csv('AAPL.csv')
print(type(AAPL['Close'].iloc[0]),type(AAPL['Date'].iloc[0]))
# Let's convert the data type of timestamp column to datatime format
AAPL['Date'] = pd.to_datetime(AAPL['Date'])
print(type(AAPL['Close'].iloc[0]),type(AAPL['Date'].iloc[0]))# Selecting subset
cond_1 = AAPL['Date'] >= '2021-04-23 00:00:00'
cond_2 = AAPL['Date'] <= '2024-04-23 00:00:00'
AAPL = AAPL[cond_1 & cond_2].set_index('Date')
print(AAPL.shape)
<class 'numpy.float64'> <class 'str'>
<class 'numpy.float64'> <class 'pandas._libs.tslibs.timestamps.Timestamp'>
(755, 6)
1.2 探索性分析(可视化)
探索性数据分析 E D A EDA EDA 是一种使用视觉技术分析数据的方法。它用于发现趋势和模式,或借助统计摘要和图形表示来检查假设。
1.2.1 股票的日收盘价
收盘价是股票在正常交易日交易的最后价格。股票的收盘价是投资者用来跟踪其长期表现的标准基准。
# plt.style.available
plt.style.use('seaborn-v0_8')
# 绘制收盘价
plt.figure(figsize=(18, 6))
plt.plot(AAPL['Adj Close'], label='AAPL')# 设置图表标题和轴标签
plt.title('Close Price with Moving Averages')
plt.xlabel('')
plt.ylabel('Price $', fontsize=18)# 显示图例
plt.legend()
plt.show()
1.2.2 股票的日收益率
股票的日收益率是反映投资者在一天内从股票投资中获得的回报比例。它通常用百分比来表示,计算公式为:日收益率 = (今日收盘价 - 前一日收盘价) / 前一日收盘价 × 100%,这里我们可是使用 .pct_change()
函数来实现。
plt.figure(figsize=(18,6))
plt.title('Daily Return History')
plt.plot(AAPL['Adj Close'].pct_change(),linestyle='--',marker='*',label='AAPL')
plt.ylabel('Daily Return', fontsize=18)
plt.legend()
plt.show()
1.2.3 股票收益率自相关性
股票收益率自相关性是描述一个股票在不同时间点的收益率如何相互关联的一个概念。具体来说,它指的是一个股票过去的收益率与其未来收益率之间的相关性。这种相关性可以是正相关(即过去的收益率上升预示着未来的收益率也可能上升),也可以是负相关(即过去的收益率上升预示着未来的收益率可能下降),或者两者之间没有显著的相关性。
AAPL['Returns'] = AAPL['Adj Close'].pct_change()# 使用pandas的autocorr函数计算自相关系数
# 注意:autocorr默认计算的是滞后1的自相关系数,要计算其他滞后的,需要循环或使用其他方法
autocorr_values = [AAPL['Returns'].autocorr(lag=i) for i in range(1, 301)] # 假设我们查看滞后1到300的自相关# 使用matplotlib绘制自相关系数
plt.figure(figsize=(18, 6))
plt.plot(range(1, 301), autocorr_values, linestyle='-.', marker='*')
plt.title('Autocorrelation of Stock Returns')
plt.xlabel('Lag')
plt.ylabel('Autocorrelation')
plt.grid(True)
plt.show()
2. 时间数据特征工程(APPL)
在时间序列分析中,时间窗口通常用于描述在训练模型时考虑的连续时间步 time steps 的数量。这个时间窗口的大小,即 window_size
,对于模型预测的准确性至关重要。
具体来说,window_size
决定了模型在做出预测时所使用的历史数据的长度。例如,如果我们想要用前60天的股票数据来预测未来7天的收盘价,那么window_size
就是60。
# 设置时间窗口大小
window_size = 60
2.1 构造序列数据
该函数需要两个参数:dataset
和 lookback
,前者是要转换成数据集的 NumPy 数组,后者是用作预测下一个时间段的输入变量的前一时间步数,默认设为 1。
# 构造序列数据函数
def create_dataset(dataset, lookback=1):"""Transform a time series into a prediction datasetArgs:dataset: A numpy array of time series, first dimension is the time stepslookback: Size of window for prediction"""X, y = [], []for i in range(len(dataset)-lookback): feature = dataset[i:(i+lookback), 0]target = dataset[i + lookback, 0]X.append(feature)y.append(target)return np.array(X), np.array(y)
2.2 特征缩放(归一化)
MinMaxScaler()
函数主要用于将特征数据按比例缩放到指定的范围。默认情况下,它将数据缩放到[0, 1]区间内,但也可以通过参数设置将数据缩放到其他范围。在机器学习中,MinMaxScaler()
函数常用于不同尺度特征数据的标准化,以提高模型的泛化能力。
# 选取AAPL['Close']作为特征, 归一化数据
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(AAPL['Close'].values.reshape(-1, 1))
# 创建数据集
X, y = create_dataset(scaled_data, lookback=window_size)
# 重塑输入数据为[samples, time steps, features]
X = np.reshape(X, (X.shape[0], X.shape[1], 1))
2.3 数据集划分(TimeSeriesSplit)
TimeSeriesSplit()
函数与传统的交叉验证方法不同,TimeSeriesSplit 特别适用于需要考虑时间顺序的数据集,因为它确保测试集中的所有数据点都在训练集数据点之后,并且可以分割多个训练集和测试集。
# 使用TimeSeriesSplit划分数据集,根据需要调整n_splits
tscv = TimeSeriesSplit(n_splits=3, test_size=90)
# 遍历所有划分进行交叉验证
for i, (train_index, test_index) in enumerate(tscv.split(X)):X_train, X_test = X[train_index], X[test_index]y_train, y_test = y[train_index], y[test_index]# print(f"Fold {i}:")# print(f" Train: index={train_index}")# print(f" Test: index={test_index}")# 查看最后一个 fold 数据帧的维度
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
(605, 60, 1) (90, 60, 1) (605,) (90,)
2.4 数据集张量(TensorDataset)
张量是一个多维数组或矩阵的数学对象,可以看作是向量和矩阵的推广。在深度学习中,张量通常用于表示输入数据、模型参数以及输出数据
# 将 NumPy数组转换为 tensor张量
X_train_tensor = torch.from_numpy(X_train).type(torch.Tensor)
X_test_tensor = torch.from_numpy(X_test).type(torch.Tensor)
y_train_tensor = torch.from_numpy(y_train).type(torch.Tensor).view(-1,1)
y_test_tensor = torch.from_numpy(y_test).type(torch.Tensor).view(-1,1)print(X_train_tensor.shape, X_test_tensor.shape, y_train_tensor.shape, y_test_tensor.shape)
view()
函数用于重塑张量对象,它等同于 NumPy 中的 reshape()
函数,允许我们重组数据,以匹配 LSTM 模型所需的输入形状。以这种方式重塑数据可确保 LSTM 模型以预期格式接收数据。
torch.Size([605, 60, 1]) torch.Size([90, 60, 1]) torch.Size([605, 1]) torch.Size([90, 1])
使用 TensorDataset
和 DataLoader
创建数据集和数据加载器
train_dataset = TensorDataset(X_train_tensor, y_train_tensor)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_dataset = TensorDataset(X_test_tensor, y_test_tensor)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
shuffle=True
表示在每个epoch开始时,数据集将被随机打乱,这有助于防止模型在训练时过拟合。与训练数据加载器类似,shuffle=False
表示在测试时不需要打乱数据集。因为测试集通常用于评估模型的性能,而不是用于训练,所以不需要打乱。
3. 构建时间序列模型(Stacked GRU)
GRU (Gated Recurrent Unit)是一种循环神经网络 R N N RNN RNN的变体,用于处理和预测序列数据。与标准RNN相比,GRU能够更有效地捕捉长期依赖关系,并且在训练时更不容易出现梯度消失或梯度爆炸的问题。
🔗 PyTorch所提供的数学公式及解释如下:
Apply a multi-layer gated recurrent unit (GRU) RNN to an input sequence. For each element in the input sequence, each layer computes the following function:
r t = σ ( W i r x t + b i r + W h r h ( t − 1 ) + b h r ) z t = σ ( W i z x t + b i z + W h z h ( t − 1 ) + b h z ) n t = tanh ( W i n x t + b i n + r t ⊙ ( W h n h ( t − 1 ) + b h n ) ) h t = ( 1 − z t ) ⊙ n t + z t ⊙ h ( t − 1 ) \begin{array}{ll} r_t = \sigma(W_{ir} x_t + b_{ir} + W_{hr} h_{(t-1)} + b_{hr}) \\ z_t = \sigma(W_{iz} x_t + b_{iz} + W_{hz} h_{(t-1)} + b_{hz}) \\ n_t = \tanh(W_{in} x_t + b_{in} + r_t \odot (W_{hn} h_{(t-1)}+ b_{hn})) \\ h_t = (1 - z_t) \odot n_t + z_t \odot h_{(t-1)} \end{array} rt=σ(Wirxt+bir+Whrh(t−1)+bhr)zt=σ(Wizxt+biz+Whzh(t−1)+bhz)nt=tanh(Winxt+bin+rt⊙(Whnh(t−1)+bhn))ht=(1−zt)⊙nt+zt⊙h(t−1)
where h t h_t ht is the hidden state at time t t t, x t x_t xt is the input at time t t t, h ( t − 1 ) h_{(t-1)} h(t−1) is the hidden state of the layer at time t − 1 t-1 t−1 or the initial hidden state at time 0 0 0, and r t r_t rt, z t z_t zt, n t n_t nt are the reset, update, and new gates, respectively. σ \sigma σ is the sigmoid function, and ⊙ \odot ⊙ is the Hadamard product.
In a multilayer GRU, the input x t ( l ) x^{(l)}_t xt(l) of the l l l -th layer ( l ≥ 2 l \ge 2 l≥2) is the hidden state h t ( l − 1 ) h^{(l-1)}_t ht(l−1) of the previous layer multiplied by dropout δ t ( l − 1 ) \delta^{(l-1)}_t δt(l−1) where each δ t ( l − 1 ) \delta^{(l-1)}_t δt(l−1) is a Bernoulli random variable which is 0 0 0 with probability d r o p o u t dropout dropout.
3.1 构建 GRU 模型
class GRUNet(nn.Module):def __init__(self, input_dim, hidden_dim, output_dim=1, num_layers=2):# input_dim 是输入特征的维度,hidden_dim 是隐藏层神经单元维度或称为隐藏状态的大小,output_dim 是输出维度,# num_layers 是网络层数,设置 num_layers=2 表示将两个 GRU 堆叠在一起形成一个堆叠 GRU,第二个 GRU 接收第一个 GRU 的输出并计算最终结果super(GRUNet, self).__init__()# 通过调用 super(GRUNet, self).__init__() 初始化父类 nn.Moduleself.hidden_dim = hidden_dimself.num_layers = num_layersself.gru = nn.GRU(input_dim, hidden_dim, num_layers, batch_first=True)# 定义 GRU 层,使用 batch_first=True 表示输入数据的形状是 [batch_size, seq_len(time_steps), input_dim]self.fc = nn.Linear(hidden_dim, output_dim)# 定义全连接层,将 GRU 的最后一个隐藏状态映射到输出维度 output_dimdef forward(self, x):h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_dim).to(x.device)# 初始化h0为全零张量,h0代表隐藏状态(hidden state)的初始值,形状为 [num_layers * num_directions, batch, hidden_dim]# 如果没有指定双向参数 bidirectional为 True,num_directions 默认为 1out, _ = self.gru(x, h0)# 将输入数据 x 和初始隐藏状态 h0 传递给 GRU层,得到输出 out(即所有时间步的输出)和最后一个时间步的隐藏状态 hn(这里用 _忽略)out = self.fc(out[:, -1, :])# GRU 的输出是一个三维张量,其形状是 [batch_size, seq_len(time_steps), hidden_dim],# 这里我们只取最后一个时间步的隐藏状态 out[:, -1, :] 并传递给全连接层。return out
3.2 定义模型、损失函数与优化器
要在 PyTorch 中构建堆叠 GRU,我们需要调用 GRUNet 类,通过输入 num_layers
的参数来实现
model = GRUNet(input_dim=1, # 输入数据的特征数量 X_train.shape[2]hidden_dim=64,output_dim=1,num_layers=2) # 表示将两个 GRU 堆叠在一起形成一个堆叠 GRU
criterion = torch.nn.MSELoss() # 定义均方误差损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 定义优化器
summary(model, (32, 60, 1)) # batch_size, seq_len(time_steps), input_dim
==========================================================================================
Layer (type:depth-idx) Output Shape Param #
==========================================================================================
GRUNet [32, 1] --
├─GRU: 1-1 [32, 60, 64] 37,824
├─Linear: 1-2 [32, 1] 65
==========================================================================================
Total params: 37,889
Trainable params: 37,889
Non-trainable params: 0
Total mult-adds (Units.MEGABYTES): 72.62
==========================================================================================
Input size (MB): 0.01
Forward/backward pass size (MB): 0.98
Params size (MB): 0.15
Estimated Total Size (MB): 1.14
==========================================================================================
4. 模型训练与可视化
train_loss = []
num_epochs = 20for epoch in range(num_epochs):model.train() # 初始化训练进程pbar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{num_epochs}")for batch_idx, (data, target) in enumerate(pbar):# 前向传播outputs = model(data) # 每个批次的预测值loss = criterion(outputs, target)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()# 记录损失值train_loss.append(loss.item())# 更新进度条pbar.update()# 这里只用于显示当前批次的损失,不是平均损失pbar.set_postfix({'Train loss': f'{loss.item():.4f}'})
这里我们使用 tqdm
模块来展示进度条
Epoch 1/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.25it/s, Train loss=0.0211]
Epoch 2/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0052]
Epoch 3/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.24it/s, Train loss=0.0030]
Epoch 4/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.06it/s, Train loss=0.0014]
Epoch 5/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.19it/s, Train loss=0.0011]
Epoch 6/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.21it/s, Train loss=0.0007]
Epoch 7/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.21it/s, Train loss=0.0015]
Epoch 8/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.22it/s, Train loss=0.0015]
Epoch 9/20: 100%|███████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.21it/s, Train loss=0.0012]
Epoch 10/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0010]
Epoch 11/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0014]
Epoch 12/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.19it/s, Train loss=0.0011]
Epoch 13/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.21it/s, Train loss=0.0013]
Epoch 14/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0013]
Epoch 15/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.03it/s, Train loss=0.0020]
Epoch 16/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.08it/s, Train loss=0.0012]
Epoch 17/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0009]
Epoch 18/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.22it/s, Train loss=0.0014]
Epoch 19/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.07it/s, Train loss=0.0019]
Epoch 20/20: 100%|██████████████████████████████████████████████████| 19/19 [00:01<00:00, 13.11it/s, Train loss=0.0013]
plt.plot(train_loss)
5. 模型评估与可视化
5.1 均方误差
model.eval() # 将模型设置为评估模式
test_loss = [] # 初始化损失
pbar = tqdm(test_loader, desc="Evaluating")
with torch.no_grad():for data, target in pbar:test_pred = model(data)loss = criterion(test_pred, target)test_loss.append(loss.item())# 计算当前批次的平均损失batch_avg_loss = sum(test_loss)/len(test_loss)pbar.set_postfix({'Test Loss': f'{batch_avg_loss:.4f}'})pbar.update() # 更新进度条pbar.close() # 关闭进度条
Evaluating: 100%|██████████████████████████████████████████████████████| 3/3 [00:00<00:00, 51.30it/s, Test Loss=0.0011]
5.2 反归一化
.inverse_transform
将经过转换或缩放的数据转换回其原始形式或接近原始形式
# 反归一化预测结果
train_pred = scaler.inverse_transform(model(X_train_tensor).detach().numpy())
y_train = scaler.inverse_transform(y_train_tensor.detach().numpy())
test_pred = scaler.inverse_transform(model(X_test_tensor).detach().numpy())
y_test = scaler.inverse_transform(y_test_tensor.detach().numpy())print(train_pred.shape, y_train.shape, test_pred.shape, y_test.shape)
(605, 1) (605, 1) (90, 1) (90, 1)
5.3 结果可视化
计算训练预测与测试预测的绘图数据
# shift train predictions for plotting
trainPredict = AAPL[window_size:X_train.shape[0]+X_train.shape[1]]
trainPredictPlot = trainPredict.assign(TrainPrediction=train_pred)testPredict = AAPL[X_train.shape[0]+X_train.shape[1]:]
testPredictPlot = testPredict.assign(TestPrediction=test_pred)
绘制模型收盘价格的原始数据与预测数据
# Visualize the data
plt.figure(figsize=(18,6))
plt.title('GRU Close Price Validation')
plt.plot(AAPL['Close'], color='blue', label='original')
plt.plot(trainPredictPlot['TrainPrediction'], color='orange',label='Train Prediction')
plt.plot(testPredictPlot['TestPrediction'], color='red', label='Test Prediction')
plt.legend()
plt.show()
6. 模型预测
6.1 转换最新时间步收盘价的数组为张量
# 假设latest_closes是一个包含最新window_size个收盘价的列表或数组
latest_closes = AAPL['Close'][-window_size:].values
latest_closes = latest_closes.reshape(-1, 1)
scaled_latest_closes = scaler.fit_transform(latest_closes)
tensor_latest_closes = torch.from_numpy(scaled_latest_closes).type(torch.Tensor).view(1, window_size, 1)
print(tensor_latest_closes.shape)
torch.Size([1, 60, 1])
6.2 预测下一个时间点的收盘价格
# 使用模型预测下一个时间点的收盘价
next_close_pred = model(tensor_latest_closes)
next_close_pred = scaler.inverse_transform(next_close_pred.detach().numpy())
next_close_pred
array([[166.83992]], dtype=float32)
相关文章:

基于门控循环单元 GRU 实现股票单变量时间序列预测(PyTorch版)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…...
Apache tika 实现各种文档内容解析
Apache tika 实现各种文档内容解析 1、依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…...
Vue3 监听属性
Vue3 监听属性 Vue.js 是一个流行的前端框架,以其响应式系统和组件化开发而闻名。在 Vue3 中,监听属性(Watchers)是一个核心功能,允许开发者监控和响应数据的变化。本文将详细介绍 Vue3 中监听属性的使用方法、场景和最佳实践。 监听属性的基本概念 在 Vue3 中,监听属…...
Transformer模型论文解读、源码分析和项目实践
本文是ChatGPT系列的开篇之作,为什么吧Transformer放到这里呢,因为不管是chatgpt-1, chatgpt-2, chatgpt-3都是以Transformer作为底层基础来实现,相当于chatgpt系列的老祖先了。如果想要深入的了解清楚chatgpt的来龙去…...
前端部署自动上传资源文件到cdn/oss 解决路由和访问慢的问题
参考文档:webpack-aliyun-oss-plugin - npm 安装依赖,这是一个预编译环境下的包 npm install webpack-aliyun-oss-plugin --save-dev 以下代码的意思是: webpack中引入一个oss上传插件,并且给予其初始参数,插件根据p…...
Diffusion 公式推导 2
Diffusion 公式推导 中对 DDPM 进行了推导,本文接着对 DDIM 进行推导。 目录 六. 模型改进 六. 模型改进 从扩散模型的推理过程不难看出,DDPM 有一个致命缺点 —— 推理速度过慢,因为逆扩散是从 x T x_{T} xT 到 x 0 x_{0} x0 的完整过…...

layui-表单(输入框)
1.基本使用方法 先写一个表单元素块 form 加上layui-form 里面写行区块结构,如下: 2.输入框样式选项 input框 placeholder默认文本 autocomplete自动填充 lay-verify required必填 3.下拉菜单样式选项 默认选择第一项 select框 disable禁…...

中职网络安全B模块渗透测试server2380
使用nmap扫描添加参数-sV Flag:2.4.38 添加参数-A不然扫不全 (这两题可以直接加-sV -A) Flag: 4.3.11-Ubuntu 根据nmap扫描发现系统为ubuntu系统,ubuntu操作系统在某些版本中默认包含一个名为"ubuntu"的用户帐户。这是为了方…...

微信小程序毕业设计-教育培训系统项目开发实战(附源码+论文)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:微信小程序毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计…...

【面试题】正向代理和反向代理的区别?
正向代理(Forward Proxy)和反向代理(Reverse Proxy)是两种常见的代理服务器类型,它们在网络通信中扮演着不同的角色,具有不同的功能和应用场景。 一、正向代理 1. 定义与位置 正向代理是位于客户端和目标…...

Python面试宝典第8题:二叉树遍历
题目 给定一棵二叉树的根节点 root ,返回它节点值的前序遍历。 示例 1: 输入:root [1,null,2,3] 输出:[1,2,3] 示例 2: 输入:root [] 输出:[] 示例 3: 输入:root […...

FastReport 指定sql 和修改 数据库连接地址的 工具类 :FastReportHelper
FastReport 指定sql 和修改 数据库连接地址的 工具类 :FastReportHelper 介绍核心代码:完整代码: 介绍 在FastReport中,经常会遇到需要给 sql 加条件的情况,或者给数据库地址做更换。 (废话不多说&#x…...

C++11中重要的新特性 Part one
序言 C11 是 C 编程语言的一个重要版本,于 2011 年由国际标准化组织 (ISO) 和国际电工委员会 (IEC) 旗下的 C 标准委员会 (ISO/IEC JTC1/SC22/WG21) 正式公布,并于同年 9 月出版。其正式名称为 ISO/IEC 14882:2011 - Information technology – Programm…...
VB 关键字
VB 关键字 Visual Basic(VB)是一种由微软开发的高级编程语言,广泛用于开发Windows桌面应用程序。在VB编程中,关键字是语言预定义的单词,具有特定的含义和用途。这些关键字不能被用作变量名或函数名,因为它们已经被编程语言赋予了特定的功能。 本文将详细介绍VB中的关键…...

Linux——多线程(四)
前言 这是之前基于阻塞队列的生产消费模型中Enqueue的代码 void Enqueue(const T &in) // 生产者用的接口{pthread_mutex_lock(&_mutex);while(IsFull())//判断队列是否已经满了{pthread_cond_wait(&_product_cond, &_mutex); //满的时候就在此情况下等待// 1.…...

InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃
InetAddress.getLocalHost().getHostAddress()阻塞导致整个微服务崩溃 import java.net.InetAddress;public class GetHostIp {public static void main(String[] args) {try {long start System.currentTimeMillis();String ipAddress InetAddress.getLocalHost().getHostA…...
在 Qt6 中,QList 和 QVector 统一 成qlist了吗?
是的,在 Qt6 中,QList 和 QVector 已经被统一了。具体来说,QList 现在基本上就是 QVector 的一个别名。这一改变意味着 QList 和 QVector 具有相同的性能和行为特性。 在 Qt5 中,QList 有自己的内部实现,对小型对象&a…...

第三期书生大模型实战营 第1关 Linux 基础知识
第三期书生大模型实战营 第1关 Linux 基础知识 第三期书生大模型实战营 第1关 Linux 基础知识InternStudio开发机创建SSH密钥配置通过本地客户端连接远程服务器通过本地VSCode连接远程服务器运行一个Python程序总结 第三期书生大模型实战营 第1关 Linux 基础知识 Hello大家好&a…...
架构设计(1)分布式架构
分布式架构 分布式架构是一种将系统中的不同组件分布在多台计算机或节点上,通过网络进行通信和协作,以实现系统功能的架构设计。分布式架构通常用于构建大型、复杂的软件系统,具有高可伸缩性、高可用性和高性能等优点。下面是关于分布式架构…...

机器学习笔记:初始化0的问题
1 前言 假设我们有这样的两个模型: 第一个是逻辑回归 第二个是神经网络 他们的损失函数都是交叉熵 sigmoid函数的导数: 他们能不能用0初始化呢? 2 逻辑回归 2.1 求偏导 2.1.1 结论 2.1.2 L对a的偏导 2.1.3 对w1,w2求偏导 w2同…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...