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

游戏AI的创造思路-技术基础-深度学习(3)

继续填坑,本篇介绍深度学习中的长短期记忆网络~~~~

目录

3.3. 长短期记忆网络(LSTM)

3.3.1. 什么是长短期记忆网络

3.3.2. 形成过程与运行原理

3.3.2.1. 细胞状态与门结构

3.3.2.2. 遗忘门

3.3.2.3. 输入门

3.3.2.4. 细胞状态更新

3.3.2.5. 输出门

3.3.2.6. 以上各步骤的示例代码

3.3.3. 优缺点

3.3.4. 存在的问题及解决方法

3.3.5. 示例代码


3.3. 长短期记忆网络(LSTM)

3.3.1. 什么是长短期记忆网络

长短期记忆网络(LSTM,Long Short-Term Memory)算法是一种特殊的循环神经网络(RNN),它旨在解决传统RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题,从而更有效地学习序列中的长期依赖关系。

  • 为了最小化训练误差,通常使用梯度下降法,如应用时序性倒传递算法,来依据错误修改每次的权重。此外,LSTM有多种变体,其中一个重要的版本是门控循环单元(GRU)。
  • LSTM适合于处理和预测时间序列中间隔和延迟非常长的重要事件。其表现通常比时间递归神经网络及隐马尔科夫模型(HMM)更好。例如,在不分段连续手写识别上,LSTM模型曾赢得过ICDAR手写识别比赛冠军。此外,LSTM还广泛应用于自主语音识别,并在2013年使用TIMIT自然演讲数据库达成了17.7%的错误率纪录。
  • LSTM的成功在很大程度上促进了深度学习和人工智能领域的发展。尽管近年来出现了新的模型结构,如基于注意力机制的Transformer,但LSTM仍然是许多序列建模任务的可靠选择。随着时间的推移,LSTM被广泛应用于自然语言处理、语音识别、文本生成、视频分析等多个领域

3.3.2. 形成过程与运行原理

LSTM通过引入“”结构和“细胞状态”来更好地捕捉序列中的长期依赖关系。(通过借鉴脑神经学的知识来组建序列中的长期依赖关系)

3.3.2.1. 细胞状态与门结构

LSTM的核心是细胞状态,它像一条传送带,在整个链上运行,只有一些小的线性操作作用其上,信息在上面流传保持不变会很容易。LSTM通过精心设计的门结构来去除或增加信息到细胞状态,这些门结构包括遗忘门、输入门和输出门。

3.3.2.2. 遗忘门

决定从细胞状态中丢弃什么信息。它查看当前的输入和前一个时间步的隐藏状态,并为细胞状态中的每个数字输出一个在0到1之间的数字,1表示“完全保留”,0表示“完全舍弃”。

遗忘门决定了从上一个时间步的细胞状态中丢弃哪些信息。其计算公式为:

[ I_t = \sigma(X_tW_{xi} + H_{t-1}W_{hi} + b_i) ]

其中,( I_t )表示输入门在时刻( t )的值,( X_t )是时刻 ( t ) 的输入,( H_{t-1} )是前一个时刻的隐藏状态,( W_{xi} )( W_{hi} ) 是对应的权重矩阵,而( b_i )( b_i )是偏置项。函数( \sigma )表示sigmoid激活函数。

3.3.2.3. 输入门

决定什么新信息将被存储在细胞状态中。这包括两部分,一部分是输入门决定我们将更新哪些部分,另一部分是tanh层创建一个新的候选值向量,这个向量可能会被添加到细胞状态中。

[ F_t = \sigma(X_tW_{xf} + H_{t-1}W_{hf} + b_f) ]

类似地,( F_t )表示遗忘门在时刻( t )的值,其他符号的含义与输入门公式中的相同,只是权重和偏置项是针对遗忘门的。

3.3.2.4. 细胞状态更新

首先,旧细胞状态与遗忘门相乘,丢弃掉需要丢弃的信息。然后,将输入门的输出与tanh层的输出相乘,得出新的候选细胞状态。最后,将这两个值相加,形成新的细胞状态。

  • 旧细胞状态与遗忘门相乘

[ \tilde{C}t = C{t-1} \odot F_t ]

这里,( \tilde{C}t )表示经过遗忘门处理后的旧细胞状态,( C{t-1} )是前一个时刻的细胞状态,( F_t ) 是遗忘门在时刻( t )的输出,而( \odot )表示逐元素相乘(Hadamard乘积)。这一步的目的是丢弃掉不需要的信息。

  • 计算新的候选细胞状态

[ \hat{C}t = \tanh(X_tW{xc} + H_{t-1}W_{hc} + b_c) ]

其中,( \hat{C}t )是新的候选细胞状态,( X_t )是时刻 ( t )的输入,( H{t-1} ) 是前一个时刻的隐藏状态,( W_{xc} )( W_{hc} ) 是对应的权重矩阵,( b_c )是偏置项。函数 ( \tanh )是双曲正切激活函数,它将输入值压缩到 ( -1 ) 到 ( 1 ) 的范围内。

  • 将候选细胞状态与输入门相乘

[ i_t \odot \hat{C}_t ]

这里,( i_t )是输入门在时刻( t )的输出,( \odot )表示逐元素相乘。这一步的目的是根据输入门的选择来决定哪些新的信息被加入到细胞状态中。

  • 更新细胞状态

[ C_t = \tilde{C}_t + i_t \odot \hat{C}_t ]

最终,新的细胞状态( C_t )是经过遗忘门处理后的旧细胞状态 ( \tilde{C}_t )与经过输入门处理后的新候选细胞状态 ( i_t \odot \hat{C}_t ) 之和。这一步完成了细胞状态的更新,使得LSTM能够记住长期依赖关系。

3.3.2.5. 输出门

基于细胞状态来决定输出什么。首先,运行一个sigmoid层来确定细胞状态的哪个部分将输出,然后将细胞状态通过tanh进行处理(得到一个在-1到1之间的值),并将其与sigmoid门的输出相乘,最终得到输出。

[ O_t = \sigma(X_tW_{xo} + H_{t-1}W_{ho} + b_o) ]

在这里,( O_t )是输出门在时刻( t )的值,其他参数和符号的意义与前面公式中的一致,但针对输出门。

3.3.2.6. 以上各步骤的示例代码

Python代码示例

import numpy as np  def sigmoid(x):  return 1 / (1 + np.exp(-x))  def tanh(x):  return np.tanh(x)  # LSTM Cell 参数初始化  
input_size = 10  
hidden_size = 20  Wf = np.random.randn(hidden_size, hidden_size + input_size) # 遗忘门权重  
Wi = np.random.randn(hidden_size, hidden_size + input_size) # 输入门权重  
Wc = np.random.randn(hidden_size, hidden_size + input_size) # 候选细胞状态权重  
Wo = np.random.randn(hidden_size, hidden_size + input_size) # 输出门权重  # LSTM Cell 前向传播  
def lstm_cell_forward(xt, ht_prev, ct_prev, Wf, Wi, Wc, Wo):  # 拼接前一个隐藏状态和当前输入  concat = np.concatenate((ht_prev, xt), axis=0)  # 计算遗忘门  ft = sigmoid(np.dot(Wf, concat))  # 计算输入门  it = sigmoid(np.dot(Wi, concat))  # 计算候选细胞状态  cct = tanh(np.dot(Wc, concat))  # 细胞状态更新  ct = ft * ct_prev + it * cct  # 计算输出门  ot = sigmoid(np.dot(Wo, concat))  # 计算隐藏状态  ht = ot * tanh(ct)  return ht, ct  # 示例使用  
xt = np.random.randn(input_size) # 当前输入  
ht_prev = np.zeros(hidden_size) # 前一个隐藏状态  
ct_prev = np.zeros(hidden_size) # 前一个细胞状态  ht, ct = lstm_cell_forward(xt, ht_prev, ct_prev, Wf, Wi, Wc, Wo)

C++代码示例

#include <Eigen/Dense>  
#include <cmath>  using namespace Eigen;  // 激活函数  
double sigmoid(double x) {  return 1.0 / (1.0 + std::exp(-x));  
}  double tanh(double x) {  return std::tanh(x);  
}  // LSTM单元前向传播  
void LSTMCellForward(const VectorXd& xt, const VectorXd& ht_prev, const VectorXd& ct_prev,   const MatrixXd& Wf, const MatrixXd& Wi, const MatrixXd& Wc, const MatrixXd& Wo,  VectorXd& ht, VectorXd& ct) {  int input_size = xt.size();  int hidden_size = ht_prev.size();  VectorXd concat(input_size + hidden_size);  concat << ht_prev, xt;  // 计算遗忘门  VectorXd ft = concat.unaryExpr([](double elem) { return sigmoid(elem); }) * Wf.transpose();  // 计算输入门  VectorXd it = concat.unaryExpr([](double elem) { return sigmoid(elem); }) * Wi.transpose();  // 计算候选细胞状态  VectorXd cct = concat.unaryExpr([](double elem) { return tanh(elem); }) * Wc.transpose();  // 细胞状态更新  ct = ft.array() * ct_prev.array() + it.array() * cct.array();  // 计算输出门  VectorXd ot = concat.unaryExpr([](double elem) { return sigmoid(elem); }) * Wo.transpose();  // 计算隐藏状态  ht = ot.array() * ct.array().unaryExpr([](double elem) { return tanh(elem); });  
}  int main() {  int input_size = 10;  int hidden_size = 20;  MatrixXd Wf = MatrixXd::Random(hidden_size, hidden_size + input_size); // 遗忘门权重  MatrixXd Wi = MatrixXd::Random(hidden_size, hidden_size + input_size); // 输入门权重  MatrixXd Wc = MatrixXd::Random(hidden_size, hidden_size + input_size); // 候选细胞状态权重  MatrixXd Wo = MatrixXd::Random(hidden_size, hidden_size + input_size); // 输出门权重  VectorXd xt = VectorXd::Random(input_size); // 当前输入  VectorXd ht_prev = VectorXd::Zero(hidden_size); // 前一个隐藏状态  VectorXd ct_prev = VectorXd::Zero(hidden_size); // 前一个细胞状态  VectorXd ht(hidden_size), ct(hidden_size);  LSTMCellForward(xt, ht_prev, ct_prev, Wf, Wi, Wc, Wo, ht, ct);  // Do something with ht and ct...  return 0;  
}

这些代码是简化示例,实际应用中LSTM的实现会更加复杂,包括多个时间步的迭代、批处理支持、梯度计算和权重更新等。

在生产环境中,建议使用成熟的深度学习框架如TensorFlow或PyTorch来实现LSTM哦。

3.3.3. 优缺点

优点

  1. 能够有效地解决传统RNN中的梯度消失和梯度爆炸问题。
  2. 能够更好地捕捉序列中的长期依赖关系。
  3. 在处理长序列数据时具有优势。

缺点

  1. LSTM模型相对复杂,计算成本较高。
  2. 对于输入序列长度较长时,可能会出现过拟合现象,导致泛化能力下降。

3.3.4. 存在的问题及解决方法

过拟合问题:可以通过正则化、dropout等技术来减轻过拟合现象。

无法有效捕捉时间上下文关系:可以引入双向LSTM(Bidirectional LSTM)结构来提高对于时间上下文之间关系的建模能力。

对输入数据序列顺序敏感:在实际应用中,可以通过数据增强、序列颠倒等方法来减轻模型对输入数据序列顺序的敏感性。

3.3.5. 示例代码

Python代码

由于篇幅限制,这里提供一个简化的Python示例,使用PyTorch库实现LSTM:

import torch  
import torch.nn as nn  # 定义一个简单的LSTM模型  
class SimpleLSTM(nn.Module):  def __init__(self, input_size, hidden_size, output_size):  super(SimpleLSTM, self).__init__()  self.hidden_size = hidden_size  self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)  self.fc = nn.Linear(hidden_size, output_size)  def forward(self, x, hidden):  lstm_out, hidden = self.lstm(x, hidden)  output = self.fc(lstm_out[:, -1, :])  # 取最后一个时间步的输出进行分类  return output, hidden  def init_hidden(self, batch_size):  return (torch.zeros(1, batch_size, self.hidden_size),  torch.zeros(1, batch_size, self.hidden_size))  # 模型参数  
input_size = 10  
hidden_size = 20  
output_size = 2  
batch_size = 1  
sequence_length = 5  # 创建模型实例  
model = SimpleLSTM(input_size, hidden_size, output_size)  # 创建虚拟输入数据和初始隐藏状态  
x = torch.randn(batch_size, sequence_length, input_size)  
hidden = model.init_hidden(batch_size)  # 前向传播  
output, hidden = model(x, hidden)  
print(output)

C++代码

在C++中使用LSTM,我们通常会借助PyTorch的C++ API,也称为LibTorch。以下是一个简单的示例:

#include <torch/script.h> // 包含TorchScript的头文件  
#include <iostream>  int main() {  // 加载一个预先训练好的LSTM模型(这里假设你已经有一个用PyTorch训练的模型并导出了TorchScript)  torch::jit::script::Module module;  try {  module = torch::jit::load("lstm_model.pt"); // 加载模型  } catch (const c10::Error& e) {  std::cerr << "模型加载错误\n";  return -1;  }  // 创建一个输入张量,假设输入大小为[1, 5, 10](batch_size, sequence_length, input_size)  torch::Tensor input = torch::randn({1, 5, 10});  // 执行模型前向传播  std::vector<torch::jit::IValue> inputs;  inputs.push_back(input);  torch::Tensor output = module.forward(inputs).toTensor();  std::cout << output << std::endl;  return 0;  
}

请注意,C++ 示例中的模型需要是预先训练好并导出为TorchScript的模型。TorchScript是PyTorch的一个子集,允许模型在没有Python运行时的环境中执行。

在C++中直接使用LSTM而不依赖预先训练的模型会更复杂,因为你需要手动实现LSTM的所有细节。这通常不是推荐的做法,除非你有特定的性能要求或需要深度定制LSTM的行为。

在大多数情况下,使用PyTorch等高级库会更加方便和高效。

相关文章:

游戏AI的创造思路-技术基础-深度学习(3)

继续填坑&#xff0c;本篇介绍深度学习中的长短期记忆网络~~~~ 目录 3.3. 长短期记忆网络&#xff08;LSTM&#xff09; 3.3.1. 什么是长短期记忆网络 3.3.2. 形成过程与运行原理 3.3.2.1. 细胞状态与门结构 3.3.2.2. 遗忘门 3.3.2.3. 输入门 3.3.2.4. 细胞状态更新 3.…...

贪心算法练习题(2024/6/24)

1K 次取反后最大化的数组和 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数组 可能的最…...

大厂程序员上班猝死成常态?

大家好&#xff0c;我是瑶琴呀&#xff0c;拥有一头黑长直秀发的女程序员。 近日&#xff0c;连续看到大厂程序员猝死、低血糖晕倒的新闻&#xff0c;同为程序员感到很难受。互联网加班成常态这是既定事实&#xff0c;尤其在这个内卷严重、经济不景气的环境中&#xff0c;加班…...

深度学习 —— 1.单一神经元

深度学习初级课程 1.单一神经元2.深度神经网络3.随机梯度下降法4.过拟合和欠拟合5.剪枝、批量标准化6.二分类 前言 本套课程仍为 kaggle 课程《Intro to Deep Learning》&#xff0c;仍按之前《机器学习》系列课程模式进行。前一系列《Keras入门教程》内容&#xff0c;与本系列…...

Android 12.0 通知发送过程源码分析-Framework

以下NotificationManagerService简称 NMS 1. 通知的发送: NotificationManager.notify(int id, Notification notification) 开始. 源码路径: /frameworks/base/core/java/android/app/NotificationManager.java/***发布通知以显示在状态栏中。 如果通知带有* 相同的 ID 已被…...

提防远程攻击:了解正向 Shell 和反向 Shell 确保服务器安全

前言 在当今网络安全形势日益复杂的环境中&#xff0c;了解正向 Shell 和反向 Shell 的工作原理和使用场景&#xff0c;对于保护你的服务器免受远程攻击至关重要。本文不仅深入解析这两种常见的远程控制技术&#xff0c;还将提供有效的防护建议&#xff0c;帮助你提升服务器的…...

RabbitMQ中CorrelationData 与DeliveryTag的区别

在RabbitMQ中&#xff0c;CorrelationData是一个用于封装业务ID信息的类&#xff0c;它主要在消息确认机制中发挥作用。以下是关于CorrelationData在RabbitMQ中的详细作用&#xff1a; 封装业务ID信息&#xff1a; 当发送消息时&#xff0c;可以将业务ID信息封装在Correlation…...

数据恢复篇:如何在Android上恢复删除的短信

如果您不小心删除了Android设备上的短信并想要检索它们&#xff0c;则可以尝试以下方法&#xff1a; 如何在Android上恢复删除的短信 检查您的备份&#xff1a; 如果您之前备份了Android设备&#xff0c;则可以从备份中恢复已删除的短信。检查您设备的内部存储空间或 Google 云…...

花了大几万的踩坑经验!宠物空气净化器哪个牌子好:希喂、小米、有哈PK

我的闺蜜最近向我大吐苦水&#xff0c;自从家里养了猫之后&#xff0c;她发现家里的空气质量大不如前。宠物的浮毛和排泄物的气味在空气中飘散&#xff0c;让她非常怀念以前没有养猫时家里清新的呼吸环境。她觉得这些漂浮的毛发和异味大大降低了居家的舒适度。 还引起了身体上…...

查普曼大学团队使用惯性动捕系统制作动画短片

道奇电影和媒体艺术学院是查普曼大学的知名学院&#xff0c;同时也是美国首屈一指的电影学院之一&#xff0c;拥有一流电影制作工作室。 最近&#xff0c;道奇学院的一个学生制作团队接手了一个项目&#xff0c;该项目要求使用真人动作、视觉效果以及真人演员和CG角色之间的互动…...

vue 代理

一、常用的发送一个ajax请求&#xff1a; 1、xhr new XMLHttpRequest(),真正开发中不常用 2、jq&#xff0c;jq主要功能是获取dom&#xff0c;周边才是请求接口 3、axios&#xff08;大名鼎鼎的&#xff09; axios.get("url").then(response>{},error>{} )4、…...

[leetcode]24-game

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:static constexpr int TARGET 24;static constexpr double EPSILON 1e-6;static constexpr int ADD 0, MULTIPLY 1, SUBTRACT 2, DIVIDE 3;bool judgePoint24(vector<int> &nums) {vector&l…...

网络爬虫的原理

网络爬虫的原理 网络爬虫&#xff0c;作为信息检索和数据分析的重要工具&#xff0c;其原理的核心在于模拟人类浏览网页的行为&#xff0c;通过自动化的方式从互联网上收集所需的数据。在了解了网络爬虫的基本原理后&#xff0c;我们可以进一步探讨其在实际应用中的工作机制以…...

游戏AI的创造思路-技术基础-机器学习(2)

本篇存在大量的公式&#xff0c;数学不好的孩子们要开始恶补数学了&#xff0c;尤其是统计学和回归方程类的内容。 小伙伴们量力而行~~~~~ 游戏呢&#xff0c;其实最早就是数学家、元祖程序员编写的数学游戏&#xff0c;一脉相承传承至今&#xff0c;囊括了更多的设计师、美术…...

【深度学习】记录为什么没有调用GPU

排查CLIP为什么评测推理没有调用GPU&#xff0c;主要是这个代码&#xff1a;https://github.com/OFA-Sys/Chinese-CLIP/blob/master/cn_clip/eval/extract_features.py 第一次认为&#xff1a;因为model并没有to.cuda()。 但是又发现&#xff0c;model.cuda(args.gpu) # 已经加…...

vite 创建vue3项目 集成 ESLint、Prettier、Sass等

在网上找了一大堆vue3脚手架的东西&#xff0c;无非就是vite或者vue-cli,在vue2时代&#xff0c;vue-cli用的人挺多的&#xff0c;也很好用&#xff0c;然而vue3大多是和vite搭配搭建的&#xff0c;而且个人感觉vite这个脚手架并没有那么的好用&#xff0c;搭建项目时只能做两个…...

计算机系统基础知识(上)

目录 计算机系统的概述 计算机的硬件 处理器 存储器 总线 接口 外部设备 计算机的软件 操作系统 数据库 文件系统 计算机系统的概述 如图所示计算机系统分为软件和硬件&#xff1a;硬件包括&#xff1a;输入输出设备、存储器&#xff0c;处理器 软件则包括系统软件和…...

[深度学习]循环神经网络RNN

RNN&#xff08;Recurrent Neural Network&#xff0c;即循环神经网络&#xff09;是一类用于处理序列数据的神经网络&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;、时间序列预测、语音识别等领域。与传统的前馈神经网络不同&#xff0c;RNN具有循环结构&am…...

【C++:list】

list概念 list是一个带头的双向循环链表&#xff0c;双向循环链表的特色&#xff1a;每一个节点拥有两 个指针进行维护&#xff0c;俩指针分别为prev和next,prev指该节点的前一个节点&#xff0c;next为该节点的后一个节点 list的底层实现中为什么对迭代器单独写一个结构体进行…...

解锁 Apple M1/M2 上的深度学习力量:安装 TensorFlow 完全指南

前言 随着 Apple M1 和 M2 芯片的问世&#xff0c;苹果重新定义了笔记本电脑和台式机的性能标准。这些强大的芯片不仅适用于日常任务&#xff0c;还能处理复杂的机器学习和深度学习工作负载。本文将详细介绍如何在 Apple M1 或 M2 芯片上安装和配置 TensorFlow&#xff0c;助你…...

Apache Iceberg:现代数据湖存储格式的未来

Apache Iceberg 是一个开源的表格式&#xff0c;用于在分布式数据湖中管理大规模数据集。它由 Netflix 开发&#xff0c;并捐赠给 Apache 基金会。Iceberg 的设计目标是解决传统数据湖存储格式&#xff08;如 Apache Hive 和 Apache Parquet&#xff09;在大规模数据管理中的一…...

【离散数学·图论】(复习)

一、基本概念 1.一些基本术语&#xff1a; 2.点u&#xff0c;v邻接&#xff08;或相邻&#xff09;: 边e称为关联顶点u和v,or e连接u和v; 3.G(V,E)中&#xff0c;顶点v所有邻居的集合&#xff1a;N(v), 成为v的邻域。 4.度 &#xff1a; deg(v) 5.悬挂点&#xff1a;度为1的…...

【ONLYOFFICE震撼8.1】ONLYOFFICE8.1版本桌面编辑器测评

随着远程工作的普及和数字化办公的发展&#xff0c;越来越多的人开始寻找一款具有强大功能和便捷使用的办公软件。在这个时候&#xff0c;ONLYOFFICE 8.1应运而生&#xff0c;成为了许多用户的新选择。ONLYOFFICE 8.1是一种办公套件软件&#xff0c;它提供了文档处理、电子表格…...

Shell 脚本编程保姆级教程(上)

一、运行第一个 Shell 脚本 1.1 Shell 脚本 Shell 脚本&#xff08;shell script&#xff09;&#xff0c;是一种为 shell 编写的脚本程序。 业界所说的 shell 通常都是指 shell 脚本&#xff0c;但读者朋友要知道&#xff0c;shell 和 shell script 是两个不同的概念。 由…...

凸优化相关文章汇总

深度学习/机器学习入门基础数学知识整理&#xff08;三&#xff09;&#xff1a;凸优化&#xff0c;Hessian&#xff0c;牛顿法_深度学习和凸优化-CSDN博客 深度学习/机器学习入门基础数学知识整理&#xff08;四&#xff09;&#xff1a;拟牛顿法、BFGS、L-BFGS、DFP、共轭梯…...

Java鲜花下单预约系统源码小程序源码

让美好触手可及 &#x1f338;一、开启鲜花新篇章 在繁忙的都市生活中&#xff0c;我们总是渴望那一抹清新与美好。鲜花&#xff0c;作为大自然的馈赠&#xff0c;总能给我们带来无尽的惊喜与愉悦。但你是否曾因为工作繁忙、时间紧张而错过了亲自挑选鲜花的机会&#xff1f;今…...

网络变压器和RJ45接线的方法

网络变压器在以太网硬件电路设计中扮演着重要的角色&#xff0c;它主要用于信号电平耦合、隔离外部干扰、实现阻抗匹配以及增加传输距离。而RJ45接口则是以太网连接的标准化接口&#xff0c;它提供了与网络电缆的连接点。 网络变压器与RJ45的接线方法通常遵循以下步骤&#xf…...

Matlab/simulink三段式电流保护

电流1段仿真波形如下所示 电流2段仿真波形如下所示 电流3段仿真波形如下所示...

OOXML入门学习

进入-飞入 <par> <!-- 这是一个并行动画序列的开始。"par"代表并行&#xff0c;意味着在这个标签内的所有动画将同时开始。 --><cTn id"5" presetID"2" presetClass"entr" presetSubtype"4" fill"hold&…...

k8s集群node节点加入失败

出现这种情况&#xff1a; [preflight] FYI: You can look at this config file with kubectl -n kube-system get cm kubeadm-config -o yaml [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kub…...

layui+jsp项目中实现table单元格嵌入下拉选择框功能,下拉选择框可手动输入内容或选择默认值,修改后数据正常回显。

需求 table列表中的数据实现下拉框修改数据&#xff0c;当默认的下拉框不符合要求时&#xff0c;可手动输入内容保存。内容修改后表格显示修改后的值同时表格不刷新。 实现 layui框架下拉框组件只能选择存在的数据&#xff0c;不支持将输入的内容显示在input中的功能&#x…...

2024年客户体验的几个预测

数字化转型、以客户为中心的理念、数字技术的发展和产品的不断创新&#xff0c;都为客户体验带来了巨大的改变。 目前&#xff0c;我们看到很多公司都在致力于塑造一种以客户为中心的商业模式。企业开始用更多技术、更多数据和更多产品来强化自己在客户体验方面的能力。 那么&a…...

【C++】动态内存管理new和delete

文章目录 一、C的内存管理方式二、new和delete的用法1.操作内置类型2.操作自定义内置类型 三、new和delete的底层实现1.operator new和operator delete函数2.new和delete的实现原理 四、定位new表达式五、malloc/free和new/delete的区别 一、C的内存管理方式 之前在C语言的动态…...

Java面向对象特性

Java继承&#xff1a; 继承的概念&#xff1a; 在Java中&#xff0c;继承&#xff08;inheritance&#xff09;是面向对象编程的一个重要概念&#xff0c;它允许一个类&#xff08;子类&#xff09;继承另一个类&#xff08;父类&#xff09;的属性和方法。通过继承&#xff0c…...

odoo17 tree视图添加按钮

需求描述 点击下图中tree视图上的同步退货单按钮,弹出相应的form视图进行退货单同步,然后点击同步按钮调用后端python代码处理。 实现步骤 主要文件目录结构 js文件的创建 /** @odoo-module **/ import {registry } from "@web/core/registry"; import {listVie…...

PreparedStatement 与Statement 的区别,以及为什么推荐使用 PreparedStatement ?

在Java中&#xff0c;PreparedStatement和Statement都是用于执行SQL语句的重要接口&#xff0c;但它们在功能、安全性和性能上有着显著的差异。理解这些差异对于编写高效且安全的数据库应用程序至关重要。 Statement&#xff1a;基本的SQL执行者 首先&#xff0c;让我们从Sta…...

wsl ubuntu 安装Anaconda3步骤

如何在Ubuntu上安装Anaconda3呢?本章记录整个安装过程。 1、下载脚本 https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2023.09-0-Linux-x86_64.sh 下载之后,将脚本上传到Ubuntu里。 2、安装脚本 bash Anaconda3-2021.11-Linux-x86_64.sh根据提示进行安装,提示输…...

Vue3响应式 ref全家桶

<template><div>{{ man.name }}<hr><button click"change">修改</button></div> </template> <script setup lang"ts"> const man {name:"cc"} const change () >{man.name "大cc&q…...

Mac(M1芯片)安装多个jdk,Mac卸载jdk

1.jdk下载 oracle官方链接&#xff1a;oracle官方下载链接 2.安装 直接下一步&#xff0c;下一步就行 3.查看是否安装成功 出现下图内容表示安装成功。 4.配置环境变量 open -e .bash_profile 路径建议复制过去 #刷新环境变量 source ~/.bash_profile 5.切换方法 6.jdk…...

Warning message:package ‘ggplot2’ is not available (for R version 3.2.3)

install.packages(ggplot2) Installing package into ‘/usr/local/lib/R/site-library’ (as ‘lib’ is unspecified) Warning message: package ‘ggplot2’ is not available (for R version 3.2.3) 根据你提供的信息&#xff0c;警告消息表明在你的R版本&#xff08;3.2.3…...

Spring Boot 过滤器和拦截器详解

目录 Spring Boot 过滤器1.什么是过滤器2.工作机制3.实现过滤器 Spring Boot 拦截器1. 什么是拦截器2. 工作原理3.实现4.拓展&#xff08;MethodInterceptor 拦截器&#xff09;实现 过滤器和拦截器区别过滤器和拦截器应用场景过滤器拦截器 Spring Boot 过滤器 1.什么是过滤器 …...

Eureka介绍与使用

Eureka是一个开源的服务发现框架&#xff0c;由Netflix开发并在2015年成为Apache的顶级项目。Eureka的核心功能是服务注册与发现&#xff0c;它允许微服务应用在启动时将自己注册到Eureka服务器&#xff0c;并能通过Eureka服务器来发现其他已注册的服务。 使用Eureka有以下几个…...

JVM专题九:JVM分代知识点梳理

今天开始&#xff0c;咱们开始剖析JVM内存划分的原理细节&#xff0c;以及我们创建的那些对象在JVM中到底是如何分配&#xff0c;如何流动的&#xff0c;首先解决第一个问题&#xff1a;JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道&#xff0c;那就是我…...

wireshark常用过滤命令

wireshark常用过滤命令 wireshark抓包介绍单机单点&#xff1a;单机多点&#xff1a;双机并行&#xff1a; wireshark界面认识默认布局调整布局(常用)显示FCS错误 wireshark常见列Time回包数据报对应网络模型 wireshark基本操作结束抓包再次开始抓包 **wireshark常用过滤命令**…...

「全新升级,性能更强大——ONLYOFFICE 桌面编辑器 8.1 深度评测」

文章目录 一、背景二、界面设计与用户体验三、主要新功能亮点3.1 高效协作处理3.2 共同编辑&#xff0c;毫无压力3.3 批注与提及3.4 追踪更改3.5 比较与合并3.6 管理版本历史 四、性能表现4.1 集成 AI 工具4.2 插件强化 五、用户反馈与使用案例 一、背景 Ascensio System SIA -…...

线程版服务器实现(pthread_server)

用到的所有方法所需要的参数可以在wrap.c文件中查询&#xff0c;wrap中找不到的直接通过man手册查询 1.首先介绍一下我自己写的包裹文件&#xff0c;里面有各种在可能要用到的方法 wrap.c: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #…...

js异常处理方案

文章目录 异常处理方案同步代码的异常处理Promise 的异常处理async await 的异常处理 感谢阅读&#xff0c;觉得有帮助可以点点关注点点赞&#xff0c;谢谢&#xff01; 异常处理方案 在JS开发中&#xff0c;处理异常包括两步&#xff1a;先抛出异常&#xff0c;然后捕获异常。…...

C++文件路径处理2 - 路径拼接路径解析

1. 关键词2. filesystem.h3. filepath.cpp6. 测试代码7. 运行结果8. 源码地址 1. 关键词 关键词&#xff1a; C 文件路径处理 路径拼接 获取父目录的路径 获取文件名 获取拓展名 跨平台 应用场景&#xff1a; 路径的拼接路径的解析 2. filesystem.h #pragma once#include…...

数据结构5---矩阵和广义表

一、矩阵的压缩存储 特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律。 稀疏矩阵:矩阵中有很多零元素。压缩存储的基本思想是: (1)为多个值相同的元素只分配一个存储空间; (2)对零元素不分配存储空间。 1、特殊矩阵的压缩存储 &#xff08;1&#xff09;对称矩…...

jquery使用infinitescroll无线滚动+自定义翻页

jquery版本 jquery-1.8.3.js infinitescroll版本 2.0.0 如果infinitescroll版本最新的jquery版本也要用新的 接口用nodejs jquery.infinitescroll.js官网地址 前端代码《接口返回JSON数据》 <!DOCTYPE html> <html lang"en"> <head><meta cha…...