一文了解Word2vec 阐述训练流程

一文了解Word2vec 阐述训练流程

  • 个性嵌入(Personality Embeddings)
  • 词嵌入(Word Embeddings)
    • 嵌入向量效果分析
  • 语言模型
    • 模型介绍
    • 模型训练
  • Word2vec训练方法
    • CBOW方法
    • Skip-gram方法
    • CBOW方法与Skip-gram方法总结
  • 重构训练方法
    • 负采样
    • 基于负采样的Skip-gram(SGNS)
  • Word2vec的最终训练方法
  • 附数百个中文Word2vec向量下载地址
  • Word2vec为什么不如BERT模型?

  在机器学习领域,嵌入(embeddings)的概念无疑是其中最令人兴奋的创新之一。想象一下,每当你与SiriGoogle AssistantAlexaGoogle Translate互动,甚至在使用具有下一个词预测功能的手机输入法(比如苹果输入法、搜狗输入法)时,你其实都在享受词嵌入模型带来的便利。这些技术在过去几十年里取得了巨大进步,尤其是近期基于上下文的词嵌入技术的发展,催生了BERTGPT2ChatGPT等领先的预训练模型。

  自2013年以来,Word2vec一直是创建词嵌入的有效方法。它不仅仅是一种词嵌入技术,还在推荐系统和商业非语言任务的理解方面显示出了惊人的效果。像Airbnb、阿里巴巴、SpotifyAnghami这些公司都已经开始利用这一NLP界的精妙技术,并将其应用到生产环境中,从而推动了新一代推荐引擎的发展。

  在本文中,我们不仅将深入探讨嵌入的概念,还会详细解析Word2vec用于生成嵌入的机制。但首先,让我们从一个简单的例子开始:理解如何使用向量来表示事物。你可能不会相信,但一个由五个数字组成的列表(即一个向量)实际上可以代表一个人的个性。

个性嵌入(Personality Embeddings)

  让我们以一个简单的例子来开始:评估一个人的内向或外向程度。 用0到100分来衡量,其中0代表极度内向,而100则意味着极度外向。你可能听说过MBTI或五大性格特征测试,这些测试通过一系列问题,为你的性格的不同方面打分,其中内向/外向只是众多方面中的一个。

请添加图片描述
  想象一下,如果我的内向/外向得分是38/100,我们可以如下图所示表示这一得分:

请添加图片描述
  让我们将范围从-1切换到1:

请添加图片描述
  但是,仅仅一个维度的信息并不足以全面了解一个人。人类性格的复杂性远不止于此。因此,我们增加更多维度,比如测试中的其他特征分数。

请添加图片描述

  尽管我暂时隐藏了我们正在绘制的具体特征,但这个练习可以帮助你逐渐习惯于在不完全了解每个维度具体含义的情况下,从一个人的个性向量中汲取有价值的信息。

  现在,这个向量开始部分地代表我的个性了。想象一下,如果我需要被一个性格相似的人替换(比如说,我不幸被公交车撞了),我们该如何选择?下图中的两个人,谁与我更相似?

请添加图片描述

  在处理这类向量数据时,计算相似性得分的一个常见方法是使用余弦相似度。

请添加图片描述

  然而,仅有两个维度并不足以捕捉人与人之间的复杂差异。心理学的研究表明,至少需要五个主要特征(以及多个次级特征)来更全面地描述一个人。所以,让我们在进行比较时考虑所有这五个维度。

请添加图片描述

  在五维空间中,我们无法像在二维空间那样直观地绘制向量,这是机器学习中常见的挑战之一。我们需要学会在高维空间中思考。幸运的是,余弦相似性在任意维度中都同样适用:

请添加图片描述

  在这部分的结尾,我们提出两个核心思想:

  1、我们可以将人(以及事物)表示为数字向量(这对机器来说是个巨大的优势!)。
  2、我们可以轻而易举地计算出这些向量之间的相似度。

请添加图片描述

词嵌入(Word Embeddings)

  理解了向量的基本概念后,我们现在可以开始探索训练好的词向量(也称为词嵌入)的一些有趣特性。这里有一个例子:GloVe模型在维基百科数据上训练得到的“国王”(king)的词嵌入向量。

[ 0.50451 , 0.68607 , -0.59517 , -0.022801, 0.60046 , -0.13498 , -0.08813 , 0.47377 , -0.61798 , -0.31012 , -0.076666, 1.493 , -0.034189, -0.98173 , 0.68229 , 0.81722 , -0.51874 , -0.31503 , -0.55809 , 0.66421 , 0.1961 , -0.13495 , -0.11476 , -0.30344 , 0.41177 , -2.223 , -1.0756 , -1.0783 , -0.34354 , 0.33505 , 1.9927 , -0.04234 , -0.64319 , 0.71125 , 0.49159 , 0.16754 , 0.34344 , -0.25663 , -0.8523 , 0.1661 , 0.40102 , 1.1685 , -1.0137 , -0.21585 , -0.15155 , 0.78321 , -0.91241 , -1.6106 , -0.64426 , -0.51042 ]

  这个向量是一个包含50个数字的列表。单纯看这些数字,我们很难得出任何有意义的结论。但如果我们把这些数字可视化,就能更直观地和其他单词的向量进行比较。想象一下,如果我们把这50个数字排成一行,看起来会是怎样?

请添加图片描述

  我们可以通过颜色来编码这些数字——例如,数值接近2时显示为红色,接近0时为白色,而接近-2时为蓝色。

请添加图片描述

  这样的颜色编码让我们无需关注具体的数字,而是通过颜色来理解每个数字的大致意义。

请添加图片描述

  现在,如果我们用这种方式来比较“King”与其他单词的向量,会发现什么呢?你会注意到“Man”和“Woman”之间的相似程度远高于它们与“King”的相似程度。这表明这些词向量在某种程度上捕捉了这些单词的意义和关联。

  接下来,我们通过另一个示例来进一步探索。通过垂直扫描各列,我们寻找颜色相似的列,从而进行比较:

请添加图片描述

  值得注意的是:

  · 所有这些不同的单词都有一个红色的直柱。它们在那个维度上是相似的(我们不知道每个维度代表什么)
  · 你可以看到“woman”和“girl”在很多地方都很相似。“man”和“boy”也是如此
  · “boy”和“girl”也有彼此相似的地方,但不同于“woman”或“man”。
  · 上图中除了最后一个字其他词都是代表人的字。我们添加了一个对象“water”来显示类别之间的差异。比如,你可以看到蓝色的柱子一直向下,在嵌入“水”之前停止。
  · “king”和“queen”有明显的相似之处,但又与其他词截然不同。

嵌入向量效果分析

  嵌入技术展示了一些不可思议的特性,其中最秀的就是类比关系的处理能力。我们可以通过对单词向量进行加减操作来获得一些有趣的结果。一个经典的例子就是这个等式:“国王(King)”减去“男人(Man)”再加上“女人(Woman)”:

请添加图片描述

  使用Python中的Gensim库,我们可以轻松地对这些词向量进行加减操作,并找到与结果向量最接近的单词。一个有趣的现象是,这种操作通常会得到一些出人意料的结果。例如,对于上述的等式,虽然得到的向量并不完全等同于“女王(Queen)”,但在我们分析的400,000个单词嵌入中,“女王”却是最接近这个结果的单词。

请添加图片描述

  在我们深入研究训练过的单词嵌入之前,有必要先了解它们的来源:语言模型。这是单词嵌入概念的核心,并为我们后续讨论Word2Vec奠定了基础。

语言模型

模型介绍

  如果我们要举出NLP应用的一个典型例子,智能手机键盘的下一个单词预测功能无疑是其中之一。想象一下,这个功能每天被数十亿人使用数百次,其影响力和普及程度是显而易见的。

请添加图片描述

  下一个单词预测是一个典型的语言模型应用场景。简单来说,语言模型可以接收一串单词(比如两个单词),然后尝试预测接下来可能出现的单词。例如,在下面的截图中,模型接收到两个绿色的单词(thou shalt)并返回一个建议列表,其中“not”是最有可能的预测。

请添加图片描述

  我们可以将这个模型视为一个“黑匣子”,但实际上它的工作原理并非如此简单。

请添加图片描述

  这个模型不仅仅输出一个单词,而是会计算并输出它所知道的所有单词的概率分数。这些单词的数量可能从几千到超过一百万不等。然后,智能手机键盘应用程序会从这些得分中挑选出最高的几个单词,呈现给用户作为输入建议。

请添加图片描述

  神经语言模型的输出实际上是对所有已知单词的概率评分。这里我们用百分比来表示这些概率,但在模型的输出向量中,这些百分比实际上是以小数形式出现的,比如40%会表示为0.4。

  经过训练的神经语言模型(比如2003年Bengio团队开发的模型)会经历几个计算步骤来做出预测。

请添加图片描述

  当我们讨论嵌入时,这些步骤中的第一步尤为重要。嵌入矩阵是训练过程的一个结果,包含了词汇表中每个单词的嵌入向量。在进行预测时,我们只需要查找输入单词的嵌入,并使用它们来计算预测结果。

请添加图片描述

  现在,让我们深入了解训练过程,探索如何开发这种嵌入矩阵的更多细节。

模型训练

  语言模型在机器学习领域中占据了独特的优势。它们的主要好处在于能够直接利用丰富的文本数据进行训练。想象一下,我们周围充斥着各种书籍、文章、维基百科的内容以及其他形式的文本数据。这与那些需要大量手工特征工程和专门收集数据的机器学习模型形成了鲜明对比。

  在训练过程中,我们通过观察单词倾向于出现在哪些其他单词旁边来获取它们的嵌入。这个过程大致如下:

  1、首先,我们获得了大量的文本数据,例如所有的维基百科文章。
  2、然后,我们设定一个窗口(比如三个单词),在所有文本中滑动这个窗口,为模型生成训练样本。
  3、当窗口在文本中滑动时,我们会生成用于训练模型的数据集。

  为了更清楚地理解这个过程,让我们看看这个滑动窗口是如何处理一个简短短语Thou shalt not make a machine in the likeness of a human mind的:

  一开始,窗口覆盖了句子的前三个词。

请添加图片描述

  我们将前两个词作为特征,第三个词作为标签,从而生成了数据集中的第一个样本,稍后用于训练语言模型。

请添加图片描述

  随后,窗口向右滑动到下一个位置,创建了第二个样本。

请添加图片描述

  这样,我们很快就拥有了一个较大的数据集,其中的单词在不同的词对后面出现。

请添加图片描述

  实际上,模型通常在我们滑动窗口的同时进行训练。但从逻辑上看,将“数据集生成”和训练阶段分开可能更为清晰。除了基于神经网络的语言建模方法之外,还有一种名为N-grams的技术常被用于训练语言模型(参见《Speech and Language Processing》第三章)。

Word2vec训练方法

  了解到目前为止的内容后,让我们来尝试一个填空游戏:

请添加图片描述

  假设我提供给你的上下文是一个空白处之前的五个单词,加上“bus”。大部分人可能会直观地认为,紧接着这些单词的应该是“bus”。但如果我进一步透露,这个空白后面紧跟着的是另一个特定的词,这是否会改变你的猜测呢?

请添加图片描述

  这个额外的信息可能完全改变我们对空白处应填单词的预测。原先我们猜测的“bus”现在可能被另一个与新信息更匹配的词所取代。这表明,一个特定单词的前后上下文都蕴含着重要的信息。事实上,同时考虑一个词的左右上下文(即我们尝试预测的单词的前后单词)可以生成更准确的单词嵌入。下面,让我们探索如何调整我们的训练模型,以便更好地利用这一发现。

CBOW方法

  在训练语言模型时,不仅可以考虑目标词之前的单词,还可以考虑其后面的单词。

请添加图片描述

  这样一来,我们构建和训练模型时考虑的数据集将会是这样的:

请添加图片描述

  这种方法在Word2Vec的研究论文中被称为CBOW架构。与此同时,还有另一种架构也显示出良好的效果,但其方法略有不同。

Skip-gram方法

  这种架构并不是根据目标词的上下文(即目标词前后的单词)来预测目标词,而是使用当前的单词来预测其相邻的单词。我们可以将其在训练文本中滑动的窗口想象成以下形式:

请添加图片描述

  这里,绿色的槽代表输入的单词,而每个粉红色的方框代表可能的输出。每个粉红色方框的不同阴影表示这个滑动窗口实际上在我们的训练数据集中创建了四个独立的样本:

请添加图片描述

  这种方法被称为“跳跃模型”(Skip-gram)架构。我们可以想象滑动窗口按以下方式执行操作:

请添加图片描述

  这样,就在我们的训练数据集中添加了这四个样本:

请添加图片描述

  随后,我们将窗口滑动到下一个位置:

请添加图片描述

  这样就生成了接下来的四个样本:

请添加图片描述

  经过几个位置的滑动之后,我们的数据集中就积累了更多这样的例子:

请添加图片描述

CBOW方法与Skip-gram方法总结

  从直观上理解,Skip-gram是给定input word来预测上下文。而CBOW是给定上下文,来预测input word。然而Word2Vec采用的是Skip-gram方法。

请添加图片描述

  重要问题:CBOW方法与Skip-gram方法有什么区别?为什么Word2vec用的是Skip-gram?

  首先贴个回答,https://zhuanlan.zhihu.com/p/37477611,回答中大概的意思有两点:
  一是Skip-gram学习次数是CBOW的K倍,K是窗口大小。
  二是Skip-gram采取一对一优化,CBOW采取一对多优化。他的核心观点是同一个词1次一对一优化比K次一对多优化好。

  我赞成观点二,反对观点一。下面给出理由:

  假设一个序列[a,b,c,d,e],窗口大小为3,CBOW造的数据集为([ac,b][bd,c][ce,d]);Skip-gram造的数据集为([b,a][b,c][c,b][c,d][d,c][d,e])。

  对于观点一,虽然CBOW只有3条数据,但对词c梯度更新时有2次;Skip-gram有6条数据,其实对词c梯度更新时也是2次。所以从更新次数上说,两种方法是一样的。
  对于观点二,CBOW标签为b时,同时更新ac的词向量;Skip-gram标签为b时,单独更新c的词向量,区别就在这里。理解为单独更新一个词的梯度比批量更新多个词的梯度更能学习到知识。

重构训练方法

  拥有了从现存运行文本中提取的Skip-gram训练数据集,我们现在可以探索如何使用这些数据来训练一个基本的神经语言模型,该模型专注于预测相邻的单词。

请添加图片描述

  首先,我们从数据集中挑选出第一个样本。我们取出这个特征,并将其输入到一个未经训练的模型中,要求它预测一个合适的相邻单词。

请添加图片描述

  这个模型会执行以下三个步骤,并输出一个预测向量,为词汇表中的每个单词分配一个概率。由于模型尚未经过训练,其在这一阶段的预测很可能是错误的。不过这没关系,因为我们已经知道正确的答案,即我们用来训练模型的当前行中的标签/输出单元格。

请添加图片描述

  那么,模型的预测和实际目标之间有多大差距呢?我们通过减去这两个向量来得到一个误差向量:

请添加图片描述

  这个误差向量接下来用于更新模型,这样当下一次模型接收到“not”作为输入时,它就更有可能做出正确的预测。

请添加图片描述

  这样,我们完成了对第一个样本的训练。接下来,我们对数据集中的下一个样本执行相同的步骤,然后再下一个,直至覆盖整个数据集。这完成了一个训练周期。我们重复进行多个周期,最终得到一个训练有素的模型,可以从中提取嵌入矩阵,用于其他各种应用。

  尽管这个过程增加了我们对训练过程的理解,但它仍然没有完全揭示Word2Vec实际上是如何训练的。我们还遗漏了一些关键的概念。

负采样

请添加图片描述

  在回顾这个神经语言模型计算其预测的三个步骤时,我们注意到第三步在计算上非常昂贵。特别是考虑到我们将对数据集中的每个训练样本执行这一过程(这很容易达到数千万次),我们需要寻找方法来提高性能。

  一种改进的方法是将我们的目标分为两个步骤:

  1. 生成高质量的单词嵌入(暂不考虑下一个单词的预测)。
  2. 使用这些高质量的嵌入来训练语言模型(进行下一个单词的预测)。

  我们现在专注于第一步。为了生成高质量的嵌入并利用高性能模型,我们可以将模型的任务从预测相邻单词:

请添加图片描述

  切换到一个模型,该模型接受输入和输出单词,并输出一个指示它们是否相邻的分数(0表示“不相邻”,1表示“相邻”)。

请添加图片描述

  这种简单的转换意味着我们需要的模型从复杂的神经网络变为了更简单、计算速度更快的逻辑回归模型。

  为了适应这个转换,我们需要调整数据集的结构——现在,标签成为一个新列,值为0或1。由于我们添加的所有单词对都是相邻的,因此它们的标签都是1。

请添加图片描述

  这使得计算能够极快地进行——在几分钟内就能处理数百万个样本。但我们需要解决一个问题。如果我们的所有样本都是正面的(目标为1),则存在一个模型总是返回1的可能性,虽然实现了100%的准确率,但实际上没有学到任何东西,生成的嵌入也是无用的。

请添加图片描述

  为了解决这个问题,我们需要在数据集中引入负样本,即非相邻词的样本。我们的模型需要为这些样本返回0。现在,这成为了一个模型必须努力解决的真正挑战,但处理速度仍然非常快。

请添加图片描述

  对于数据集中的每个样本,我们都添加了对应的负例。它们有相同的输入单词和一个0标签,但输出词是如何选择的呢?我们从词汇表中随机选取。

请添加图片描述

  这种方法的灵感来自于噪声对比估计(NCE)。我们通过将实际信号(相邻单词的正例)与噪声(随机选择的非相邻单词)进行对比,实现了计算和统计效率的重大改进。

基于负采样的Skip-gram(SGNS)

  我们现在已经讨论了word2vec中的两个中心思想:作为一对,它们被称为负采样skipgram。

请添加图片描述

Word2vec的最终训练方法

  现在我们已经理解了Skip-gram和负采样的核心概念,就让我们深入了解实际的Word2Vec训练过程。

  在训练开始前,我们对目标文本进行预处理。这一步骤涉及确定词汇表的大小(假设为10,000)和哪些单词将被包括在内。

  训练的初期,我们创建两个矩阵:嵌入矩阵和上下文矩阵。这两个矩阵都包含词汇表中每个单词的嵌入,其中一个维度是词汇量(vocab_size),另一个维度是嵌入长度(例如,一个常见的值是300,尽管我们之前看到了一个50维的例子)。

请添加图片描述

  这些矩阵在训练开始时被随机初始化。然后,训练过程启动。在每一步训练中,我们选取一个正例和相关的负例来训练。让我们看看第一组样本:

请添加图片描述

  我们的样本包括输入词“not”和输出/上下文词:“thou”(实际邻居)、“aaron"和"taco”(负例)。我们查找它们的嵌入——输入单词的嵌入在嵌入矩阵中,而上下文单词的嵌入则在上下文矩阵中。

请添加图片描述

  接下来,我们计算输入嵌入与每个上下文嵌入的点积。每个点积都产生一个数字,表示输入和上下文嵌入之间的相似度。

请添加图片描述

  现在,我们需要将这些分数转换成类似概率的值——它们需要是正数且在0到1之间。这是sigmoid函数的理想应用场景。

请添加图片描述

  将sigmoid函数的输出视为模型对这些示例的预测。你会注意到,"taco"的分数最高,而"aaron"的分数最低。

  这时,未经训练的模型已做出了预测,我们有实际的目标标签可用于比较,让我们计算模型预测的误差有多大。计算方法是目标标签减去sigmoid分数。

请添加图片描述

  现在进入“机器学习”中的“学习”阶段。我们可以利用这个误差分数来调整"not"、“thou”、"aaron"和"taco"的嵌入,使得下次我们进行这个计算时,结果更接近目标分数。

请添加图片描述

  这样,一次训练步骤就完成了。这些词(“not”、“thou”、“aaron"和"taco”)的嵌入现在略有改进。我们继续进行下一个训练步骤——处理下一个正例及其相关的负例,并重复同样的过程。

请添加图片描述

  随着我们多次遍历整个数据集,嵌入逐渐得到改善。最终,我们可以停止训练过程,弃用上下文矩阵,并将嵌入矩阵用作下一任务的预训练嵌入。

附数百个中文Word2vec向量下载地址

https://github.com/Embedding/Chinese-Word-Vectors/blob/master/README_zh.md

在这里插入图片描述

Word2vec为什么不如BERT模型?

  理解了这两个模型之后,很难评这个问题。

  Word2vec其实是一个字典,一个词对应一个固定的向量;而BERT是模型,是预训练模型,一个词输入BERT之后,其实是要经过神经网络模型计算得到表征向量的;所以它俩就不是一个东西,似乎没有可比性。

  但是,我们又经常把BERT整体当作一个Embedding层,所以要是从词向量角度,它俩又可以比一比:

  模型区别、一词多义、词汇表大小、句子编码

  模型区别 Word2Vec的核心特点是它的嵌入即是模型本身。无论是CBOW还是Skip-gram模型,Word2Vec没有除嵌入以外的其他参数。这使得模型结构相对简单,但也意味着其功能有一定的限制。

  一词多义 Word2Vec的一个主要限制是对于每个词条(token)只有一个固定表示,这一点长期以来一直受到批评。由于Word2Vec是基于词袋模型(BOW)的,它缺乏对单词位置的建模能力。虽然后续出现了如structure-Word2Vec等改进工作,但这些尝试依然没能完全解决这些固有的问题。

  词汇表大小 Word2Vec的词汇表通常非常庞大,常见的词汇量达到100万。相比之下,BERT系列模型由于掩蔽语言模型(MLM)任务的限制和字节对编码(BPE)分词器的流行,通常单一语言的词汇量大约在3万到5万之间。

  句子编码 BERT系列模型的一个显著优势是同时对token和句子进行建模。在Transformer模型中,每个token的表示都是基于对上一层所有token使用注意力机制的结果,这使得获取句子级别的表示变得非常简单。通常只需要使用如[CLS]这样的特殊token即可,从而充分利用模型的所有能力。相较而言,传统的Word2Vec模型没有直接获取句子级别表示的有效方法。一般做法是对所有词向量进行平均,但这并不等同于显式地对句子表示进行建模。

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

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

相关文章

nodejs+vue慢性胃炎健康管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于慢性胃炎健康管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了慢性胃炎健康管理系统, 系统首页、个…

AtCoder Beginner Contest 329 题解A~F

A - Spread 输入字符串&#xff0c;字符之间加上空格输出 B - Next 输出数组当中第二大的数 C - Count xxx 统计每个字符出现过的最长长度&#xff0c;再累加即可 #include<bits/stdc.h> #pragma GCC optimize("Ofast") #define INF 0x3f3f3f3f #define I…

【面试经典150 | 算术平方根】

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;数学表达式方法二&#xff1a;二分法 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并…

广州华锐互动VRAR:VR教学楼地震模拟体验增强学生防震减灾意识

在当今社会&#xff0c;地震作为一种自然灾害&#xff0c;给人们的生活带来了巨大的威胁。特别是在学校这样的集体场所&#xff0c;一旦发生地震&#xff0c;后果将不堪设想。因此&#xff0c;加强校园安全教育&#xff0c;提高师生的防震减灾意识和能力&#xff0c;已经成为了…

Python编程技巧 – 使用字符串(Strings)

Python编程技巧 – 使用字符串&#xff08;Strings) Python Programming Essentials – Using Strings 本文简要介绍如何使用字符串&#xff0c;来进行Python编程。字符串有很多用途&#xff0c;包括输出结果、反馈状态、数据处理以及切片和文本筛选等 1. 字符串 字符串(St…

详解自动化测试之 Selenium

目录 1. 什么是自动化 2.自动化测试的分类 3. selenium&#xff08;web 自动化测试工具&#xff09; 1&#xff09;选择 selenium 的原因 2&#xff09;环境部署 3&#xff09;什么是驱动&#xff1f; 4. 一个简单的自动化例子 5.selenium 常用方法 5.1 查找页面元素&…

基于SSM的北海旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

nodejs微信小程序-实验室上机管理系统的设计与实现-安卓-python-PHP-计算机毕业设计

用户&#xff1a;管理员、教师、学生 基础功能&#xff1a;管理课表、管理机房情况、预约机房预约&#xff1b;权限不同&#xff0c;预约类型不同&#xff0c;教师可选课堂预约和个人&#xff1b;课堂预约。 目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 …

2023.11.18 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态时间序列分析

目录 一、编程挑战&#xff1a;动态时间序列分析 实际应用&#xff1a; 实现提示&#xff1a; 二、实现 1. C 2. Python 3. JAVA 4. Go 一、编程挑战&#xff1a;动态时间序列分析 问题描述&#xff1a; 假设你是一名软件工程师&#xff0c;需要开发一个应用来分析和预…

asp.net心理健康管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 心理健康管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 系统视频链接 https://www.bilibili.com/video/BV19w411H7P4/ 二、功能介绍 本系统使用Microsoft Visual Studio…

初识Linux:目录的创建销毁

目录 ​编辑 提示&#xff1a;以下指令均在Xshell 7 中进行 零、桌面的本质 &#x1f4bb; 扩展&#x1f387;&#xff1a; 一、cd指令&#xff1a; 1、cd - &#xff1a; 2、cd ~&#xff1a; 重命名命令&#xff1a;alias 二、stat指令 冷知识&#xff1a; 如果…

SpringCloud总结

注&#xff1a;本文并不涉及具体功能是怎么实现的&#xff0c;而只是微服务技术栈的整体总结和理解。 目录 一.基础概念--认识微服务 1.单体架构 2.分布式架构 3.微服务 4.SpringCloud 二.服务的拆分原则 三.RestTemplate--实现不同服务之间的通信与远程调用 四.Eurek…

代码随想录算法训练营第二十八天| 78 子集 90 子集|| 93 复原IP地址

78 子集 由题意可知数组中的元素互不相同&#xff0c;所以在dfs中我们可以将当前的path直接加入到res中。 class Solution {List<List<Integer>>res new ArrayList<>();List<Integer>path new LinkedList<>();public List<List<Integer…

系列一、JVM概述

一、概述 1.1、Java发展中的重大事件 1.2、虚拟机 vs Java虚拟机 1.2.1、虚拟机 1.2.2、Java虚拟机 1.2.3、Java虚拟机的作用 Java虚拟机是二进制字节码的运行环境&#xff0c;负责装载字节码到其内部&#xff0c;解释/编译为对应平台上的机器指令指令。每一条Java指令&#…

鸿蒙:使用Stack、ContentTable、Flex等组件和布局实现一个显示界面

效果展示 一.概述 跟随官网继续HarmonyOS学习 本篇博文实现一个食物详情页的开发Demo 通过这个开发过程学习如何使用容器组件Stack、Flex和基本组件Image、Text&#xff0c;构建用户自定义组件&#xff0c;完成图文并茂的食物介绍 二.构建Stack布局 1.食物名称 创建Stack…

【Dubbo】Dubbo负载均衡实现解析

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

Android 13 - Media框架(14)- OpenMax(二)

这一节我们将来解析 media.codec 这个 HIDL service 究竟提供了什么服务&#xff0c;服务是如何启动的。 1、main 函数 我们先来看 frameworks/av/services/mediacodec/main_codecservice.cpp&#xff1a; int main(int argc __unused, char** argv) {strcpy(argv[0], "…

广州华锐互动VRAR:利用VR开展刑事案件公安取证培训,沉浸式体验提升实战能力

随着科技的飞速发展&#xff0c;虚拟现实(VR)技术为我们的生活和工作带来了前所未有的便利。近年来&#xff0c;VR技术在刑事案件公安取证培训中的应用逐渐显现出其独特优势。通过模拟真实的犯罪现场&#xff0c;VR技术为学员提供了沉浸式的体验&#xff0c;使他们在安全的环境…

java文件压缩加密,使用流的方式

使用net.lingala.zip4j来进行文件加密压缩。 添加依赖net.lingala.zip4j包依赖&#xff0c;这里使用的是最新的包2.11.5版本。 <dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>${zip4j.versi…

微服务调用链路追踪

概述 本文介绍微服务调用链路追踪&#xff0c;涉及技术有&#xff1a;sleuth和zipkin。sleuth负责追踪调用链路数据&#xff0c;zipkin负责调用链路数据可视化展现。 本文的操作是在 服务网关实践 的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 …