时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)
目录
引言
LSTM的预测效果图
LSTM机制
了解LSTM的结构
忘记门
输入门
输出门
LSTM的变体
只有忘记门的LSTM单元
独立循环(IndRNN)单元
双向RNN结构(LSTM)
运行代码
代码讲解
引言
LSTM(Long Short-Term Memory)是一种常用的循环神经网络(RNN)模型,用于处理序列数据,具有记忆长短期的能力。在时间序列预测中,LSTM既可以多元预测机制又可以作为单元预测机制使用。
作为多元预测机制,LSTM可以处理多个相关变量的历史数据,从而可以预测这些变量的未来值。具体地,我们可以将多个变量的历史数据作为LSTM的输入,将多个变量的未来值作为LSTM的输出。在训练过程中,我们可以使用误差反向传播算法来更新LSTM的参数,从而优化模型的预测性能。
作为单元预测机制,LSTM可以预测单一变量的未来值,例如股票价格、销售量等。在单元时间序列预测中,我们需要对历史数据进行分析,确定趋势、季节性和周期性等因素,并使用这些因素来预测未来的值。LSTM可以通过学习历史数据中的模式和规律,来预测未来的值。
LSTM作为多元预测机制和单元预测机制的优点是可以处理序列数据中的长期依赖关系,从而可以捕捉到数据中的复杂模式和规律。它可以自适应地学习和调整模型参数,从而提高模型的预测性能和泛化能力。
总的来说,LSTM作为多元预测机制和单元预测机制的应用广泛,可以用于预测股票价格、气象数据、交通流量等多个领域的数据。
(文末有复制粘贴即可运行的代码)
LSTM的预测效果图
这里先给大家展示一下LSTM的预测效果图(这里的预测指的是预测未知的数据并不是在测试集或者验证集上的预测),其中MAE误差为0.15,ME误差为-0.03。
其误差损失图为,其为MAE的误差图
LSTM机制
LSTM(长短期记忆,Long Short-Term Memory)是一种用于处理序列数据的深度学习模型,属于循环神经网络(RNN)的一种变体,其使用一种类似于搭桥术结构的RNN单元。相对于普通的RNN,LSTM引入了门控机制,能够更有效地处理长期依赖和短期记忆问题,是RNN网络中最常使用的Cell之一。
了解LSTM的结构
LSTM通过刻意的设计来实现学习序列关系的同时,又能够避免长期依赖的问题。它的结构示意图如下所示。
在LSTM的结构示意图中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。其中“+”号代表着运算操作(如矢量的和),而矩形代表着学习到的神经网络层。汇合在一起的线表示向量的连接,分叉的线表示内容被复制,然后分发到不同的位置。
如果上面的LSTM结构图你看着很难理解,但是其实LSTM的本质就是一个带有tanh激活函数的简单RNN,如下图所示。
LSTM这种结构的原理是引入一个称为细胞状态的连接。这个状态细胞用来存放想要的记忆的东西(对应简单LSTM结构中的h,只不过这里面不再只保存上一次状态了,而是通过网络学习存放那些有用的状态),同时在加入三个门,分别是。
忘记门:决定什么时候将以前的状态忘记。
输入门:决定什么时候将新的状态加进来。
输出门:决定什么时候需要把状态和输入放在一起输出。
从字面上可以看出,由于三个门的操作,LSTM在状态的更新和状态是否要作为输入,全部交给了神经网络的训练机制来选择。
下面分别来介绍一下三个门的结构和作用。
忘记门
下图所示为忘记门的操作,忘记门决定模型会从细胞状态中丢弃什么信息。
忘记门会读取前一序列模型的输出和当前模型的输入
来控制细胞状态中的每个数是否保留。
例如:在一个语言模型的例子中,假设细胞状态会包含当前主语的性别,于是根据这个状态便可以选择正确的代词。当我们看到新的主语时,应该把新的主语在记忆中更新。忘记们的功能就是先去记忆中找到一千那个旧的主语(并没有真正执行忘记的操作,只是找到而已。
在上图的LSTM的忘记门中,代表忘记门的输出, α代表激活函数,
代表忘记门的权重,
代表当前模型的输入,
代表前一个序列模型的输出,
代表忘记门的偏置。
输入门
输入门可以分为两部分功能,一部分是找到那些需要更新的细胞状态。另一部分是把需要更新的信息更新到细胞状态里
在上面输入门的结构中,代表要更新的细胞状态,α代表激活函数,
代表当前模型的输入,
代表前一个序列模型的输出,
代表计算
的权重,
代表计算
的偏置,
代表使用tanh所创建的新细胞状态,
代表计算
的权重,
代表计算
的偏置。
忘记门找到了需要忘掉的信息后,在将它与旧状态相乘,丢弃确定需要丢弃的信息。(如果需要丢弃对应位置权重设置为0),然后,将结果加上
*
使细胞状态获得新的信息。这样就完成了细胞状态的更新,如下图输入门的更新图所示。
再上图LSTM输入门的更新图中,代表忘记门的输出结果,
代表忘记门的输出结果,
代表前一个序列模型的细胞状态,
代表要更新的细胞状态,
代表使用tanh所创建的新细胞状态。
输出门
如下图LSTM的输出门结构图所示,在输出门中,通过一个激活函数层(实际使用的是Sigmoid激活函数)来确定哪个部分的信息将输出,接着把细胞状态通过tanh进行处理(得到一个在-1~1的值),并将它和Sigmoid门的输出相乘,得出最终想要输出的那个部分,例如,在语言模型中,假设已经输入了一个代词,便会计算出需要输出一个与该代词相关的信息(词向量)
在LSTM的输出门结构图中,代表要输出的信息,α代表激活函数,
代表计算
的权重,
代表计算
的偏置,
代表更新后的细胞状态,
代表当前序列模型的输出结果。
LSTM的变体
只有忘记门的LSTM单元
只有忘记门的JANET)单元也是LSTM单元的一个变种,发布于2018年。该单元结构源于一个大胆的猜测——当LSTM只有忘记门时会如何?
实验表明,只有忘记门的网络性能居然优于标准LSTM单元。同样,该优化方式也可以被用于其他RNN结构。
如果大家想了解更多LSTM的变体,可以查看一下其他相关资料例如该论文。
独立循环(IndRNN)单元
独立循环单元是一种新型的循环神经网络结构单元结构,发布于2018年其效果和速度均优于LSTM的单元。
IndRNN单元不但可以有效解决传统RNN模型存在的梯度爆炸和梯度小时问题,而且能够更好地学习样本中的长期依赖关系。
在搭建模型时:
可以用堆叠、残差、全连接的方式使用IndRNN单元,搭建更深的网络结构;
将IndRNN单元配合ReLU等非饱和激活函数一起使用,会使模型表现出更好的鲁棒性
双向RNN结构(LSTM)
双向RNN又称Bi-RNN,是采用两个方向的RNN模型
RNN模型擅长的是对连续数据的处理,既然是连续的数据,那么模型不但可以学习它的正向特征,而且可以学习它的反向特征,这种将正向和反向结合的结构,会比单向的循环网络有更高的拟合度。
双向RNN的处理过程就是在正向传播的基础上再进行一次反向传播。正向传播和反向传播都连接着一个输出层。这个结构提供给输出层输入序列中每一个点的完整的过去和未来的上下文信息。如图所示是一个沿着事件展开的双向循环神经网络(我们用LSTM举例实际可以是其他任何一个RNN结构)
双向RNN会比单项RNN多一个隐藏层,6个独特的权值在每一个时步被重复利用,6个权值分别对应:输入到向前和向后隐含层,隐含层到隐含层自身,向前和向后隐含层到输出层。
有关双向RNN(LSTM)我会在后续文章中讲到,这里只是大致介绍一下。
(在大多数应用中,基于时间序列的分析和有关NLP中自动回答类的一些问题中,一般是以双向LSTM配合单向LSTM或RNN横向扩展来实现,效果非常好)
运行代码
下面的代码大家可以赋值到一个py文件中输入自己的文件预测文件即可运行,这只是一个简单LSTM模型搭建,其可以搭配许多其他模块进行组合例如:注意力机制(TPA)、其他的网络结构(GRU)、双向的RNN结构等。
import time
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from matplotlib import pyplot as plt
from sklearn.preprocessing import MinMaxScalernp.random.seed(0)def calculate_mae(y_true, y_pred):# 平均绝对误差mae = np.mean(np.abs(y_true - y_pred))return maetrue_data = pd.read_csv('ETTh1-Test.csv') # 填你自己的数据地址target = 'OT'# 这里加一些数据的预处理, 最后需要的格式是pd.seriestrue_data = np.array(true_data['OT'])# 定义窗口大小
test_data_size = 32
# 训练集和测试集的尺寸划分
test_size = 0.15
train_size = 0.85
# 标准化处理
scaler_train = MinMaxScaler(feature_range=(0, 1))
scaler_test = MinMaxScaler(feature_range=(0, 1))
train_data = true_data[:int(train_size * len(true_data))]
test_data = true_data[-int(test_size * len(true_data)):]
print("训练集尺寸:", len(train_data))
print("测试集尺寸:", len(test_data))
train_data_normalized = scaler_train.fit_transform(train_data.reshape(-1, 1))
test_data_normalized = scaler_test.fit_transform(test_data.reshape(-1, 1))
# 转化为深度学习模型需要的类型Tensor
train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1)
test_data_normalized = torch.FloatTensor(test_data_normalized).view(-1)def create_inout_sequences(input_data, tw, pre_len):inout_seq = []L = len(input_data)for i in range(L - tw):train_seq = input_data[i:i + tw]if (i + tw + 4) > len(input_data):breaktrain_label = input_data[i + tw:i + tw + pre_len]inout_seq.append((train_seq, train_label))return inout_seqpre_len = 4
train_window = 16
# 定义训练器的的输入
train_inout_seq = create_inout_sequences(train_data_normalized, train_window, pre_len)class LSTM(nn.Module):def __init__(self, input_dim=1, hidden_dim=350, output_dim=1):super(LSTM, self).__init__()self.hidden_dim = hidden_dimself.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)self.fc = nn.Linear(hidden_dim, output_dim)def forward(self, x):x = x.unsqueeze(1)h0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)c0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)out, _ = self.lstm(x, (h0_lstm, c0_lstm))out = out[:, -1]out = self.fc(out)return outlstm_model = LSTM(input_dim=1, output_dim=pre_len, hidden_dim=train_window)
loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(lstm_model.parameters(), lr=0.001)
epochs = 10
Train = True # 训练还是预测if Train:losss = []lstm_model.train() # 训练模式start_time = time.time() # 计算起始时间for i in range(epochs):for seq, labels in train_inout_seq:lstm_model.train()optimizer.zero_grad()y_pred = lstm_model(seq)single_loss = loss_function(y_pred, labels)single_loss.backward()optimizer.step()print(f'epoch: {i:3} loss: {single_loss.item():10.8f}')losss.append(single_loss.detach().numpy())torch.save(lstm_model.state_dict(), 'save_model.pth')print(f"模型已保存,用时:{(time.time() - start_time) / 60:.4f} min")plt.plot(losss)# 设置图表标题和坐标轴标签plt.title('Training Error')plt.xlabel('Epoch')plt.ylabel('Error')# 保存图表到本地plt.savefig('training_error.png')
else:# 加载模型进行预测lstm_model.load_state_dict(torch.load('save_model.pth'))lstm_model.eval() # 评估模式results = []reals = []losss = []test_inout_seq = create_inout_sequences(test_data_normalized, train_window, pre_len)for seq, labels in train_inout_seq:pred = lstm_model(seq)[0].item()results.append(pred)mae = calculate_mae(pred, labels.detach().numpy()) # MAE误差计算绝对值(预测值 - 真实值)reals.append(labels.detach().numpy())losss.append(mae)print("模型预测结果:", results)print("预测误差MAE:", losss)plt.style.use('ggplot')# 创建折线图plt.plot(results, label='real', color='blue') # 实际值plt.plot(reals, label='forecast', color='red', linestyle='--') # 预测值# 增强视觉效果plt.grid(True)plt.title('real vs forecast')plt.xlabel('time')plt.ylabel('value')plt.legend()plt.savefig('test——results.png')
数据格式
运行上述代码需要只需要一列数据即可,并且最后数据需要是一个pd.series类型,大家可以在读取进来文件后面加一些数据的处理操作。
(需要注意的是大家的数据不要打乱时间顺序否则预测出来的结果可能不准)
代码讲解
在上面的运行代码中,主要填写的是在下面填上你的数据目录,
true_data = pd.read_csv('') # 填你自己的数据地址
这里是定义了test_data_size是指根据过去多少条数据来预测未来的预测值
test_size和train_size代表训练集和测试集的尺寸划分。
# 定义窗口大小
test_data_size = 350
# 训练集和测试集的尺寸划分
test_size = 0.15
train_size = 0.85
这里定义了数据加载器的操作
def create_inout_sequences(input_data, tw):inout_seq = []L = len(input_data)for i in range(L - tw):train_seq = input_data[i:i + tw]if (i + tw + 4) > len(input_data):breaktrain_label = input_data[i + tw:i + tw + 1]inout_seq.append((train_seq, train_label))return inout_seqtrain_window = 350
# 定义训练器的的输入
train_inout_seq = create_inout_sequences(train_data_normalized, train_window)
模型的本身其中包含一个LSTM层和一个全连接层进行结果的输出
class LSTM(nn.Module):def __init__(self, input_dim=1, hidden_dim=350, output_dim=1):super(LSTM, self).__init__()self.hidden_dim = hidden_dimself.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)self.fc = nn.Linear(hidden_dim, output_dim)def forward(self, x):x = x.unsqueeze(1)h0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)c0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)out, _ = self.lstm(x, (h0_lstm, c0_lstm))out = out[:, -1]out = self.fc(out)return out
这里定义了模型损失函数和优化器,其中的Train代表着是否进行训练。
lstm_model = LSTM()
loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(lstm_model.parameters(), lr=0.001)
epochs = 20
Train = False # 训练还是预测
当Train为True时则开始训练并在最好将模型保存到本地,训练好模型之后我门将Train设置为False则开始评估模式。
if Train:losss = []lstm_model.train() # 训练模式for i in range(epochs):start_time = time.time() # 计算起始时间for seq, labels in train_inout_seq:lstm_model.train()optimizer.zero_grad()y_pred = lstm_model(seq)single_loss = loss_function(y_pred, labels)losss.append(single_loss.detach().numpy())single_loss.backward()optimizer.step()if i % 1 == 1:print(f'epoch: {i:3} loss: {single_loss.item():10.8f}')torch.save(lstm_model.state_dict(), 'save_model.pth')print(f"模型已保存,用时:{(time.time() - start_time) / 60:.4f} min")plt.plot(losss)# 设置图表标题和坐标轴标签plt.title('Training Error')plt.xlabel('Epoch')plt.ylabel('Error')# 保存图表到本地plt.savefig('training_error.png')
else:# 加载模型进行预测lstm_model.load_state_dict(torch.load('save_model.pth'))lstm_model.eval() # 评估模式results = []losss = []test_inout_seq = create_inout_sequences(test_data_normalized, train_window)for seq, labels in test_inout_seq:# 这里的pred = lstm_model(seq)[0].item()是结果的输出这里只保存了输出的第一个值如果想拿出更多的预测值可以修改数字0用切片的方式pred = lstm_model(seq)[0].item()results.append(pred)mae = calculate_mae(pred, labels.detach().numpy()) # MAE误差计算绝对值(预测值 - 真实值)losss.append(mae)print("模型预测结果:", results)print("预测误差MAE:", losss)
后期我也会讲一些最新的预测模型包括Informer,TPA-LSTM,ARIMA,XGBOOST,Holt-winter,移动平均法等等一系列关于时间序列预测的模型,包括深度学习和机器学习方向的模型我都会讲,你可以根据需求选取适合你自己的模型进行预测,如果有需要可以+个关注,包括本次模型我自己的代码大家有需要我也会放出百度网盘下载链接!!
其它时间序列预测模型的讲解!
--------------------------------------------------------MTS-Mixers---------------------------------------------------------
【全网首发】(MTS-Mixers)(Python)(Pytorch)最新由华为发布的时间序列预测模型实战案例(一)(包括代码讲解)实现企业级预测精度包括官方代码BUG修复Transform模型
--------------------------------------------------------Holt-Winters--------------------------------------------------------
时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)
如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决!
相关文章:

时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)
目录 引言 LSTM的预测效果图 LSTM机制 了解LSTM的结构 忘记门 输入门 输出门 LSTM的变体 只有忘记门的LSTM单元 独立循环(IndRNN)单元 双向RNN结构(LSTM) 运行代码 代码讲解 引言 LSTM(Long Short-Term Memory)是一种常用的循环神经网络&a…...

[8] CUDA之向量点乘和矩阵乘法
CUDA之向量点乘和矩阵乘法 计算类似矩阵乘法的数学运算 1. 向量点乘 两个向量点乘运算定义如下: #真正的向量可能很长,两个向量里边可能有多个元素 (X1,Y1,Z1) * (Y1,Y2,Y3) X1Y1 X2Y2 X3Y3这种原始输入是两个数组而输出却缩减为一个(单一值)的运…...

音视频开发9 FFmpeg 解复用框架说明,重要知识点
一,播放器框架 二 常用音视频术语 容器/文件(Conainer/File): 即特定格式的多媒体文件, 比如mp4、flv、mkv等。 媒体流(Stream): 表示时间轴上的一段连续数据࿰…...

抖音小店出单之后怎么发货?抖店详细发货流程来了
大家好,我是喷火龙。 抖音小店发货是有规则的,如果出现超时发货或者虚假发货都会被平台处罚的,会影响我们店铺的评分和正常运营,还有些小伙伴们在发货的时候会遇到平台的违规提醒等问题。 今天我就给大家讲一下抖音小店的发货流…...
Transformer详解(5)-编码器和解码器
1、Transformer编码器 import torch from torch import nn import copy from norm import Norm from multi_head_attention import MultiHeadAttention from feed_forward import FeedForward from pos_encoder import PositionalEncoderdef get_clones(module, N):"&quo…...
线程安全-3 JMM
一.谈一下JMM 1.JMM,JavaMemoryModel,Java内存模型。定义了多线程对共享内存读写操作的行为规范,通过规范多线程对共享内存的读写操作,以保证指令执行和结果的正确性。 2.JMM把内存分为两块 (1)主内存&a…...
4 CSS的 变换、过渡与动画
CSS3引入了变换、过渡和动画特性,使得网页可以呈现出丰富的视觉效果和交互体验。通过这些新特性,开发者可以创建复杂的动画效果,而不需要使用JavaScript。 4.1 变换(Transforms) 变换允许开发者对元素进行旋转、缩放…...
前端基础入门三大核心之JS篇:掌握数字魔法 ——「累加器与累乘器」的奥秘籍【含样例代码】
前端基础入门三大核心之JS篇:掌握数字魔法 ——「累加器与累乘器」的奥秘籍 🧙♂️ 基础概念:数字的魔杖与炼金术累加器(Accumulator)累乘器(Multiplier) 📚 实战演练:…...
git clone 出现的问题
问题: core源码ref新API % git clone https://github.com/xxxx.git Cloning into core... remote: Enumerating objects: 58033, done. remote: Counting objects: 100% (1393/1393), done. remote: Compressing objects: 100% (750/750), done. error: 432 bytes of body are …...

Vue2和Vue3生命周期的对比
Vue2和Vue3生命周期的对比 Vue2 和 Vue3 生命周期对照表Vue2 和 Vue3 生命周期图示 Vue2 和 Vue3 生命周期对照表 触发时机Vue2.xVue3.x组件创建时运行beforeCreate setup createdsetup 挂载在DOM时运行beforeMountonBeforeMountmountedonMounted响应数据修改时运行beforeUpdat…...

全面解析Java.lang.ClassCastException异常
全面解析Java.lang.ClassCastException异常 全面解析Java.lang.ClassCastException异常:解决方案与最佳实践 🚀📚摘要引言1. 什么是Java.lang.ClassCastException?代码示例 2. 报错原因2.1 类型不兼容2.2 泛型类型擦除2.3 接口和实…...

美团Java社招面试题真题,最新面试题
如何处理Java中的内存泄露? 1、识别泄露: 使用内存分析工具(如Eclipse Memory Analyzer Tool、VisualVM)来识别内存泄露的源头。 2、代码审查: 定期进行代码审查,关注静态集合类属性和监听器注册等常见内…...

二十八、openlayers官网示例Data Tiles解析——自定义绘制DataTile源数据
官网demo地址: https://openlayers.org/en/latest/examples/data-tiles.html 这篇示例讲解的是自定义加载DataTile源格式的数据。 先来看一下什么是DataTile,这个源是一个数组,与我们之前XYZ切片源有所不同。DataTile主要适用于需要动态生成…...

分布式事务解决方案(最终一致性【TCC解决方案】)
最终一致性分布式事务概述 强一致性分布式事务解决方案要求参与事务的各个节点的数据时刻保持一致,查询任意节点的数据都能得到最新的数据结果,这就导致在分布式场景,尤其是高并发场景下,系统的性能受到了影响。而最终一致性分布式…...

App Inventor 2 Encrypt.Security 安全性扩展:MD5哈希,SHA/AES/RSA/BASE64
这是关于App Inventor和Thunkable安全性的扩展,它提供MD5哈希,SHA1和SHA256哈希,AES加密/解密,RSA加密/解密,BASE64编码/解码方法。 权限 此扩展程序不需要任何权限。 事件 OnErrorOccured 抛出任何异常时将触发此事件…...

深入了解Linux中的环境变量
在Linux系统中,环境变量(Environment Variables)是用于配置操作系统和应用程序运行环境的一种机制。它们储存在键值对中,可以控制程序的行为、路径查找和系统配置。本文将深入探讨环境变量的基本概念、常见类型、设置和管理方法&a…...

雷军-2022.8小米创业思考-8-和用户交朋友,非粉丝经济;性价比是最大的诚意;新媒体,直播离用户更近;用真诚打动朋友,脸皮厚点!
第八章 和用户交朋友 2005年,为了进一步推动金山的互联网转型,让金山的同事更好地理解互联网的精髓,我推动了一场向谷歌学习的运动,其中一个小要求就是要能背诵“谷歌十诫”。 十诫的第一条就令人印象深刻:以用户为中…...

【Vue2.x】props技术详解
1.什么是prop? 定义:组件标签上注册的一些自定义属性作用:向子组件传递数据特点 可以传递任意数量的prop可以传递任意类型的prop 2.prop校验 为了避免乱传数据,需要进行校验 完整写法 将之前props数组的写法,改为对象…...

C语言例题46、根据公式π/4=1-1/3+1/5-1/7+1/9-1/11+…,计算π的近似值,当最后一项的绝对值小于0.000001为止
#include <stdio.h> #include <math.h>int main() {int fm 1;//分母double sign 1;//正负号double fzs 1;//分子式double sum 0;while (fabs(fzs) > 0.000001) {sum fzs;sign * -1; //变换正负号fm 2; //分母3、5、7、9...增长fzs sign / fm;//分子式…...

fpga系列 HDL: 05 阻塞赋值(=)与非阻塞赋值(<=)
在Verilog硬件描述语言(HDL)中,信号的赋值方式主要分为两种:连续赋值和过程赋值。每种赋值方式有其独特的用途和语法,并适用于不同类型的电路描述。 1. 连续赋值(Continuous Assignment,assign 和…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...