当前位置: 首页 > news >正文

Pytorch的极简transformer用于时间序列预测

本博客来源于CSDN机器鱼,未同意任何人转载。

更多内容,欢迎点击本专栏,查看更多内容。

目录

0.引言

1.数据准备

2. 网络搭建

3. 完整代码

4. 结语


0.引言

在【博客】中,我们基于tensorflow2.x深度学习框架搭建了transformer模型用于时间序列预测,博客里较为详细的构建了位置编码、自注意力等模块。而从2017年发展到现在,因为tansformer大火,Pytorch已经将大部分基础模块写进了库函数中,因此我们可以用简单的几句程序搭建一个transformer。

主要用到的函数torch.nn.TransformerEncoderLayer。网上搜这个函数,可以看到内部集成了需要用到的多头注意力、LayerNorm等函数。同理Pytorch内部也集成了decoder,可以搜torch.nn.TransformerDecoderLayer。因此我们搭建一个transformer网络可以很简单。

1.数据准备

这次的数据两列的时间序列,如下所示。我们采用前n时刻的平均风速与平均功率,预测第n+1:n+m时刻的平均功率值。

数据拆分的代码如下:

数据含有2个特征,采用滚动序列建模的方法,生成输入数据与输出数据。具体为:设定输入时间步m与输出时间步n,然后取第1到m时刻的所有数据作为输入,取第m+1到第m+n时刻的功率作为输出,作为第一个样本;然后取第2到m+1时刻的所有数据作为输入,取第m+2到第m+n+1时刻的功率作为输出,作为第二个样本。。。依次类推,通过这种滚动的方法获得输入输出数据。举个例子,当m取10,n取3时,则输入层的维度为[None,10,2],输出层的维度为[None,3],模型训练好后,只需要输入过去10个时刻的所有数据,就能预测得到未来3个时刻的功率预测值。最后不要忘记了对数据进行归一化或者标准化

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler,StandardScalerdef create_inout_sequences(input_data, input_window,output_window):in_seq,out_seq = [],[]L = len(input_data)for i in range(L-input_window-output_window+1):train_seq = input_data[i:i+input_window,:]train_label = input_data[i+input_window:i+input_window+output_window,-1]in_seq.append(train_seq)out_seq.append(train_label)in_seq=np.array(in_seq).reshape(len(in_seq), -1)out_seq=np.array(out_seq).reshape(len(out_seq), -1)return in_seq,out_seq
# In[] 生成数据
input_window = 100 # number of input steps
output_window = 1 # number of prediction steps
series = pd.read_excel('数据.xlsx').iloc[:,1:]seriesdata=series.values#第一列是风速 第二列是功率
# 我们用前input_window个时刻的是风速与功率值预测output_window时刻的功率值data,label = create_inout_sequences(seriesdata,input_window,output_window)
# 数据划分 前70%训练 后30%测试
n=np.arange(data.shape[0])
m=int(0.7*data.shape[0])
train_data=data[n[0:m],:]
train_label=label[n[0:m]]
test_data=data[n[m:],:]
test_label=label[n[m:]]# 归一化
ss_X = StandardScaler().fit(train_data)
ss_Y = StandardScaler().fit(train_label)
# ss_X=MinMaxScaler(feature_range=(0,1)).fit(train_data)
# ss_Y=MinMaxScaler(feature_range=(0,1)).fit(train_label)
train_data = ss_X.transform(train_data).reshape(train_data.shape[0],input_window,-1)
train_label = ss_Y.transform(train_label)test_data = ss_X.transform(test_data).reshape(test_data.shape[0],input_window,-1)
test_label = ss_Y.transform(test_label)
feature_size=train_data.shape[-1]
out_size=train_label.shape[-1]

2. 网络搭建

 与【博客】一致,我们仅搭建一个encoder,直接将encoder的输出flatten成向量,然后输入进dense实现回归预测。网络构建部分的主要代码如下所示:

import torch
import torch.nn as nn
import numpy as np
#torch.manual_seed(0)
#np.random.seed(0)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")class PositionalEncoding(nn.Module):#https://zhuanlan.zhihu.com/p/389183195def __init__(self, d_model, max_len=5000,dropout=0.1):super(PositionalEncoding, self).__init__()       pe = torch.zeros(max_len, d_model)self.dropout = nn.Dropout(p=dropout)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)pe = pe.unsqueeze(0).transpose(0, 1)#pe.requires_grad = Falseself.register_buffer('pe', pe)def forward(self, x):x= x + self.pe[:x.size(0), :]return self.dropout(x)class TransAm(nn.Module):def __init__(self,feature_size=2,out_size=1,embedding_size=250,num_layers=1,dropout=0.1,nhead=10):super(TransAm, self).__init__()self.src_mask = Noneself.embedding= nn.Linear(feature_size,embedding_size)self.pos_encoder = PositionalEncoding(embedding_size)self.encoder_layer = nn.TransformerEncoderLayer(d_model=embedding_size, nhead=nhead, dropout=dropout)self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=num_layers)        self.decoder = nn.Linear(embedding_size,out_size)self.init_weights()def init_weights(self):initrange = 0.1    self.decoder.bias.data.zero_()self.decoder.weight.data.uniform_(-initrange, initrange)def forward(self,src):src=self.embedding(src)if self.src_mask is None or self.src_mask.size(0) != len(src):device = src.devicemask = self._generate_square_subsequent_mask(len(src)).to(device)self.src_mask = masksrc = self.pos_encoder(src)output = self.transformer_encoder(src,self.src_mask)#, self.src_mask)output = self.decoder(output)
#        print(output.size())return outputdef _generate_square_subsequent_mask(self, sz):mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))return mask

首先,我们用一个全连接层作为embed层,我们的数据特征是2维【平均风速与平均功率】,经过embedding升维至d_model维度。然后加上位置编码,最后将编码后的数据送至num_layer个transformerlayer构成的encoder中,并将encoder的结果输入dense实现预测输出,网络搭建就这么几句.

值得注意的是nn.TransformerEncoder接受的数据格式[seq_len,batchsize,d_model],输出也是[seq_len,batchsize,d_model]。并且可以不输入src_mask,用None替代也行。

3. 完整代码

有了数据、模型之后,搭配上损失函数,训练步骤就可以了,完整的代码如下:

import torch
import torch.nn as nn
import numpy as np
import math
import  matplotlib.pyplot as plt 
from sklearn.metrics import r2_score
from sklearn.preprocessing import MinMaxScaler,StandardScaler
import pandas as pd
#torch.manual_seed(0)
#np.random.seed(0)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#device = torch.device("cpu")
# In[] 此函数用于最后计算各种指标
def result(real,pred,name):# ss_X = MinMaxScaler(feature_range=(-1, 1))# real = ss_X.fit_transform(real).reshape(-1,)# pred = ss_X.transform(pred).reshape(-1,)real=real.reshape(-1,)pred=pred.reshape(-1,)# mapetest_mape = np.mean(np.abs((pred - real) / real))# rmsetest_rmse = np.sqrt(np.mean(np.square(pred - real)))# maetest_mae = np.mean(np.abs(pred - real))# R2test_r2 = r2_score(real, pred)print(name,'的mape:%.4f,rmse:%.4f,mae:%.4f,R2:%.4f'%(test_mape ,test_rmse, test_mae, test_r2))#位置编码
class PositionalEncoding(nn.Module):#https://zhuanlan.zhihu.com/p/389183195def __init__(self, d_model, max_len=5000,dropout=0.1):super(PositionalEncoding, self).__init__()       pe = torch.zeros(max_len, d_model)self.dropout = nn.Dropout(p=dropout)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))pe[:, 0::2] = torch.sin(position * div_term)pe[:, 1::2] = torch.cos(position * div_term)pe = pe.unsqueeze(0).transpose(0, 1)#pe.requires_grad = Falseself.register_buffer('pe', pe)def forward(self, x):x= x + self.pe[:x.size(0), :]return self.dropout(x)#主网络
class TransAm(nn.Module):def __init__(self,feature_size=2,out_size=1,embedding_size=250,num_layers=1,dropout=0.1,nhead=10):super(TransAm, self).__init__()self.src_mask = Noneself.embedding= nn.Linear(feature_size,embedding_size)self.pos_encoder = PositionalEncoding(embedding_size)self.encoder_layer = nn.TransformerEncoderLayer(d_model=embedding_size, nhead=nhead, dropout=dropout)self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=num_layers)        self.decoder = nn.Linear(embedding_size,out_size)self.init_weights()def init_weights(self):initrange = 0.1    self.decoder.bias.data.zero_()self.decoder.weight.data.uniform_(-initrange, initrange)def forward(self,src):src=self.embedding(src)if self.src_mask is None or self.src_mask.size(0) != len(src):device = src.devicemask = self._generate_square_subsequent_mask(len(src)).to(device)self.src_mask = masksrc = self.pos_encoder(src)output = self.transformer_encoder(src,self.src_mask)#, self.src_mask)output = self.decoder(output)
#        print(output.size())
#nn.TransformerEncoder的输入与输出都是(seqlen,batchsize,d_model)
#这里经过self.decoder之后变成了(seqlen,batchsize,out_size)
#由于数据处理里面我只预测了未来一个时刻的,所以这里取了[-1]return output[-1]def _generate_square_subsequent_mask(self, sz):mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))return maskdef create_inout_sequences(input_data, input_window,output_window):in_seq,out_seq = [],[]L = len(input_data)for i in range(L-input_window-output_window+1):train_seq = input_data[i:i+input_window,:]train_label = input_data[i+input_window:i+input_window+output_window,-1]in_seq.append(train_seq)out_seq.append(train_label)in_seq=np.array(in_seq).reshape(len(in_seq), -1)out_seq=np.array(out_seq).reshape(len(out_seq), -1)return in_seq,out_seqdef get_batch(source,target, i,batch_size):## transformer 只能输入 seqlenth x batch x dim 形式的数据。#所以这里做一下转换seq_len = min(batch_size, len(source) - 1 - i)input_ = source[i:i+seq_len] input_=torch.FloatTensor(input_).to(device)target_ = target[i:i+seq_len]    target_=torch.FloatTensor(target_).to(device)input_ = torch.stack(input_.chunk(input_window,1)) 
#    target_ = torch.stack(target_.chunk(input_window,1))input_=input_.squeeze(2)
#    target_=target_.unsqueeze(2)return input_, target_def evaluate(eval_model, data_source,data_target):eval_model.eval() # Turn on the evaluation modetotal_loss = 0.eval_batch_size = 64with torch.no_grad():for i in range(0, len(data_source) - 1, eval_batch_size):source, targets = get_batch(data_source,data_target, i,eval_batch_size)output = eval_model(source)            total_loss += len(data[0])* criterion(output, targets).cpu().item()return total_loss / len(data_source)# In[] 生成数据
input_window = 100 # number of input steps
output_window = 1 # number of prediction steps
series = pd.read_excel('数据.xlsx').iloc[:,1:]seriesdata=series.values#第一列是风速 第二列是功率
# 我们用前input_window个时刻的是风速与功率值预测input_window时刻的功率值data,label = create_inout_sequences(seriesdata,input_window,output_window)
# 数据划分 前70%训练 后30%测试
n=np.arange(data.shape[0])
m=int(0.7*data.shape[0])
train_data=data[n[0:m],:]
train_label=label[n[0:m]]
test_data=data[n[m:],:]
test_label=label[n[m:]]# 归一化
ss_X = StandardScaler().fit(train_data)
ss_Y = StandardScaler().fit(train_label)
# ss_X=MinMaxScaler(feature_range=(0,1)).fit(train_data)
# ss_Y=MinMaxScaler(feature_range=(0,1)).fit(train_label)
train_data = ss_X.transform(train_data).reshape(train_data.shape[0],input_window,-1)
train_label = ss_Y.transform(train_label)test_data = ss_X.transform(test_data).reshape(test_data.shape[0],input_window,-1)
test_label = ss_Y.transform(test_label)
feature_size=train_data.shape[-1]
out_size=train_label.shape[-1]
# In[]
model = TransAm(feature_size=feature_size,out_size=out_size,embedding_size=250,num_layers=1,dropout=0.1,nhead=10).to(device)
criterion = nn.MSELoss()
lr = 0.005 
batch_size = 64 
epochs = 100#optimizer = torch.optim.SGD(model.parameters(), lr=lr)
optimizer = torch.optim.AdamW(model.parameters(), lr=lr)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95)best_val_loss = float("inf")
best_model = None
train_all_loss,val_all_loss=[],[]
for epoch in range(1, epochs + 1):model.train() # Turn on the train mode \o/for batch, i in enumerate(range(0, len(train_data) - 1, batch_size)):source, targets = get_batch(train_data,train_label, i,batch_size)optimizer.zero_grad()output = model(source)loss = criterion(output, targets)loss.backward()torch.nn.utils.clip_grad_norm_(model.parameters(), 0.7)optimizer.step()model.eval() train_loss=evaluate(model, train_data,train_label)val_loss=evaluate(model, test_data,test_label)val_all_loss.append(val_loss)train_all_loss.append(train_loss)print('| end of epoch {:3d} | train loss {:5.5f} | valid loss {:5.5f}'.format(epoch, train_loss, val_loss))if val_loss < best_val_loss:best_val_loss = val_lossbest_model=modeltorch.save(best_model, 'model/best_model0.pth')scheduler.step() torch.save(model, 'model/last_model0.pth')
plt.figure
plt.plot(train_all_loss,label='train_loss')
plt.plot(val_all_loss,label='valid_loss')
plt.legend()
plt.title('loss curve')
plt.savefig('model/loss.jpg')
plt.show()# In[] 预测
# 预测并画图
model=torch.load('model/best_model0.pth', map_location=device).to(device)
model.eval() eval_batch_size = 64
truth,test_result=np.zeros((0,test_label.shape[-1])),np.zeros((0,test_label.shape[-1]))for i in range(0, len(test_data) - 1, eval_batch_size):data, targets = get_batch(test_data,test_label, i,eval_batch_size)output = model(data)            output=output.cpu().detach().numpy()targets=targets.cpu().detach().numpy()test_result = np.vstack([test_result, output])truth = np.vstack([truth, targets])predict = ss_Y.inverse_transform(test_result)
truth = ss_Y.inverse_transform(truth)
result(truth,predict,'Transformer')
plt.figure()
plt.plot(predict,color="red",label='pred')       
plt.plot(truth,color="blue",label='real')    
plt.grid(True, which='both')
plt.legend()
plt.savefig('model/result.jpg')
plt.show()

4. 结语

获取更多内容请点击【专栏】,您的点赞与收藏是我持续更新【Python神经网络1000个案例分析】的动力 

相关文章:

Pytorch的极简transformer用于时间序列预测

本博客来源于CSDN机器鱼&#xff0c;未同意任何人转载。 更多内容&#xff0c;欢迎点击本专栏&#xff0c;查看更多内容。 目录 0.引言 1.数据准备 2. 网络搭建 3. 完整代码 4. 结语 0.引言 在【博客】中&#xff0c;我们基于tensorflow2.x深度学习框架搭建了transforme…...

垂直行业突围:工业软件在汽车、航空领域的 “破壁” 实践

在当今科技高速发展的时代&#xff0c;工业软件已悄然完成从通用工具到垂直行业 “战略武器” 的蜕变。特别是在汽车与航空这两大高端制造领域&#xff0c;工业软件的价值早已超越单纯的效率提升&#xff0c;成为关乎核心技术自主可控的关键要素&#xff0c;一场围绕工业软件的…...

人工智能在智能家居中的应用与发展

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;智能家居逐渐成为现代生活的重要组成部分。从智能语音助手到智能家电&#xff0c;AI正在改变我们与家居环境的互动方式&#xff0c;让生活更加便捷、舒适和高效。本文将探讨人工智能在智能家居中的应用现状、…...

维度建模工具箱 提纲与总结

这里写自定义目录标题 基本概念事实表和维度表BI(Business Intelligence) 产品 事实表事实表的粒度事实表的种类 维度表建模技术基本原则避免用自然键作为维度表的主键&#xff0c;而要使用类似自增的整数键避免过度规范化避免变成形同事实表的维度表 SCD(Slowly Changed Dimen…...

Vue3 源码解析(六):响应式原理与 reactive

今天这篇文章是笔者会带着大家一起深入剖析 Vue3 的响应式原理实现&#xff0c;以及在响应式基础 API 中的 reactive 是如何实现的。对于 Vue 框架来说&#xff0c;其非侵入的响应式系统是最独特的特性之一了&#xff0c;所以不论任何一个版本的 Vue&#xff0c;在熟悉其基础用…...

规则引擎 - Easy Rules

Easy Rules 依赖demodemo1demo2 总结 Easy Rules 是一个轻量级的 Java 规则引擎&#xff0c;使用简单&#xff0c;适合快速开发和简单的规则场景&#xff0c;适合对于一些判断&#xff0c;是否属于白名单&#xff0c;是否有特殊权限&#xff0c;是否属于当前区域&#xff0c;调…...

uniapp打ios包

uniapp在windows电脑下申请证书并打包上架 前言 该开发笔记记录了在window系统下&#xff0c;在苹果开发者网站生成不同证书&#xff0c;进行uniapp打包调试和上线发布&#xff0c;对window用户友好 注&#xff1a;苹果打包涉及到两种证书&#xff1a;开发证书 和 分发证书 …...

from tensorflow.keras.models import Model中Model报红;以及动态链接库(DLL)初始化例程失败

博主也是网上搜索资料又问的kimi 试了一节课 总结下来&#xff1a; 1、用这句话导入Model from tensorflow.keras.models import Model 2、更新pip pip install --upgrade pip 3、卸载重装tensorflow pip uninstall tensorflow 4、使用阿里云使tensorflow降低到2.8.0&a…...

【初阶数据结构】树——二叉树(上)

文章目录 目录 前言 一、树 1.树的概念与结构 2.树相关术语 3.树的表示 二、二叉树 1.概念与结构 2.特殊的二叉树 3.二叉树存储结构 总结 前言 本篇带大家学习一种非线性数据结构——树&#xff0c;简单认识树和二叉数以及了解二叉树的存储结构。 一、树 1.树的概念与结构 树…...

Debian GNU/Linux的新手入门介绍

Debian GNU/Linux&#xff1a;起源、基本介绍与发行版对比 一、起源与发展历程 Debian GNU/Linux 是现存最古老的 Linux 发行版之一&#xff0c;由 Ian Murdock 于 1993 年 8 月 16 日创立。其名称结合了他的女友&#xff08;后成为妻子&#xff09;Debra 和他自己的名字 Ian…...

13 数据存储单位与 C 语言整数类型:从位到艾字节、常见整数类型及其范围、字面量后缀、精确宽度类型详解

1 数据存储单位 在计算机科学领域&#xff0c;数据存储采用分层级的单位体系&#xff0c;各层级单位以 2 的幂次方为换算基础&#xff0c;而非传统数学中的 10 的幂次方。 以下是常见的数据存储单位介绍&#xff1a; 位&#xff08;bit&#xff0c;b&#xff09;是计算机中的最…...

【CPU】结合RISC-V CPU架构回答中断系统的7个问题(个人草稿)

结合RISC-V CPU架构对中断系统七个关键问题的详细解析&#xff0c;按照由浅入深的结构进行说明&#xff1a; 一、中断请求机制&#xff08;问题①&#xff09; 硬件基础&#xff1a; RISC-V通过CLINT&#xff08;Core Local Interrupter&#xff09;和PLIC&#xff08;Platfor…...

基于unsloth微调一个越狱大模型

网上其实并没有找到现成的开源越狱数据集&#xff0c;所以数据集获取是个麻烦事。想了想easydataset&#xff0c;可能还是不行&#xff0c;easydataset是基于大模型回答的&#xff0c;大模型一般都做了对齐训练&#xff0c;那本地文档生成数据这条路也不可靠。 现成的越狱数据…...

城市客运安全员证适用岗位及要求

城市客运安全员证适用岗位及要求 城市客运安全员证是从事城市公共交通行业安全管理工作的重要资格证书&#xff0c;主要适用于以下岗位&#xff1a; 1. 公交车辆安全员 岗位职责&#xff1a;负责公交车辆运行过程中的安全监督&#xff0c;检查乘客携带物品&#xff0c;防止危…...

UDP协议详解

UDP协议详解 一、理解socket套接字 1.1理解IP ​ 我们都知道在网络中IP用来标识主机的唯一性。那么&#xff1f;这句话该如何理解呢&#xff1f;大家来思考一个问题&#xff1a;计算机之间传输传输数据是目的吗&#xff1f;就好比&#xff0c;你爸叫你给你妈带句话&#xff…...

Unreal Engine中FRotator与FQuat在赛车游戏方向盘控制中的协同应用解析

摘要 深入剖析 Unreal Engine 中这两个关键组件在赛车游戏方向盘控制中的协同作用&#xff0c;涵盖全流程与实践技巧。 一、引言 在赛车游戏开发中&#xff0c;实现逼真的方向盘控制是提升玩家体验的关键要素之一。而在 Unreal Engine 里&#xff0c;FRotator 与 FQuat 这两…...

第十四届蓝桥杯 2023 C/C++组 飞机降落

目录 题目&#xff1a; 题目描述&#xff1a; ​编辑题目链接&#xff1a; 思路&#xff1a; 核心思路&#xff1a; 思路详解&#xff1a; 代码&#xff1a; 代码详解&#xff1a; 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; 洛谷 P9241 [蓝桥杯 20…...

完美解决Microsoft Edge浏览器无法同步/一直在同步中/更新失败等问题

在使用Microsoft Edge浏览器的过程中&#xff0c;我们可能会遇到一些常见的问题&#xff0c;例如无法同步数据或无法更新浏览器。这些问题通常可以归结为以下两个主要原因&#xff1a; 一、网络连接问题 当Edge浏览器无法同步或更新时&#xff0c;首要考虑的是网络连接问题。…...

CSS文本属性

CSS文本属性 在CSS中&#xff0c;可以使用以下属性来设置文本的样式和布局&#xff1a; 1.color &#xff1a; 设置文本颜色。可以使用颜色名称、十六进制值或RGB值来指定颜色&#xff1a; p{color:red; }font-family &#xff1a; 设置文本的字体系列。可以指定一个或多个字…...

思科路由器做DNS服务器

1.实验环境中&#xff0c;常常需要一台DNS服务器来做名称解析&#xff0c;一般会安装一台windows server&#xff0c;启用dns服务&#xff0c;或者安装一台Linux服务器&#xff0c;安装Bind来实现&#xff1b;虽然可以实现你想要的功能&#xff0c;但是费时费力且配置复杂&…...

Windows部署FunASR实时语音听写便捷部署教程

FunASR提供可便捷本地或者云端服务器部署的实时语音听写服务,内核为FunASR已开源的runtime-SDK。 FunASR集成了达摩院语音实验室在Modelscope社区开源的语音端点检测(VAD)、Paraformer-large非流式语音识别(ASR)、Paraformer-large流式语音识别(ASR)、标点预测(PUNC) 等相关能…...

C++之unordered封装

目录 一、哈希表的修改 1.1、哈希表节点结构 1.2、迭代器 1.3、哈希表结构 1.4、完整代码 二、unordered_map的实现 二、unordered_set的实现 一、哈希表的修改 注意&#xff1a;这里我们使用哈希桶来封装unordered_map和unordered_set。 1.1、哈希表节点结构 templa…...

Pycharm(九)函数的闭包、装饰器

目录 一、函数参数 二、闭包 三、装饰器 一、函数参数 def func01():print("func01 shows as follows") func01() # 函数名存放的是函数所在空间的地址 print(func01)#<function func01 at 0x0000023BA9FC04A0> func02func01 print(func02)#<function f…...

7. 栈与队列(随想录)

1.栈实现队列 2.用队列实现栈 3.有效的括号 4.删除字符串中的所有相邻重复项 5.逆波兰表达式 6.滑动窗口最大值 7.前k个高频元素...

GPU软硬件架构协同设计解析

GPU软硬件架构协同设计解析 ​ GPU(图形处理器)的软硬件协同设计是其在通用计算和高性能计算(HPC)领域取得突破的核心原因。以下从硬件架构、软件架构、协同设计的关键技术及典型案例展开深度解析。 一、硬件架构的核心设计原则 流式多处理器(SM)的模块化设计 计算单元…...

【软考】论NoSQL数据库技术及其应用示例

论NoSQL数据库技术及其应用 随着互联网web2.0网站的兴起&#xff0c;传统关系数据库在应对web2.0 网站&#xff0c;特别是超大规模和高并发的web2.0纯动态SNS网站上已经显得力不从心&#xff0c;暴露了很多难以克服的问题&#xff0c;而非关系型的数据库则由于其本身的特点得到…...

特伦斯智慧钢琴评测:如何用科技重塑钢琴学习新体验

对于渴望学习钢琴的爱好者而言&#xff0c;传统钢琴的笨重体积、高昂成本与扰民问题往往成为绊脚石。而智能电钢琴的出现&#xff0c;正以轻量化设计、沉浸式体验与智能化功能打破这些壁垒。特伦斯智慧钢琴凭借其专业级硬件配置与创新教学系统&#xff0c;成为市场中兼具性能与…...

UML 状态图:解锁电子图书馆管理系统的高效设计

目录 一、UML 状态图的核心要素 状态&#xff1a;系统行为的 “栖息地” 转换&#xff1a;连接状态的 “桥梁” 动作&#xff1a;赋予功能的 “实践者” 二、电子图书馆管理系统状态图解析 系统空闲状态&#xff1a;一切的起点 读者登录与身份验证&#xff1a;安全的 “…...

UML 状态图:陪伴机器人系统示例

目录 一、状态图的基本概念 1.1 状态 1.2 转换 1.3 动作 二、陪伴机器人系统状态图解析 2.1 初始与待机状态 2.2 情绪检测中状态 2.3 陪伴模式下的细分 2.4 疏导模式的严谨流程 2.5 安抚模式的关键作用 三、状态图绘画 四、UML 状态图的强大 4.1 直观呈现系统行为…...

超详细实现单链表的基础增删改查——基于C语言实现

文章目录 1、链表的概念与分类1.1 链表的概念1.2 链表的分类 2、单链表的结构和定义2.1 单链表的结构2.2 单链表的定义 3、单链表的实现3.1 创建新节点3.2 头插和尾插的实现3.3 头删和尾删的实现3.4 链表的查找3.5 指定位置之前和之后插入数据3.6 删除指定位置的数据和删除指定…...

分布式光纤测温技术让森林火灾预警快人一步

2025年春季&#xff0c;多地接连发生森林火灾&#xff0c;累计过火面积超 3万公顷。春季历来是森林草原火灾易发、多发期&#xff0c;加之清明节已到来&#xff0c;生产生活用火活跃&#xff0c;民俗祭祀用火集中&#xff0c;森林火灾风险进一步加大。森林防火&#xff0c;人人…...

判断链表是否为环(Java版本自己用)

141. 环形链表 核心代码版本&#xff1a; public class Solution {public boolean hasCycle(ListNode head) {if (head null) {return false;}ListNode slow head;ListNode fast head.next;while (fast ! null && fast.next ! null) {if (slow fast) {return true…...

leetcode 516. Longest Palindromic Subsequence

题目描述&#xff1a; 代码&#xff1a; class Solution { public:int longestPalindromeSubseq(string s) {int n s.size();//i<j,dp[i][j]表示s[i,j]的最长回文子串的长度,按照这个定义dp[0][n-1]就是答案,i>j的dp[i][j]不定义vector<vector<int>> dp(n,…...

关于敏感文件或备份 安全配置错误 禁止通过 URL 访问 Vue 项目打包后的 .gz 压缩文件

要禁止通过 URL 访问 Vue 项目打包后的 .gz 压缩文件&#xff08;如 sc.6abb69d9.css.gz&#xff09;或其他敏感文件&#xff0c;可以通过 Nginx 配置和 Tomcat 配置双重防护来实现。以下是具体解决方案&#xff1a; 方法 1&#xff1a;通过 Nginx 配置禁止访问 .gz 文件 在 N…...

Linux系统启动全流程解析:从BIOS到用户登录

摘要 深度解析Linux系统启动五阶段&#xff1a;内核加载→init进程初始化→系统服务启动→终端创建→用户登录&#xff0c;涵盖SysV/Systemd差异及运行级别管理&#xff0c;提供故障排查指南。 一、启动流程全景概览 Linux系统启动过程严格遵循5个阶段顺序执行&#xff0c;每…...

unity动态骨骼架设+常用参数分享(包含部分穿模解决方案)

Unity骨骼物理模拟插件Dynamic Bone Dynamic Bone 可用于对角色的骨骼&#xff08;bones&#xff09;或者铰链系统&#xff08;joints&#xff09;施加物理效果。 物理效果可以使得游戏角色的头发、衣服、胸部或者是其他的任何部位&#xff0c;都可以以近似真实的状态运动。 …...

【云原生】k8s集群部署最新版ELFK日志采集平台

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Golang开…...

基于瑞芯微RK3576国产ARM八核2.2GHz A72 工业评估板——ROS2系统使用说明

前 言 本文主要介绍创龙科技TL3576-MiniEVM评估板演示基于Ubuntu的ROS系统(版本:ROS2 Foxy)使用说明,包括镜像编译、镜像替换,以及ROS系统测试的方法。适用开发环境如下。 Windows开发环境:Windows 10 64bit Linux虚拟机环境:VMware16.2.5、Ubuntu22.04.5 64bit U-B…...

android studio sdk unavailable和Android 安装时报错:SDK emulator directory is missing

md 网上说的都是更换proxy代理什么的&#xff0c;还有一些二其他乱七八糟的&#xff0c;根本没用&#xff0c;感觉很多就是解决不了问题&#xff0c;还贼多贼一致&#xff0c;同质化&#xff0c;感觉很坑人&#xff0c;让人觉得他们和我的一样的&#xff0c;大家都是按他们说的…...

qemu构建arm环境(AI生成)

要编译 qemu-system-arm&#xff0c;你需要安装一些依赖库&#xff0c;配置编译环境&#xff0c;并执行编译过程。以下是一般步骤&#xff0c;适用于大多数基于Linux的系统。 1. 安装依赖 首先&#xff0c;你需要安装一些必要的开发工具和库。你可以使用包管理器来安装这些依…...

10天学会嵌入式技术之51单片机-day-4

第十二章 中断系统 中断系统是单片机用于处理外部紧急事件的一种机制。中断系统工作的大致流程如下 图所示&#xff1a;当 CPU 正在处理某项任务时&#xff0c;外部发生了某个紧急事件&#xff0c;此时 CPU 会暂停当前 的工作&#xff0c;转而去处理这个紧急事件&#xff0c;处…...

spark—SQL3

连接方式 内嵌Hive&#xff1a; 使用时无需额外操作&#xff0c;但实际生产中很少使用。 外部Hive&#xff1a; 在虚拟机下载相关配置文件&#xff0c;在spark-shell中连接需将hive-site.xml拷贝到conf/目录并修改url、将MySQL驱动copy到jars/目录、把core-site.xml和hdfs-sit…...

CENTOS 7 安装VNC

一、VNC简介 VNC&#xff08;Virtual Network Computing&#xff09;&#xff0c;为一种使用RFB协议的屏幕画面分享及远程操作软件。此软件借由网络&#xff0c;可发送键盘与鼠标的动作及即时的屏幕画面。 VNC与操作系统无关&#xff0c;因此可跨平台使用&#xff0c;例如可用…...

第42讲:走进智慧农业的“感知神经系统”——农田遥感 + 边缘计算的融合实践

目录 ✨一、为什么要融合遥感与边缘计算? 🧪二、典型应用场景案例 ✅ 案例 1:棉花田的智能水分监测系统 ✅ 案例 2:水稻纹枯病自动识别与预警系统 💻三、关键技术框架与实现思路 🚦 1. 系统架构流程图: 📦 2. 模型部署建议: 💡四、未来发展趋势展望 �…...

Dify忘记管理员密码,重置的问题

今天本地win10电脑&#xff0c;使用源码启动dify&#xff0c;忘记了管理员账号和密码&#xff0c;于是网上查找解决办法。 1.有的网上资料说是去数据库删除用户表&#xff0c;于是进入数据库&#xff1a; docker exec -it docker-db-1 psql -U postgres -d dify 找到postgre…...

C#—Lazy<T> 类型(延迟初始化/懒加载模式)

C# 的 Lazy<T> 类型 Lazy<T> 是 C# 中的一个类&#xff0c;用于实现延迟初始化&#xff08;懒加载&#xff09;模式。它提供了一种线程安全的方式来延迟创建大型或资源密集型对象&#xff0c;直到第一次实际需要时才进行初始化。 主要特点 延迟初始化&#xff1a…...

unity打包安卓时的签名文件jks转换keystore

前言 unity打包安卓时需要的签名文件格式默认是keystore&#xff0c;而有时我们拿到的是jks格式的签名文件&#xff0c;就需要把jks格式文件转换成keystore格式文件。 其实在windows下也可以不转换&#xff0c;在选择签名文件的文件选择框时&#xff0c;把文件扩展名筛选项&a…...

Android audio_policy_configuration.xml加载流程

目录 一、audio_policy_configuration.xml文件被加载流程 1、AudioPolicyService 创建阶段 2、createAudioPolicyManager 实现 3、AudioPolicyManager 构造 4、配置文件解析 loadConfig 5、核心解析逻辑 PolicySerializer::deserialize 二、AudioPolicyConfig类解析 1、…...

AOSP Android14 Launcher3——远程窗口动画关键类SurfaceControl详解

在 Launcher3 执行涉及其他应用窗口&#xff08;即“远程窗口”&#xff09;的动画时&#xff0c;例如“点击桌面图标启动应用”或“从应用上滑回到桌面”的过渡动画&#xff0c;SurfaceControl 扮演着至关重要的角色。它是实现这些跨进程、高性能、精确定制动画的核心技术。 …...

iframe下系统访问跨域问题解决办法

问题描述&#xff1a;iframe下嵌入web页面&#xff0c;访问后端接口跨域&#xff0c;导致接口调不通。 产生原因&#xff1a;iframe下&#xff0c;web端访问后端接口时&#xff0c;会优先向后端发送请求方法为OPTIONS的预检测请求&#xff0c;该请求调用不通&#xff0c;导致真…...