双向RNN和双向LSTM

双向RNN和双向LSTM

一、双向循环神经网络BiRNN

1、为什么要用BiRNN

双向RNN,即可以从过去的时间点获取记忆,又可以从未来的时间点获取信息,也就是说具有以下两个特点:

捕捉前后文信息:传统的单向 RNN 只能利用先前的上下文信息,而 BiRNN 同时利用了输入序列的前后文信息。在很多任务中,如自然语言处理中的命名实体识别、机器翻译等,理解一个词的前后文语境至关重要。

例如:img

判断句子中Teddy是否是人名,如果只从前面两个词是无法得知Teddy是否是人名,如果能有后面的信息就很好判断了,这就需要用的双向循环神经网络。

提高精度:在处理某些序列数据时,单向 RNN 可能无法充分捕捉整个序列中的重要信息,导致性能欠佳。BiRNN 能够通过双向处理,提高模型的表达能力和准确度。

2、BiRNN的架构

双向循环神经网络(BRNN)的基本思想是提出每一个训练序列向前和向后分别是两个循环神经网络(RNN),而且这两个都连接着一个输出层。这个结构提供给输出层输入序列中每一个点的完整的过去和未来的上下文信息。下图展示的是一个沿着时间展开的双向循环神经网络。六个独特的权值在每一个时步被重复的利用,六个权值分别对应:输入到向前和向后隐含层(w1, w3),隐含层到隐含层自己(w2, w5),向前和向后隐含层到输出层(w4, w6)。值得注意的是:向前和向后隐含层之间没有信息流,这保证了展开图是非循环的。每一个输出都是综合考虑两个方向获得的结果再输出,如下图所示:

在这里插入图片描述

H → t = ϕ ( X t W x h ( f ) + H → t − 1 W h h ( f ) + b h ( f ) ) , H ← t = ϕ ( X t W x h ( b ) + H ← t + 1 W h h ( b ) + b h ( b ) ) , \begin{array}{l} \overrightarrow{\mathbf{H}}_{t}=\phi\left(\mathbf{X}_{t} \mathbf{W}_{x h}^{(f)}+\overrightarrow{\mathbf{H}}_{t-1} \mathbf{W}_{h h}^{(f)}+\mathbf{b}_{h}^{(f)}\right), \\ \overleftarrow{\mathbf{H}}_{t}=\phi\left(\mathbf{X}_{t} \mathbf{W}_{x h}^{(b)}+\overleftarrow{\mathbf{H}}_{t+1} \mathbf{W}_{h h}^{(b)}+\mathbf{b}_{h}^{(b)}\right), \end{array} H t=ϕ(XtWxh(f)+H t1Whh(f)+bh(f)),H t=ϕ(XtWxh(b)+H t+1Whh(b)+bh(b)),
拼接得到结果:
H t = [ H → t H ← t ] \mathbf{H}_{t}=\left[\overrightarrow{\mathbf{H}}_{t} \overleftarrow{\mathbf{H}}_{t}\right] Ht=[H tH t]
至于网络单元到底是标准的RNN还是GRU或者是LSTM是没有关系的

(GRU:把遗忘门和输入门合并成一个更新门(Update Gate),并且把Cell State和Hidden State也合并成一个Hidden State,它的计算如下图所示)

在这里插入图片描述

对于整个双向循环神经网络(BRNN)的计算过程如下:

向前推算(Forward pass):

对于双向循环神经网络(BRNN)的隐含层,向前推算跟单向的循环神经网络(RNN)一样,除了输入序列对于两个隐含层是相反方向的,输出层直到两个隐含层处理完所有的全部输入序列才更新:

img

向后推算(Backward pass):

双向循环神经网络(BRNN)的向后推算与标准的循环神经网络(RNN)通过时间反向传播相似,除了所有的输出层δ项首先被计算,然后返回给两个不同方向的隐含层:

img

3、代码(用IMDB进行情感分析)

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 torch.utils.data import Dataset, DataLoader
import spacy
from torchtext.vocab import GloVe

# 加载数据集
base_csv = r'E:\kaggle\情感分析\archive (1)\IMDB Dataset.csv'
df = pd.read_csv(base_csv)

# 分割数据集
train_data, test_data = train_test_split(df, test_size=0.2, random_state=42)

# 保存为CSV文件
train_data.to_csv('train.csv', index=False)
test_data.to_csv('test.csv', index=False)

# 加载Spacy分词器
spacy_en = spacy.load('en_core_web_sm')
tokenizer = spacy_en.tokenizer

class TextDataset(Dataset):
    def __init__(self, dataframe, text_field, label_field, vocab):
        self.dataframe = dataframe
        self.text_field = text_field
        self.label_field = label_field
        self.vocab = vocab

    def __len__(self):
        return len(self.dataframe)

    def __getitem__(self, idx):
        text = self.dataframe.iloc[idx][self.text_field]
        label = self.dataframe.iloc[idx][self.label_field]
        tokens = tokenizer(text)
        token_ids = [self.vocab.get(token.text, self.vocab['<unk>']) for token in tokens]
        label = 1 if label == "positive" else 0
        return torch.tensor(token_ids, dtype=torch.long), torch.tensor(label, dtype=torch.long)

# 加载预训练词向量
glove_embeddings = GloVe(name='6B', dim=100)
vocab = glove_embeddings.stoi
vocab['<unk>'] = len(vocab)  # 添加 <unk> 标记
glove_embeddings.vectors = torch.cat((glove_embeddings.vectors, torch.zeros(1, glove_embeddings.dim)), 0)

# 创建数据集
train_dataset = TextDataset(train_data, 'review', 'sentiment', vocab)
test_dataset = TextDataset(test_data, 'review', 'sentiment', vocab)

# 创建数据加载器
batch_size = 32

def collate_fn(batch):
    texts, labels = zip(*batch)
    text_lengths = [len(text) for text in texts]
    padded_texts = nn.utils.rnn.pad_sequence(texts, batch_first=True, padding_value=0)
    return padded_texts, torch.tensor(labels, dtype=torch.long)

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_fn)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, collate_fn=collate_fn)

# 定义模型
class BiRNN(nn.Module):
    def __init__(self, vocab_size, embed_size, hidden_size, num_layers, num_classes, pad_idx):
        super(BiRNN, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.num_directions = 2

        self.embedding = nn.Embedding(vocab_size, embed_size, padding_idx=pad_idx)
        self.rnn = nn.GRU(embed_size, hidden_size, num_layers, batch_first=True, bidirectional=True)
        self.fc = nn.Linear(hidden_size * self.num_directions, num_classes)

    def forward(self, x):
        h0 = torch.zeros(self.num_layers * self.num_directions, x.size(0), self.hidden_size).to(x.device)
        x = self.embedding(x)
        out, _ = self.rnn(x, h0)
        out = self.fc(out[:, -1, :])
        return out

# 设置参数
vocab_size = len(vocab)
embed_size = 100
hidden_size = 256
num_layers = 2
num_classes = 2
pad_idx = 0

model = BiRNN(vocab_size, embed_size, hidden_size, num_layers, num_classes, pad_idx)
model.embedding.weight.data.copy_(glove_embeddings.vectors)
model.embedding.weight.data[pad_idx] = torch.zeros(embed_size)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
criterion = criterion.to(device)

# 训练模型
num_epochs = 5

for epoch in range(num_epochs):
    model.train()
    epoch_loss = 0
    for texts, labels in train_loader:
        texts = texts.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()
        outputs = model(texts)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()

    print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss / len(train_loader):.4f}')

# 评估模型
model.eval()
with torch.no_grad():
    correct = 0
    total = 0
    for texts, labels in test_loader:
        texts = texts.to(device)
        labels = labels.to(device)
        outputs = model(texts)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    accuracy = correct / total
    print(f'Accuracy: {accuracy * 100:.2f}%')

# 保存模型
torch.save(model.state_dict(), 'model.ckpt')

# 预测函数
def predict(text, model, vocab, device):
    model.eval()
    tokens = tokenizer(text)
    token_ids = [vocab.get(token.text, vocab['<unk>']) for token in tokens]
    token_tensor = torch.tensor(token_ids, dtype=torch.long).unsqueeze(0).to(device)

    with torch.no_grad():
        output = model(token_tensor)
        _, predicted = torch.max(output.data, 1)
        return 'positive' if predicted.item() == 1 else 'negative'

# 示例使用
sample_text = "This movie was fantastic! I really enjoyed it."
prediction = predict(sample_text, model, vocab, device)
print(f'Prediction: {prediction}')

4、多层RNN

将许多RNN层堆叠,构成一个多层RNN网络。RNN每读取一个新的 x t \mathrm{x}_{\mathrm{t}} xt输就会生成状态向量 h t \mathrm{h}_{\mathrm{t}} ht作为当前时刻的输出和下一时刻的输入状态。 将T 个输入 x 0 ∼ x T \mathrm{x}_{0} \sim \mathrm{x}_{\mathrm{T}} x0xT 依次输入RNN,相应地会产生个输出。第一层RNN输出的T TT个状态向量可以作为第二层RNN的输入,第二层RNN拥有独立的参数,依次读取T个来自第一层RNN的状态向量,产生T个新的输出。第二层RNN输出的T个状态向量可以作为第三层RNN的输入,依此类推,构成一个多层RNN网络。
在这里插入图片描述

RNN自带层数和是否双向,只要把层数设置成你想要的层数就可以

class RNN(nn.Module):
    def __init__(self,vocab_size, embedding_dim, hidden_size, num_classes, num_layers,bidirectional):
        super(RNN, self).__init__()
        self.vocab_size = vocab_size
        self.embedding_dim = embedding_dim
        self.hidden_size = hidden_size
        self.num_classes = num_classes
        self.num_layers = num_layers
        
        self.embedding = nn.Embedding(self.vocab_size, embedding_dim, padding_idx=word2idx['<PAD>'])
        # 这里用了torch的embeding函数
        self.rnn = nn.RNN(input_size=self.embedding_dim, hidden_size=self.hidden_size,batch_first=True,num_layers=self.num_layers)
        # input_size:表示输入 xt 的特征维度,从embeding层的size
        # hidden_size:表示输出的特征维度
        # num_layers:表示网络的层数
        # nonlinearity:表示选用的非线性激活函数,默认是 ‘tanh’
        # bias:表示是否使用偏置,默认使用
        # batch_first:表示输入数据的形式,默认是 False,就是这样形式,(seq, batch, feature),也就是将序列长度放在第一位,batch 放在第二位
        # dropout:表示是否在输出层应用(随机丢掉一些特征,重要的调参)
        # bidirectional:表示是否使用双向的 rnn,默认是 False。
        
    def forward(self, x):
        batch_size, seq_len = x.shape
        h0 = torch.randn(self.num_layers, batch_size, self.hidden_size).to(device)
        #初始化一个h0,也即c0,在RNN中一个Cell输出的ht和Ct是相同的,而LSTM的一个cell输出的ht和Ct是不同的
        #维度[layers, batch, hidden_len]

        x = self.embedding(x)   # 这里用的是nn的embeding
        out,_ = self.rnn(x, h0)  # 输入x,h0是初始化的特征,
        output = self.fc(out[:,-1,:]).squeeze(0) #因为有max_seq_len个时态,所以取最后一个时态即-1层
        return output   

二、双向LSTM----Bi-LSTM

BiLSTM无非就是把cell变成了LSTM的基本单元,其他同理如上所示

需要修改的内容:

  1. 替换RNN层为LSTM层:将nn.RNN替换为nn.LSTM
  2. 设置双向LSTM:将LSTM层的bidirectional参数设置为True
  3. 修改隐藏状态的初始化:LSTM的隐藏状态包含两个张量(隐藏状态和细胞状态),因此需要初始化这两个张量。
  4. 处理双向LSTM的输出:双向LSTM的输出维度会加倍(因为有两个方向)

在这里插入图片描述

class RNN(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_size, num_classes, num_layers, bidirectional):
        super(RNN, self).__init__()
        self.vocab_size = vocab_size
        self.embedding_dim = embedding_dim
        self.hidden_size = hidden_size
        self.num_classes = num_classes
        self.num_layers = num_layers
        self.bidirectional = bidirectional
        self.num_directions = 2 if bidirectional else 1
        
        self.embedding = nn.Embedding(self.vocab_size, embedding_dim, padding_idx=word2idx['<PAD>'])
        
        self.lstm = nn.LSTM(input_size=self.embedding_dim, 
                            hidden_size=self.hidden_size, 
                            num_layers=self.num_layers, 
                            bidirectional=self.bidirectional, 
                            batch_first=True)#替换了原来的nn.RNN层,使其变为LSTM,并添加了双向参数
        
        # 全连接层的输入大小需要考虑双向LSTM的输出维度
        self.fc = nn.Linear(self.hidden_size * self.num_directions, self.num_classes)
    
    def forward(self, x):
        batch_size, seq_len = x.shape
        # 初始化隐藏状态和细胞状态,双向LSTM需要初始化2*num_layers的hidden states
        h0 = torch.zeros(self.num_layers * self.num_directions, batch_size, self.hidden_size).to(device)
        c0 = torch.zeros(self.num_layers * self.num_directions, batch_size, self.hidden_size).to(device)
        
        x = self.embedding(x)  # Embedding layer
        
        # LSTM layer
        out, (hn, cn) = self.lstm(x, (h0, c0))
        
        # 取最后一个时间步的输出,双向LSTM会拼接两个方向的输出
        output = self.fc(out[:, -1, :])
        
        return output

三、两者异同

双向RNN(Bidirectional Recurrent Neural Network)和双向LSTM(Bidirectional Long Short-Term Memory)都是用于处理序列数据的神经网络模型。它们在处理时间序列、自然语言处理等任务中非常有用,因为它们能够考虑到序列中的前后信息。尽管它们有一些相似之处,但也有一些关键的不同点。

1、相同点

  1. 双向结构:无论是双向RNN还是双向LSTM,它们都有双向结构,这意味着它们有两个隐藏层,一个从前向后处理序列,另一个从后向前处理序列。这种结构允许模型在每个时间步上同时考虑前面和后面的信息,从而提高预测性能。

  2. 序列处理:两者都是为序列数据设计的,适用于自然语言处理、时间序列预测等任务。

  3. 隐层状态的结合:在每个时间步,它们都会结合来自两个方向的隐藏状态(通常是通过连接或求和)来产生输出。

2、不同点

  1. 基本单元

    • 双向RNN:基本单元是RNN,即简单的循环神经网络。它们依赖于隐藏状态将信息从一个时间步传播到下一个时间步。然而,RNN在处理长序列时容易遇到梯度消失和梯度爆炸问题,这限制了它们捕捉长距离依赖的能力。
    • 双向LSTM:基本单元是LSTM,即长短期记忆网络。LSTM通过引入遗忘门、输入门和输出门来控制信息的流动,从而更好地解决了梯度消失和梯度爆炸问题。因此,LSTM在处理长序列时比普通RNN更有效。
  2. 记忆能力

    • 双向RNN:由于其结构的限制,普通RNN在处理长期依赖关系时表现不佳。它们更适合短期依赖任务。
    • 双向LSTM:LSTM单元通过其门控机制能够有效地捕捉和保持长期依赖信息,因此在需要长时间记忆的任务中表现更优。
  3. 复杂性和计算成本

    • 双向RNN:结构相对简单,计算成本较低。但由于其局限性,可能需要更多层次的堆叠或者更复杂的架构来提升性能。
    • 双向LSTM:由于引入了门机制,LSTM单元比RNN单元复杂,计算成本也更高。但其增强的记忆能力通常能带来更好的性能。

参考https://zhuanlan.zhihu.com/p/519965073

https://fancyerii.github.io/books/rnn-intro/

https://www.cnblogs.com/Lee-yl/p/10066531.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Audio Hijack for Mac 激活版:音频录制与处理软件

Audio Hijack for Mac&#xff0c;让您的音频创作更加高效、便捷。它支持多种音频格式的录制和导出&#xff0c;包括MP3、AAC、WAV等&#xff0c;让您的音频作品具有更广泛的兼容性。同时&#xff0c;软件界面简洁明了&#xff0c;操作流畅自然&#xff0c;即使您是初学者也能快…

EasyCVR智慧校园建设中的关键技术:视频汇聚智能管理系统应用

一、引言 随着信息技术的迅猛发展&#xff0c;智慧校园作为教育信息化建设的重要组成部分&#xff0c;对于提升校园安全、教学效率和管理水平具有重要意义。本文旨在介绍智慧校园视频管理系统的架构设计&#xff0c;为构建高效、智能的校园视频监控系统提供参考。 二、系统整…

【嵌入式开发】Arduino人机界面及接口技术:独立按键接口,矩阵按键接口,模拟量按键接口(基础知识介绍)

“生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方。” 🎯作者主页: 追光者♂🔥 🌸个人简介: 📝[1] CSDN 博客专家📝 🏆[2] 人工智能领域优质创作者🏆 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🌿[4] …

PCIE协议-2-事务层规范-Virtual Channel (VC) Mechanism

2.5 虚拟通道&#xff08;VC&#xff09;机制 虚拟通道&#xff08;VC&#xff09;机制提供了对可以在整个结构中传输使用TC&#xff08;流量类别&#xff09;标签区分的流量的支持。VC的基础是独立的结构资源&#xff08;队列/缓冲区及其相关的控制逻辑&#xff09;。这些资源…

遥感数据集制作(Potsdam数据集为例):TIF图像转JPG,TIF标签转PNG,图像重叠裁剪

文章目录 TIF图像转JPGTIF标签转PNG图像重叠裁剪图像重命名数据集转COCO格式数据集转VOC格式 遥感图像不同于一般的自然图像&#xff0c;由于波段数量、图像位深度等原因&#xff0c;TIF图像数据不能使用简单的格式转换方法。本文以Potsdam数据集为例&#xff0c;制作能够直接用…

信创电脑|暴雨新增兆芯KX-7000处理器版本

IT世界 5 月 15 日消息&#xff0c;暴雨公司信创家族新上架了一款搭载兆芯KX-7000系列处理器、摩尔线程8GB 显卡、16G DDR5 内存以及 512G SSD 的新配置台式电脑主机。 兆芯 KX-7000 处理器采用开先的 8 核 Chiplet互联架构&#xff0c;最高频率3.7 GHz&#xff0c;拥有 32MB 的…

2024最新软件测试【测试理论+ 接口测试】面试题(内附答案)

一、测试理论 3.1 你们原来项目的测试流程是怎么样的? 我们的测试流程主要有三个阶段&#xff1a;需求了解分析、测试准备、测试执行。 1、需求了解分析阶段 我们的 SE 会把需求文档给我们自己先去了解一到两天这样&#xff0c;之后我们会有一个需求澄清会议&#xff0c; …

干什么副业好呢?

选择适合自己的副业可以根据个人的兴趣、技能和时间来决定。以下是一些常见的副业选择 1. 在线销售 可以在电商平台上开设自己的网店&#xff0c;销售自己感兴趣的产品&#xff0c;如手工艺品、服装、配饰等。 2. 做任务 网上我还在做的致米宝库&#xff0c;一个月有个一千多…

shiro_attack工具-shiro反序列化漏洞的快速检测和利用

shiro反序列化漏洞的快速检测和利用 前言 今天分享一个好用的渗透测试工具&#xff0c;主要是针对shiro框架漏洞的&#xff0c;它可以自动的爆破shiro密钥&#xff0c;同时可以写入大马&#xff0c;本人实战中觉得很好用&#xff01;&#xff01;&#xff01; 工具名称 shi…

自学VBA 设置单元格文字格式 笔记

一.设定对应单元格对应需要显示的格式 Cells(1, 1).Font.Size 18 字体大小 Cells(1, 2).Font.Color RGB(255, 0, 0) 字体颜色 Cells(1, 3).Font.Name "黑体" 字体类型 Cells(1, 4).Font.Italic True 字体斜体 Cells(1, 5).Font.FontStyle "BOLD"…

哈夫曼编码的应用

数据结构与算法课的一个简单实验&#xff0c;记录一下&#xff0c;以供参考。 文章目录 要求测试样例统计字母出现次数建立哈夫曼树对字符编码对原文进行编码译码 要求 输入一段100—200字的英文短文&#xff0c;存入一文件a中。统计短文出现的字母个数n及每个字母的出现次数…

stm32ADC注入通道使用笔记(以STM32F407 为例)

ADC_JDR1 存放的是第一次转换的数据 ADC_JDR2 存放的是第二次转换的数据 ADC_JDR3 存放的是第三次转换的数据 ADC_JDR4 存放的是第四次转换的数据 1.当 JL 0&#xff08;定序器中有 1 次注入转换&#xff09;时&#xff0c;ADC 将仅转换 JSQ4[4:0] 通道。值存入ADC_JDR1中…

表现层设计模式_1.MVC模式

1.MVC模式三个核心模块 MVC是一种目前广泛流行的软件设计模式。近年来&#xff0c;随着Java EE的成熟&#xff0c;MVC成为了Java EE平台上推荐的一种设计模式。MVC强制性地把一个应用的输入、处理、输出流程按照视图、控制、模型的方式进行分离&#xff0c;形成了控制器…

战网国际服加速器哪个好用 暴雪战网免费加速器分享

战网国际服&#xff08;Battle.net International或Battle.net Global&#xff09;是由暴雪娱乐公司&#xff08;Blizzard Entertainment&#xff09;运营的面向全球玩家的多人在线游戏平台。与专注于特定地区的版本不同&#xff0c;国际服允许玩家不受地域限制地访问暴雪的多款…

1:硬件测试面试

1&#xff1a;板级测试 . JTAG和Boundary Scan 对于硬件板级测试&#xff0c;我使⽤JTAG和Boundary Scan技术进⾏⾃动化测试。这些技术可以帮助我访问PCB 上的芯⽚引脚&#xff0c;从⽽进⾏信号测量、连通性测试和故障诊断。 2&#xff1a;整机测试 3&#xff1a;测试准备 4…

第189题|幂级数的展开的常规方法(二)|武忠祥老师每日一题

解题思路&#xff1a;将函数展开成幂级数有两种方法&#xff1a;一种是直接法&#xff08;这种一般比较麻烦&#xff09;&#xff0c;一种是拆解成现有展开式展开&#xff08;这种的特征一般是能因式分解&#xff09;。 第一步&#xff1a; 这里看到 ln(1-x-2x^2) 将里面的式…

【图神经网络——消息传递】

消息传递机制 画图先&#xff1a;导包&#xff1a;画图&#xff1a; 实现消息传递&#xff1a;例子一&#xff1a;例子二&#xff1a; 画图先&#xff1a; 导包&#xff1a; import networkx as nx import matplotlib.pyplot as plt import torch from torch_geometric.nn im…

蛋白聚乙二醇化修饰检测试剂盒

蛋白多肽因其高生物活性、高特异性等优点备受药物开发商和研究者的青睐。但分子量大、亲水性强、稳定性差等劣势限制了蛋白多肽在临床上的应用&#xff0c;特别是蛋白多肽作为一种异源蛋白具有很强的免疫原性&#xff0c;容易被机体免疫系统识别并清除&#xff0c;导致药物的血…

动态规划-两个数组的dp问题3

文章目录 1. 两个字符串的最小ASCII删除和&#xff08;712&#xff09;2. 最长重复子数组&#xff08;718&#xff09; 1. 两个字符串的最小ASCII删除和&#xff08;712&#xff09; 题目描述&#xff1a; 状态表示&#xff1a; 根据经验以及题目要求&#xff0c;建立二维数…

zabbix触发器配置定期生效教程

在企业生产过程中&#xff0c;并非所有的设备都需要全天候、满负载运转&#xff0c;也有些仅需要周期性的运转即可。例如&#xff0c;在某家企业&#xff0c;有一批这样的机器&#xff0c;每天都会在固定的时间跑批量任务&#xff0c;期间&#xff0c;机器的CPU使用率会有明显的…