【NLP】自然语言处理的序列建模

news/2024/4/30 1:40:07/文章来源:https://blog.csdn.net/sikh_0529/article/details/127022632

   🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎

📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​

📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】  深度学习【DL】

 🖍foreword

✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。

如果你对这个系列感兴趣的话,可以关注订阅哟👋

一个序列是项目的有序集合。传统机器学习假设数据点是独立同分布 (IID),但在许多情况下,例如语言、语音和时间序列数据,一个数据项依赖于它之前或之后的项。此类数据也称为序列数据。顺序信息在人类语言中无处不在。例如,语音可以被认为是一系列基本单位,称为音素。在像英语这样的语言中,句子中的单词不是随意的。它们可能会受到它们之前或之后的单词的限制。例如,在英语中,介词“of”后面可能跟冠词“the”;例如,“狮子是丛林之王。” 再举一个例子,在包括英语在内的许多语言中,动词的数量必须与句子中主语的数量一致。这是一个例子:

The book is on the table
The books are on the table.

有时这些依赖关系或约束可以任意长。例如:

The book that I got yesterday is on the table.
The books read by the second-grade children are shelved in the lower rack.

简而言之,理解序列对于理解人类语言至关重要。在前面的章节中,向您介绍了前馈神经网络,如多层感知器和卷积神经网络,以及向量表示的强大功能。尽管使用这些技术可以处理范围广泛的自然语言处理任务,正如我们将在本章和接下来的两章中学习的那样,它们并不能充分模拟序列。1

在 NLP 中使用传统方法对序列进行建模隐马尔可夫模型、条件随机场和其他类型的概率图模型虽然没有在本书中讨论,但仍然是相关的。

深度学习,建模序列涉及维护隐藏的“状态信息”,或隐藏状态。当遇到序列中的每个项目时——例如,当模型看到句子中的每个单词时——隐藏状态就会更新。因此,隐藏状态(通常是一个向量)封装了到目前为止序列所看到的所有内容。3这个隐藏状态向量,也称为序列表示,然后可以根据我们正在解决的任务以多种方式用于许多序列建模任务,从分类序列到预测序列。本章我们研究序列数据的分类,但第 7 章介绍如何使用序列模型生成序列。

我们首先介绍最基本的神经网络序列模型:循环神经网络(RNN)。在此之后,我们在分类设置中展示了 RNN 的端到端示例。具体来说,您将看到如何使用基于字符的 RNN 将姓氏分类到各自的国籍。姓氏示例表明序列模型可以捕获语言中的正字法(子词)模式。此示例的开发方式使读者能够将模型应用于其他情况,包括对数据项是单词而不是字符的文本序列进行建模。

递归神经网络简介

递归神经网络的目的是对张量序列进行建模。4 RNN 与前馈网络一样,是一系列模型。RNN 家族中有几个不同的成员,但在本章中,我们只使用最基本的形式,有时称为埃尔曼循环神经网络5循环网络的目标——基本的 Elman 形式和第 7 章中概述的更复杂的形式——是学习序列的表示。这是通过维护一个隐藏的捕获序列当前状态的状态向量。隐藏状态向量是根据当前输入向量和先前的隐藏状态向量计算的。这些关系如图 6-1所示,它显示了计算依赖项的功能(左)和“展开”(右)视图。在这两个插图中,输出与隐藏向量相同。情况并非总是如此,但在 Elman RNN 的情况下,隐藏向量就是预测的内容。

图 6-1。Elman RNN(左)的功能视图将循环关系显示为隐藏向量上的反馈循环。“展开”视图(右)清楚地显示了计算关系;每个时间步的隐藏向量取决于该时间步的输入和前一个时间步的隐藏向量。

让我们看一个稍微更具体的描述,以了解 Elman RNN 中发生了什么。如图 6-1的展开视图所示,也称为通过时间反向传播(BPTT),来自当前时间步的输入向量和来自前一个时间步的隐藏状态向量被映射到当前时间步的隐藏状态向量。在图 6-2中更详细地显示了一个新的隐藏向量,它使用一个隐藏到隐藏的权重矩阵来映射先前的隐藏状态向量,并使用一个输入到隐藏的权重矩阵来映射输入向量。

图 6-2。Elman RNN 内部的显式计算显示为两个量的相加:前一个时间步的隐藏向量与隐藏到隐藏权重矩阵之间的点积,以及输入向量与输入到隐藏权重矩阵的点积。 -隐藏的权重矩阵。

至关重要的是,隐藏到隐藏和输入到隐藏的权重在不同的时间步长之间共享。您应该从这个事实中得到的直觉是,在训练期间,这些权重将被调整,以便 RNN 学习如何合并输入信息并维护一个状态表示来总结迄今为止看到的输入。RNN 无法知道它在哪个时间步上。相反,它只是简单地学习如何从一个时间步转换到另一个时间步,并保持一种状态表示,以使其损失函数最小化。

在每个时间步使用相同的权重将输入转换为输出是参数共享的另一个例子。在第 4 章中,我们看到了 CNN 如何跨空间共享参数。CNN 使用参数,称为kernels,计算输入数据中子区域的输出。卷积核在输入中移动,从每个可能的位置计算输出,以学习平移不变性。相比之下,RNN 使用相同的参数在每个时间步计算输出,依靠隐藏状态向量来捕获序列的状态。通过这种方式,RNN 的目标是通过能够计算给定隐藏状态向量和输入向量的任何输出来学习序列不变性。你可以想象一个 RNN 跨时间共享参数,一个 CNN 跨空间共享参数。

因为单词和句子可以有不同的长度,所以应该配备 RNN 或任何序列模型来处理变长序列。一种可能的技术是人为地将序列限制为固定长度。在本书中,我们使用了另一种技术,称为masking,通过利用序列长度的知识来处理可变长度序列。简而言之,屏蔽允许数据在某些输入不应计入梯度或最终输出时发出信号。PyTorch 提供了用于处理可变长度序列的原语,称为 PackedSequences 从这些不太密集的张量中创建密集的张量。“示例:使用字符 RNN 对姓氏国籍进行分类”说明了一个这方面的例子。6

实现 Elman RNN

探索 RNN 的细节,让我们逐步了解 Elman RNN 的简单实现。PyTorch 提供了许多有用的类和辅助函数来构建 RNN。PyTorchRNN类实现了 Elman RNN。本章不直接使用这个类,而是使用 RNNCell,对 RNN 的单个时间步长的抽象,并从中构造一个 RNN。我们这样做的目的是明确地向您展示 RNN 计算。示例 6-1中所示的类ElmanRNN用于RNNCell创建前面描述的输入到隐藏和隐藏到隐藏的权重矩阵。每次调用都RNNCell()接受一个输入向量矩阵和一个隐藏向量矩阵。它返回由一步产生的隐藏向量矩阵。

示例 6-1。使用 PyTorch 的 RNNCell 实现 Elman RNN

class ElmanRNN(nn.Module):""" 使用 RNNCell 构建的 Elman RNN"""def __init__(self, input_size, hidden_size, batch_first=False):"""参数:input_size (int): 输入向量的大小hidden_​​size (int): 隐藏状态向量的大小batch_first (bool): 第0维是否为batch"""super(ElmanRNN, self).__init__()self.rnn_cell = nn.RNNCell(input_size, hidden_size)self.batch_first = batch_firstself.hidden_size = hidden_sizedef _initialize_hidden(self, batch_size):return torch.zeros((batch_size, self.hidden_size))def forward(self, x_in, initial_hidden=None):"""ElmanRNN的前向传递参数:x_in(torch.Tensor):输入数据张量。如果self.batch_first:x_in.shape = (batch_size, seq_size, feat_size ) Else: x_in.shape = (seq_size, batch_size, feat_size) initial_hidden (torch.Tensor): RNN 的初始隐藏状态Returns: hiddens (torch.Tensor): RNN 在每个时间步的输出。如果是 self。 batch_first: hiddens.shape = (batch_size, seq_size, hidden_​​size)否则: hiddens.shape = (seq_size, batch_size, hidden_​​size) """if self.batch_first:batch_size, seq_size, feat_size = x_in.size()x_in = x_in.permute(1, 0, 2)else:seq_size, batch_size, feat_size = x_in.size()hiddens = []if initial_hidden is None:initial_hidden = self._initialize_hidden(batch_size)initial_hidden = initial_hidden.to(x_in.device)hidden_t = initial_hiddenfor t in range(seq_size):hidden_t = self.rnn_cell(x_in[t], hidden_t)hiddens.append(hidden_t)hiddens = torch.stack(hiddens)if self.batch_first:hiddens = hiddens.permute(1, 0, 2)return hiddens

除了控制输入和隐藏大小RNN 中的超参数,有一个布尔参数用于指定维度是否在0第 th 维度上。此标志也存在于所有 PyTorch RNN 实现中。当设置为True时,RNN 交换输入张量上的0th 和1st 维度。

ElmanRNN课堂上, forward()方法循环输入张量以计算每个时间步的隐藏状态向量。请注意,有一个用于指定初始隐藏状态的选项,但如果未提供,0则使用所有 s 的默认隐藏状态向量。当ElmanRNN类在输入向量的长度上循环时,它会计算一个新的隐藏状态。这些隐藏状态被聚合并最终堆叠。7在他们归还之前, batch_first再次检查标志。如果是True,则对输出隐藏向量进行置换,以使批次再次位于0第 th 维上。

该类的输出是一个三维张量——在批次维度和每个时间步长上的每个数据点都有一个隐藏状态向量。您可以根据手头的任务以几种不同的方式使用这些隐藏向量。您可以使用它们的一种方法是将每个时间步分类为一些离散的选项集。这种方法意味着将调整 RNN 权重以跟踪与每个时间步的预测相关的信息。此外,您可以使用最终向量对整个序列进行分类。这意味着将调整 RNN 权重以跟踪对最终分类重要的信息。在本章中,我们只看到分类设置,但在接下来的两章中,我们将更仔细地研究逐步预测。

示例:使用字符 RNN 对姓氏国籍进行分类

现在我们已经概述了 RNN 的基本属性并逐步完成了 RNN 的实现ElmanRNN,让我们将其应用到任务中。我们将考虑的任务是第 4 章中的姓氏分类任务,其中字符序列(姓氏)被分类为原籍国。

SurnameDataset 类

本例中的数据集是 surnames 数据集,之前已在第 4 章中介绍过。每个数据点由一个姓氏和相应的国籍表示。我们将避免重复数据集的详细信息,但您应该参考“姓氏数据集”进行复习。

在此示例中,就像在“示例:使用 CNN 对姓氏进行分类”中一样,我们将每个姓氏视为一个字符序列。像往常一样,我们实现了一个数据集类,如例 6-2所示,它返回向量化的姓氏以及表示其国籍的整数。另外返回的是序列的长度,用于下游计算以了解序列中最终向量的位置。这是在实际训练开始之前熟悉的一系列步骤(实施Dataset、 aVectorizer和 a )的一部分。Vocabulary

示例 6-2。实现 SurnameDataset 类

class SurnameDataset(Dataset):        @classmethoddef load_dataset_and_make_vectorizer(cls, surname_csv):"""加载数据集并从头开始制作一个新的矢量化器参数: surname_csv (str): 数据集的位置返回:SurnameDataset 的一个实例"""surname_df = pd.read_csv(surname_csv)train_surname_df = surname_df[surname_df.split=='train']return cls(surname_df, SurnameVectorizer.from_dataframe(train_surname_df))def __getitem__(self, index):"""PyTorch 数据集的主要入口点方法参数:index (int):数据点的索引返回:保存数据点的字典:特征 (x_data)标签 (y_target)特征长度 (x_length)"""row = self._target_df.iloc[index]surname_vector, vec_length = \self._vectorizer.vectorize(row.surname, self._max_seq_length)nationality_index = \self._vectorizer.nationality_vocab.lookup_token(row.nationality)return {'x_data': surname_vector, 'y_target': nationality_index, 'x_length': vec_length}

矢量化数据结构

矢量化管道的第一阶段是将姓氏中的每个字符标记映射到一个唯一的整数。为此,我们使用 SequenceVocabulary数据结构,我们在“Example: Transfer Learning Using Pretrained Embeddings for Document Classification”中首次介绍和描述。回想一下,这种数据结构不仅将名称中的字符映射为整数,而且还利用了四种特殊用途的标记:UNK标记、MASK标记、BEGIN-OF-SEQUENCE标记和END-OF-SEQUENCE标记。前两个标记对于语言数据至关重要:UNK标记用于输入中看不见的词汇表外标记,并且MASK标记可以处理可变长度输入。后两个标记为模型提供句子边界特征,并分别添加到序列中。我们向您推荐“词汇、矢量化器和数据加载器”有关SequenceVocabulary.

整个矢量化过程由 SurnameVectorizer,它使用 aSequenceVocabulary来管理姓氏和整数中的字符之间的映射。例 6-3展示了它的实现,看起来应该很熟悉;在上一章中,我们研究了将新闻文章的标题分类到特定类别,矢量化管道几乎相同。

示例 6-3。姓氏矢量化器.

class SurnameVectorizer(object):""" 协调词汇并使用它们的 Vectorizer"""   def vectorize(self, surname, vector_length=-1):"""参数: title (str): 字符串vector_length (int): 强制索引向量长度的参数"""indices = [self.char_vocab.begin_seq_index]indices.extend(self.char_vocab.lookup_token(token) for token in surname)indices.append(self.char_vocab.end_seq_index)if vector_length < 0:vector_length = len(indices)out_vector = np.zeros(vector_length, dtype=np.int64)out_vector[:len(indices)] = indicesout_vector[len(indices):] = self.char_vocab.mask_indexreturn out_vector, len(indices)@classmethoddef from_dataframe(cls, surname_df):"""从数据集数据帧实例化矢量化器参数: surname_df (pandas.DataFrame): 姓氏数据集返回:SurnameVectorizer 的实例"""char_vocab = SequenceVocabulary()nationality_vocab = Vocabulary()for index, row in surname_df.iterrows():for char in row.surname:char_vocab.add_token(char)nationality_vocab.add_token(row.nationality)return cls(char_vocab, nationality_vocab)

姓氏分类模型

SurnameClassifier型号_由 Embedding 层、ElmanRNNLinear层组成。我们假设模型的输入是表示为一组整数的标记,在它们被映射到整数之后SequenceVocabulary。该模型首先使用嵌入层嵌入整数。然后,使用 RNN 计算序列表示向量。这些向量代表姓氏中每个字符的隐藏状态。因为目标是对每个姓氏进行分类,所以提取每个姓氏中最终字符位置对应的向量。考虑这个向量的一种方法是,最终向量是传递整个序列输入的结果,因此它是姓氏的摘要向量。这些汇总向量通过Linear层来计算预测向量。预测向量用于训练损失,或者我们可以应用 softmax 函数来创建一个姓氏的概率分布。8

该模型的参数是嵌入的大小、嵌入的数量(即词汇大小)、类的数量和 RNN 的隐藏状态大小。其中两个参数——嵌入的数量和类的数量——由数据决定。剩余的超参数是嵌入的大小和隐藏状态的大小。尽管这些可以取任何值,但通常最好从可以快速训练以验证模型是否有效的小东西开始。

示例 6-4。使用 Elman RNN 实现 SurnameClassifier 模型

class SurnameClassifier(nn.Module):""" 用于提取特征的 RNN 和用于分类的 MLP"""def __init__(self, embedding_size, num_embeddings, num_classes,rnn_hidden_size, batch_first=True, padding_idx=0):"""参数 : embedding_size (int): 字符嵌入的大小num_embeddings (int): 要嵌入的字符数num_classes (int): 预测向量的大小注:国籍数量rnn_hidden_​​size (int): RNN的大小hidden state batch_first (bool): 告知输入张量是否会在第 0 维有批次或序列padding_idx (int):张量填充的索引;参见 torch.nn.Embedding """super(SurnameClassifier, self).__init__()self.emb = nn.Embedding(num_embeddings=num_embeddings,embedding_dim=embedding_size,padding_idx=padding_idx)self.rnn = ElmanRNN(input_size=embedding_size,hidden_size=rnn_hidden_size,batch_first=batch_first)self.fc1 = nn.Linear(in_features=rnn_hidden_size,out_features=rnn_hidden_size)self.fc2 = nn.Linear(in_features=rnn_hidden_size,out_features=num_classes)def forward(self, x_in, x_lengths=None, apply_softmax=False):"""分类器的前向传递参数: x_in (torch .Tensor): 一个输入数据张量x_in.shape 应该是 (batch, input_dim) x_lengths (torch.Tensor):用于找到每个序列的最终向量的batch中每个序列的长度apply_softmax (bool): 一个标志如果与交叉熵损失一起使用,softmax 激活应该是错误的返回:out (torch.Tensor); `out.shape = (batch, num_classes)` """x_embedded = self.emb(x_in)y_out = self.rnn(x_embedded)if x_lengths is not None:y_out = column_gather(y_out, x_lengths)else:y_out = y_out[:, -1, :]y_out = F.dropout(y_out, 0.5)y_out = F.relu(self.fc1(y_out))y_out = F.dropout(y_out, 0.5)y_out = self.fc2(y_out)if apply_softmax:y_out = F.softmax(y_out, dim=1)return y_out

您会注意到该forward()函数需要序列的长度。长度用于检索从 RNN 返回的张量中每个序列的最终向量,该函数名为 column_gather(),如例 6-5所示。该函数迭代批处理行索引并检索位于相应序列长度指示的位置的向量。

示例 6-5。使用 column_gather() 检索每个序列中的最终输出向量

def column_gather(y_out, x_lengths):"""从`y_out`中的每个batch数据点获取一个特定的向量。参数: y_out (torch.FloatTensor, torch.cuda.FloatTensor) shape: (batch, sequence, feature) x_lengths ( torch.LongTensor, torch.cuda.LongTensor)形状: (batch,)返回: y_out (torch.FloatTensor, torch.cuda.FloatTensor)形状: (batch, feature) """x_lengths = x_lengths.long().detach().cpu().numpy() - 1out = []for batch_index, column_index in enumerate(x_lengths):out.append(y_out[batch_index, column_index])return torch.stack(out)

训练程序和结果

训练程序遵循标准公式。对于单批数据,应用模型并计算预测向量。使用 CrossEntropyLoss()函数和基本事实来计算损失值。使用损失值和优化器,计算梯度并使用这些梯度更新模型的权重。对训练数据中的每个批次重复此操作。对验证数据进行类似处理,但将模型设置为 eval 模式以防止反向传播。相反,验证数据仅用于对模型的执行情况提供较少偏见的感觉。对特定数量的时期重复此例程。代码见补充材料。我们鼓励您使用超参数来了解影响性能的因素和影响程度,并将结果制成表格。我们还将为此任务编写合适的基线模型作为练习供您完成。9实施的模型“姓氏分类模型”是通用的,不限于字符。模型中的嵌入层可以映射离散项序列中的任何离散项;例如,一个句子是一个单词序列。我们鼓励您在其他序列分类任务中使用示例 6-6中的代码,例如句子分类。

示例 6-6。基于 RNN 的 SurnameClassifier 的参数

args = Namespace(# 数据和路径信息surname_csv="data/surnames/surnames_with_splits.csv",vectorizer_file="vectorizer.json",model_state_file="model.pth",save_dir="model_storage/ch6/surname_classification",# 模型超参数char_embedding_size=100,rnn_hidden_size=64,# 训练超参数num_epochs=100,learning_rate=1e-3,batch_size=64,seed=1337,early_stopping_criteria=5,# 运行时选项省略
)

概括

在本章中,我们介绍了使用循环神经网络对序列数据进行建模,并研究了一种最简单的循环网络,称为 Elman RNN。我们确定序列建模的目标是学习序列的表示(即向量)。这种学习的表示可以根据任务以不同的方式使用。我们考虑了一个示例任务,该任务涉及将此隐藏状态表示分类到许多类之一。姓氏分类任务展示了一个使用 RNN 在子词级别捕获信息的示例。

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

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

相关文章

Teams Bot App 初探

上一篇文章深入讲了incoming webhook。这篇文章我们来看一个稍微复杂点的&#xff0c;正式点的 teams app&#xff1a;bot。 我们先来和之前一样&#xff0c;通过teams toolkit 的 sample gallery来创建一个 Teams bot app。 创建之后我们先来看一下目录结构和生成的文件。 一…

二叉树中求最大路径和

题目来自LeetCode中&#xff0c;链接为124. 二叉树中的最大路径和 一棵树的最大路径和可能存在于哪里&#xff1a; 单纯的存在于以左子树为根节点的子树中单纯的存在于以右子树为根节点的子树中根节点到达左子树B中某节点的路径根节点到达右子树C中某节点的路径左子树中某节…

Android日志分析02-am篇

Android日志分析02-am篇 在日常分析bug时&#xff0c;免不了和系统ActivityManagerService打交道&#xff0c;根据日志去查看各个Activity的生命周期&#xff0c;从而判断是否出现Activity生命周期异常。 先使用adb logcat和adb bugreport再pixel2的模拟器抓取一份从开机到打开…

代码随想录4——链表: 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07链表相交、142.环形链表II

文章目录1.24两两交换链表中的节点1.1.题目1.2.思路1.3.代码实现1.3.1.对next指针的理解1.3.2.编程中要备份哪些节点的指针&#xff1f;1.3.3.代码实现2.19删除链表的倒数第N个节点2.1.题目2.2.思路3.面试题02.07链表相交3.1.题目3.2.解答4.142.环形链表II4.1.题目4.2.思路1.24…

JavaEE——No.1 多线程案例

JavaEE传送门JavaEE JavaEE——No.1 线程安全问题 JavaEE——No.2 线程安全问题 目录多线程案例1. 单例模式饿汉模式懒汉模式2. 阻塞队列阻塞队列的使用阻塞队列的实现多线程案例 1. 单例模式 单例模式是一种常见的设计模式. 设计模式: 软件开发时, 会遇到一些常见的 “问…

存储系统基本概念

内容框图 存储器的层次化结构 由于cpu运行太快&#xff0c;所以中间需要主存&#xff0c;Cache&#xff0c;寄存器去传递。 主存–辅存&#xff08;硬件操作系统&#xff09;&#xff1a;实现虚拟存贮系统&#xff0c;解决了主存容量不够的问题。 Cache–主存&#xff08;硬件自…

测试用例设计专栏

哈喽大家好哎呀&#xff0c;今天给大家普及一下测试用例如何设计&#xff0c;看牛逼的大佬们是如何测试的。 测试用例笔试题 出题&#xff1a;在一个页面上有一个输入框&#xff0c;一个计数器(count)按钮&#xff0c;用于计算一个文本字符串中字母a出现的次数&#xff0c;请…

Linux 逻辑卷精简卷报错问题解决

一、 故障描述 现象1:oraclelog目录提示坏道信息,进行修复后执行删除文件操作,目录不可使用。 现象2:lsblk看到目录出现重复,并且有tmeta,tdata卷出现(图一) 现象3:message日志出现多目录报错,持续写入(图二) 图一 检查lv #lvs -a 看到多出的pmspare,tdata,tmeta…

VSCode 使用教程-9.Node运行js出现 Cannot use import statement outside a module的问题

前言 js中导入公共模块&#xff0c;使用import的方式导入&#xff0c;用node运行js文件会出现Cannot use import statement outside a module的问题 问题描述 目录结构 └─src└─js└─ext.js└─main.js └─index.html在ext.js 文件写一些公共方法 export const m (f…

vue3 ts vite 项目快速构建

1.安装nodejs(建议装14版本稳定) 下载 | Node.js 中文网 装完之后会有一个命令叫 npm 可以在终端输入npm -v 来检查是否安装成功2.构建vite项目官方文档开始 {#getting-started} | Vite中文网 vite 的优势冷服务 默认的构建目标浏览器是能 在 script 标签上支持原生 ESM 和…

Java操作HDFS

1. 创建maven项目 New Project 2. 添加依赖 <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.…

steam搬砖汇率差项目详解

很久没有分享赚钱项目了&#xff0c;今天这里给大家介绍一个游戏搬砖的项目&#xff1a;steam游戏汇率差赚钱项目。 项目原理&#xff1a; Steam平台是一个国外游戏及装备售卖平台。而我们所谓的Steam游戏装备搬砖就是利用steam平台和网易的BUFF平台来操作。steam汇率差赚钱原…

十大经典排序算法综述(Java代码实现,思想通用)

关于十大排序的文章也有不少了&#xff0c;但感觉大部分在各个排序算法的适用场景、如何实现外排等细节方面没怎么讲&#xff0c;故总结了这篇文章&#xff0c;欢迎浏览 一、前言 内部排序是指排序时将待排序数据全部加载到内存的算法。 外部排序是指在处理海量数据排序时&…

什么是C语言?

什么是C语言&#xff1f; 文章目录什么是C语言&#xff1f;1.C语言的起源2.C语言的使用领域3. 为什么要学习C语言4.C语言的学习境界5.如何学习C语言6.学习C语言的推荐书籍1.C语言的起源 C语言之父是丹尼斯里奇&#xff1a;丹尼斯里奇&#xff08;1941年9月9日-2011年10月12日&…

Linux 简单命令 - cron 计划任务 、NTP

Linux 简单命令 - cron NTP cronNTP 一、cron 计划任务就是按照系统的时间(时刻、周期)执行指定的任务 系统服务&#xff1a; crond。 配置文件&#xff1a; /etc/crontab /var/spool/cron/用户名 配置记录格式&#xff1a; 分 时 日 月 周 任务操作命令 (用绝对路径、必要时…

集成学习详解

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 目录 一、集成学习的产生原因与相关定义 1、产生原因 2、相关定义 &#xff08;1&#xff09;同质集成 &#xff08;2&#xf…

第三章 学校与班级管理

01 学校组织与管理 02 班级与班集体 03 班主任与班主任工作 04 班级活动与班队活动 05 课外活动 02 班级与班集体 一、班级与班集体 二、班级管理 三、班级突发事件的处理 一、班级与班集体 &#xff08;一&#xff09;班级 了解 年龄、知识程度相近&#xff0c;有共同的学…

python学习—第一步—Python小白逆袭大神(第二天)

python进阶python语法继续学习数据结构数字字符串列表元组字典面向对象继承JSON异常处理try except finallyLinux命令作业来啦&#xff01;问题python语法继续学习 数据结构 数字 Number类型用于存储数值。 1、数学运算math模块及常用函数 菜鸟教程 导入math 代码示例&#…

微信小程序事件和页面跳转

一、页面跳转 1.非TabBar页面 一个小程序拥有多个页面&#xff0c;我们通过wx.navigateTo进入一个新的页面 我们通过下边点击事件实现页面跳转进行代码实现及参考 wx.navigateBack&#xff08;&#xff09;回退到上一个页面 wx.redirectTo&#xff08;url&#xff09;删除…

最新AWVS14.9.220913107 支持Windows使用教程(附下载地址)

主要内容&#xff1a;awvs14.9下载、awvs14.9使用教程、awvs14.9安装教程、awvs14.9批量扫描、awvs14.9用法、awvs最新版下载 使用方法 一键PJ 一键PJ则只需要在安装Acunetix软件后&#xff0c;运行pj工具即可 通用思路 修改hosts文件&#xff08;C:\Windows\System32\driv…