⌈ 传知代码 ⌋ 深度学习革新音乐转录

news2024/9/21 19:39:50

💛前情提要💛

本文是传知代码平台中的相关前沿知识与技术的分享~

接下来我们即将进入一个全新的空间,对技术有一个全新的视角~

本文所涉及所有资源均在传知代码平台可获取

以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦!!!

以下内容干货满满,跟上步伐吧~


📌导航小助手📌

  • 💡本章重点
  • 🍞一. 概述
  • 🍞二. MT3模型:多任务多轨音乐转录的突破
  • 🍞三.Transformer 模型:简化钢琴音乐转录
  • 🍞四. 关键技术与创新点
  • 🍞五. 部署过程
  • 🫓总结


💡本章重点

  • 深度学习革新音乐转录

🍞一. 概述

自动音乐转录(AMT)作为音乐信息检索(MIR)的一个重要分支,其目标是将音频信号转换成可读的乐谱形式,这在音乐分析、教育、制作等多个领域都有着广泛的应用。AMT的发展历程可以划分为两个主要阶段:早期基于规则的方法和现代基于深度学习的技术。

在早期阶段,研究者依赖于手工设计的特征提取方法,例如尺度不变特征变换(SIFT)和加速稳健特征(SURF)算法。这些方法虽然在特定应用上取得了成功,但它们的普适性和可扩展性受限,通常需要专业知识来定制特征提取器。这些传统方法往往需要专家对音乐信号进行深入分析,以手动定义特征提取规则和音高估计算法,这不仅耗时耗力,而且难以适应音乐的多样性和复杂性。

随着深度学习技术的兴起,计算机视觉领域迎来了革命性的变化,这一变革同样波及到了音乐转录领域。卷积神经网络(CNNs)的出现,使得计算机能够自动从图像中学习特征表示,极大地推动了图像分类、目标检测和图像分割等任务的发展。在音乐转录领域,深度学习技术的应用同样取得了显著的进展。自2012年AlexNet在ImageNet竞赛中取得历史性胜利后,CNNs便成为了计算机视觉领域的核心技术,而在AMT中,深度学习模型也逐渐展现出其强大的能力。

深度学习在音乐转录中的重要性体现在其能够自动学习从简单到复杂的音乐特征。这使得AMT系统在多种音乐任务上都取得了显著的成功。为了进一步提升性能,研究者们不断改进深度学习模型的设计,引入了批量归一化、残差连接和深度可分离卷积等创新技术,这些技术提高了网络的训练效率,并使得构建更深、更宽的网络成为可能。

尽管CNNs在多个视觉任务上表现出色,但它们的局限性也逐渐显现,尤其是在处理图像中长距离依赖关系时。为了解决这一问题,研究者们开始探索注意力机制,该机制最初在自然语言处理领域取得了巨大成功。Transformer模型通过自注意力机制处理序列数据,能够捕捉长距离依赖关系。这一机制的引入,使得AMT模型能够更加灵活地处理音乐中的结构关系,Vision Transformer(ViT)便是基于这一思想的代表模型。

MLP-Mixer模型的提出为音乐转录领域带来了新的思考。这是一种完全基于多层感知器(MLPs)的架构,它不依赖于卷积或自注意力机制。MLP-Mixer通过独立地在音乐片段上应用MLPs来进行特征和结构信息的混合,简化了模型结构,同时保持了对音乐特征的有效捕捉。MLP-Mixer的提出不仅挑战了CNNs和Transformers在音乐任务中的主导地位,而且展示了一种全新的视角,即通过基本的矩阵运算和非线性激活函数实现强大的音乐表征。


🍞二. MT3模型:多任务多轨音乐转录的突破

音乐转录领域面临的一个主要挑战是如何处理多种乐器的同时演奏,这要求模型不仅要识别出不同的音符,还要区分它们是由哪种乐器发出的。MT3模型正是为了应对这一挑战而设计的,它通过多任务学习的方法,实现了对多种乐器声音的同时转录。

  • MT3模型的核心概念与架构

在这里插入图片描述

MT3能够从原始音频光谱图中转录任意数量的仪器。这里显示的是真正的4秒音频剪辑,从模型的标记输出重建钢琴卷,和相应的乐器标签(额外的 Slakh2100乐器省略了由于空间)。注意,在某些情况下,从单声乐器(如单簧管或圆号)预测的多个音符反映了包含该乐器的多个演奏者的合奏 MT3 模型的核心概念是将音乐转录任务视为一个序列到序列的问题,其中输入是音频的频谱图,输出是一系列表示音符和乐器的标记。

这种处理方式使得MT3能够处理多轨音乐,即同时对多个乐器的声音进行转录。MT3模型采用了Transformer架构,这是一种基于自注意力机制的深度学习模型,它能够处理长距离依赖关系,并在多种序列建模任务中表现出色。

MT3模型的架构包括一个编码器-解码器结构,其中编码器负责处理输入的音频频谱图,而解码器则生成表示音乐的序列输出。模型使用了一种紧凑且灵活的标记化方案,将模型输出的标记转换为多轨MIDI文件,这使得MT3能够支持不同组合的乐器数据集。

多任务学习在音乐转录中的应用

在这里插入图片描述

标记化/去标记化,MIDI 数据(左边,在这里表示为多音轨“ pianoroll”)可以标记为用于训练的类似 MIDI 的目标标记(右边)。可以确定地将使用相同词汇表的输出标记解码回 MIDI 数据。

多任务学习是MT3模型的另一个关键特点。在传统的单任务学习中,模型通常被训练来完成一个特定的任务。然而,在多任务学习中,模型被同时训练来完成多个任务,这有助于提高模型的泛化能力,并允许它在低资源的情况下也能表现良好。MT3模型通过联合训练多个数据集,能够同时学习到不同乐器的特征,从而在转录过程中更准确地识别和区分它们。

MT3模型的统一训练框架提供了几个显著的优势。它允许使用来自不同数据集的数据进行训练,这增加了模型训练时可以使用的数据量和多样性。统一框架简化了模型的训练和评估过程,因为所有的数据集都使用相同的评估指标和测试集分割。这种方法还有助于提高模型对低资源乐器的转录性能,因为它通过从高资源乐器中转移知识来增强对低资源乐器的识别能力。MT3模型的这些特点使其在多任务多轨音乐转录方面取得了突破性的进展。它不仅能够处理多种乐器的声音,还能够在低资源乐器上实现高质量的转录,这对于音乐研究和教育等领域具有重要的意义。随着深度学习技术的不断进步,MT3模型有望在未来的音乐转录任务中发挥更大的作用


🍞三.Transformer 模型:简化钢琴音乐转录

序列到序列方法的原理

序列到序列(Seq2Seq)方法是机器学习中的一种重要框架,广泛应用于各种需要处理输入和输出序列的任务中。最初应用于机器翻译任务,该方法已经在多个领域取得了显著成果,包括文本生成、语音识别和音乐转录等。

在序列到序列框架中,模型由两个主要部分组成:编码器(Encoder)和解码器(Decoder)。编码器负责读取和理解输入序列,将其转换为一个固定长度的上下文向量(context vector),这个向量捕捉了输入序列中的重要信息。解码器则利用这个上下文向量生成输出序列,通过逐步预测下一个输出元素来完成任务。

传统的序列到序列模型通常采用递归神经网络(RNN)或长短期记忆网络(LSTM)作为其基本架构。这些网络通过其循环结构来捕捉序列中的时间依赖关系。然而,RNN和LSTM在处理长序列时存在一些固有的局限性,比如梯度消失和计算效率低下的问题。

Transformer模型的出现解决了这些问题。Transformer通过自注意力机制(self-attention mechanism)和并行计算,显著提高了序列到序列任务的性能和效率。自注意力机制允许模型在处理每个输入元素时都能访问整个输入序列,从而更好地捕捉全局依赖关系。此外,Transformer的架构中没有循环结构,完全依赖于注意力机制和前馈神经网络,这使得它在处理长序列时更加高效。

  • Transformer模型在音乐转录中的创新应用

音乐转录,尤其是钢琴音乐转录,是一个复杂的任务,需要将音频信号转换为符号表示(如MIDI事件)。这不仅要求模型能够准确地识别音符的开始和结束,还要捕捉音符的力度、时间和其他细节。传统的音乐转录方法往往依赖于专门设计的特征提取器和复杂的后处理步骤,而Transformer模型提供了一种更简洁和高效的解决方案。

在论文《Sequence-to-Sequence Piano Transcription with Transformers》中,作者提出了一种使用Transformer模型进行钢琴转录的方法。该模型采用了标准的编码器-解码器Transformer架构,没有任何特定领域的调整或优化,这一设计选择展示了Transformer模型的通用性和强大能力。

具体来说,模型输入是音频的频谱图帧,这些帧表示了音频信号在不同时间点上的频率分布。通过频谱图,模型能够捕捉到音频中的时间和频率信息,这对识别音符非常关键。编码器将这些频谱图帧转换为高维特征表示,这些表示包含了输入音频的所有关键信息。解码器则基于这些特征表示生成音符事件序列,包括音符的开始和结束、力度以及时间。

这种方法的一个显著优势是它简化了整个转录过程。传统方法通常需要复杂的特征提取步骤,如频谱图处理、音高估计和音符事件检测等。而Transformer模型通过其强大的表征能力,可以直接从原始频谱图中学习这些特征,大大减少了手工特征提取和调试的工作量。

  • 模型的编码器-解码器结构及其作用

Transformer模型的编码器-解码器结构是其成功的核心。该结构由多个编码器和解码器层堆叠而成,每一层都包含了自注意力机制和前馈神经网络。

编码器

编码器由若干相同的层堆叠组成,每层包括一个多头自注意力机制和一个前馈神经网络。多头自注意力机制允许模型在不同的表示空间中计算注意力权重,从而更好地捕捉输入序列中的复杂依赖关系。前馈神经网络则对注意力机制的输出进行进一步的非线性变换和处理。

在音乐转录任务中,编码器的作用是将输入的频谱图帧转换为高维特征表示。频谱图帧中的每个时间步都与一个特征向量对应,这些特征向量通过多层编码器的处理,逐渐融合了整个输入序列的信息,形成了对音频信号的全局理解。

解码器

解码器也由若干相同的层堆叠组成,每层包含一个多头自注意力机制、一个编码器-解码器注意力机制和一个前馈神经网络。自注意力机制用于解码器自身的序列建模,而编码器-解码器注意力机制则允许解码器在生成每个输出标记时,参考编码器的输出。

在音乐转录任务中,解码器的作用是基于编码器生成的特征表示,逐步生成音符事件序列。解码器在每一步生成一个音符事件,这些事件包括音符的开始和结束、力度和时间等信息。通过这种方式,解码器可以在生成过程中利用整个输入序列的信息,从而提高转录的准确性和连贯性。

这种编码器-解码器结构的一个重要特点是其并行计算能力。与传统的RNN和LSTM不同,Transformer中的注意力机制允许模型在处理每个输入元素时同时考虑所有其他元素,这极大地提高了计算效率,尤其是在处理长序列时。此外,Transformer的层次化结构使得模型可以更好地捕捉输入序列中的层次化特征,从而增强了模型的表达能力。


🍞四. 关键技术与创新点

  • MT3模型的技术亮点:多任务学习、数据集整合、评估标准统一

多任务学习

  1. 多任务学习(Multi-Task Learning, MTL)是MT3模型中的一个关键技术亮点。传统的机器学习模型通常是为单一任务设计的,但在实际应用中,许多任务之间存在相互关联和依赖关系。多任务学习旨在通过同时训练多个相关任务,利用这些任务之间的共享信息来提高模型的泛化能力和性能。

  2. 在MT3模型中,多任务学习被应用于音乐转录任务中。音乐转录不仅包括识别音符的开始和结束,还包括识别音符的力度、持续时间和音高等多种信息。通过将这些相关任务整合在一个模型中,MT3能够在不同任务之间共享特征表示,从而更准确地捕捉音频信号中的细节信息。这种方法有几个主要优势:

  • 共享信息和资源:多任务学习允许模型在多个任务之间共享底层特征表示,从而提高数据的利用效率。这种共享可以减少过拟合风险,提高模型的泛化能力。

  • 互相增强:相关任务之间的信息共享可以互相增强。例如,在音乐转录任务中,识别音符的音高信息可以帮助模型更好地确定音符的开始和结束时间,反之亦然。

  • 高效训练:多任务学习可以在一次训练过程中同时优化多个任务的目标函数,从而减少训练时间和计算资源的消耗。

数据集整合

数据集整合是MT3模型的另一个重要技术亮点。在实际应用中,获取大规模高质量的标注数据通常是一个巨大的挑战。不同的数据集可能包含不同的标注标准和格式,这给模型训练带来了额外的复杂性。MT3通过整合多个不同来源的数据集,并对其进行统一处理和标准化,解决了这一问题。

数据集整合涉及以下几个步骤:

  • 数据收集:收集来自不同来源的数据集,包括公开数据集和自有数据集。这些数据集可能包含不同类型的音乐,具有不同的标注格式。

  • 数据清洗和预处理:对收集到的数据进行清洗和预处理,包括去除噪声数据、填补缺失数据和标准化标注格式。这一步骤确保了数据的一致性和高质量。

  • 统一标注标准:将不同数据集的标注标准进行统一,创建一个通用的标注格式。这一步骤使得模型可以在不同的数据集上进行一致的训练和评估。

通过数据集整合,MT3模型能够利用更大规模和更多样化的数据进行训练,从而提高模型的鲁棒性和泛化能力。同时,统一的标注标准也简化了模型的训练和评估过程,减少了由于数据集不一致带来的误差。

评估标准统一

评估标准的统一是确保模型性能和结果可比性的关键。不同的研究和应用通常采用不同的评估标准,这使得直接比较不同模型的性能变得困难。MT3通过引入统一的评估标准,解决了这一问题。

在音乐转录任务中,常用的评估标准包括准确率、召回率、F1分数等。这些指标分别衡量了模型在正确识别音符、未漏掉音符以及整体性能方面的表现。MT3模型采用统一的评估标准,对不同任务和不同数据集上的性能进行评估。这种方法有助于:

  • 确保可比性:统一的评估标准使得不同模型的性能结果具有可比性,研究人员可以更准确地比较和评估不同方法的优劣。

  • 提高透明度:统一标准增加了研究的透明度,使得研究结果更易于理解和复现。

  • 促进进步:通过一致的评估标准,研究人员可以更加专注于模型本身的改进和优化,而不必担心由于评估标准不同带来的不确定性。

在这里插入图片描述

从 Slakh2100数据集的混合中15秒钟的 MT3转录摘录。黑线表示模型输入框架。蓝色音符表示“真正的积极”音符与正确的预测发病,偏移,音高和乐器。在这个片段中,模型实现了0.665的起始偏移 F1。


🍞五. 部署过程

  • 安装依赖库
`flax`: `pip install flax @ git+https://github.com/google/flax#egg=flax`
  • 克隆代码库
git clone https://github.com/magenta/mt3.git
cd mt3
  • 设置环境
export PYTHONPATH="/path/to/mt3:$PYTHONPATH"
   # 假设samples是你的音频样本数据
   samples = ...
   spectrogram_config = spectrograms.SpectrogramConfig()
   frames, frame_times = _audio_to_frames(samples, spectrogram_config)
   
   # 将音频转换为模型可以理解的标记
   # 需要提供序列化的音乐序列数据sequence和codec
   sequence = ...
   codec = event_codec.Codec()
   tokenized = tokenize_transcription_example(
       ...,
       spectrogram_config=spectrogram_config,
       codec=codec,
       ...
   )
  • 定义Transformer模型
class TransformerModel(tf.keras.Model):
    def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, pe_input, pe_target):
        super(TransformerModel, self).__init__()

        self.tokenizer = tf.keras.layers.TextVectorization(max_tokens=input_vocab_size)

        self.encoder = Encoder(num_layers, d_model, num_heads, dff, input_vocab_size, pe_input)
        self.decoder = Decoder(num_layers, d_model, num_heads, dff, target_vocab_size, pe_target)

        self.final_layer = tf.keras.layers.Dense(target_vocab_size)

    def call(self, inp, tar):
        enc_output = self.encoder(inp)
        dec_output, _ = self.decoder(tar, enc_output)
        final_output = self.final_layer(dec_output)

        return final_output

# 定义模型参数
num_layers = 4
d_model = 128
num_heads = 8
dff = 512
input_vocab_size = 8000
target_vocab_size = 8000
pe_input = 10000
pe_target = 10000

# 初始化模型
transformer = TransformerModel(num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, pe_input, pe_target)
  • 定义和训练模型
复制from tasks import add_transcription_task_to_registry

# 添加转录任务到seqio.TaskRegistry
add_transcription_task_to_registry(
    dataset_config=...,
    spectrogram_config=SPECTROGRAM_CONFIG,
    vocab_config=VOCAB_CONFIG_FULL,
    tokenize_fn=...,
    onsets_only=False,
    include_ties=False,
    skip_too_long=False
)
  • 保存和加载模型
from checkpoint import save_checkpoint, load_checkpoint

# 保存模型检查点
save_checkpoint(workdir, model_params, step)

# 加载模型检查点
model_params = load_checkpoint(workdir)
  • 评估模型
from metrics_utils import event_predictions_to_ns

# 将预测结果转换为NoteSequence
predictions = ...
codec = ...
encoding_spec = ...
result = event_predictions_to_ns(predictions, codec, encoding_spec)

  • 模型部署
transformer.save('path/to/save/transformer_model')
# 使用TensorFlow Serving部署模型
# 请参考TensorFlow Serving文档进行详细配置和部署
#创建一个Web服务。
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/transcribe', methods=['POST'])
def transcribe():
    # 处理请求,进行模型预测
    # ...
    return jsonify(result)

if __name__ == '__main__':
    app.run(debug=True)

🫓总结

综上,我们基本了解了“一项全新的技术啦” 🍭 ~~

恭喜你的内功又双叒叕得到了提高!!!

感谢你们的阅读😆

后续还会继续更新💓,欢迎持续关注📌哟~

💫如果有错误❌,欢迎指正呀💫

✨如果觉得收获满满,可以点点赞👍支持一下哟~✨

【传知科技 – 了解更多新知识】

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

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

相关文章

SpringBoot上传文件大小超出范围捕获异常

文件上传中,可以限定文件大小,防止用户上传过大的文件,但是出现异常会报错,不够优雅 这里做异常捕获,然后自定义提示文字,可以更加优雅的解决文件上传超出限制报异常 /*** 上传文件超出大小限制异常 适用于…

微信公众号获取用户openid(PHP版,snsapi_base模式)

微信公众号获取用户openid的接口有2个:snsapi_base、snsapi_userinfo 详情见微信公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html 本文介绍用PHP方式调用snsapi_base接口获取微信用户…

Godot入门 02玩家1.0版

添加Node2D节点,重命名Game 创建玩家场景,添加CharacterBody2D节点 添加AnimatedSprite2D节点 从精灵表中添加帧 选择文件 设置成8*8 图片边缘模糊改为清晰 设置加载后自动播放,动画循环 。动画速度10FPS,修改动画名称idle。 拖动…

Spark实时(六):Output Sinks案例演示

文章目录 Output Sinks案例演示 一、​​​​​​​File sink 二、​​​​​​​​​​​​​​Memory Sink 三、​​​​​​​​​​​​​​Foreach Sink 1、​​​​​​​foreachBatch 2、​​​​​​​​​​​​​​foreach Output Sinks案例演示 当我们对流式…

HarmonyOS NEXT星河版零基础入门到实战

文章目录 一、HarmonyOS NEXT介绍学习内容1、鸿蒙APP开发2、能力套件开发3、全场景开发适合人群 持续更新中✒️总结 一、HarmonyOS NEXT介绍 放弃安卓框架之后,HarmonyOS NEXT成为真正独立于安卓、iOS的操作系统,堪称是一场史无前例的脱胎换骨。在其众多…

模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域

Vue.js 是一个流行的 JavaScript 框架,因此,确保其组件按预期工作至关重要:有效,更重要的是,可靠。模拟依赖项是最有效的测试方法之一,我们将在本文中发现。 模拟依赖项的必要性 模拟依赖项是一种对测试施加…

大数据-49 Redis 缓存问题中 穿透、雪崩、击穿、数据不一致、HotKey、BigKey

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

亚信安慧AntDB-M负载均衡

负载均衡是分布式系统中常用的技术,主要是将工作任务均衡分布到系统的各个资源点上,可以充分利用系统资源。 AntDB-M分布式内存数据库节点角色可以分为管理节点(MN)、计算节点(CN)和数据节点(DN)三种。管理节点收到客户端连接请求后,会经由负…

【学习记录】锚框

主要解释程序代码,具体解析在代码中进行标注 锚框,具体看见网址https://zh-v2.d2l.ai/chapter_computer-vision/anchor.html#iou 对应程序解析:https://fkjkkll.github.io/2021/11/23/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8BSSD/#more 目录…

数据结构:(1)线性表

一、基本概念 概念:零个或多个数据元素的有限序列 元素之间是有顺序了。如果存在多个元素,第一个元素无前驱,最后一个没有后继,其他的元素只有一个前驱和一个后继。 当线性表元素的个数n(n>0&am…

UE4 UnrealPak加密功能(配置AES encrypt key)

本文的重点在于如何使用UnrealPak的加密功能,以及相关的UE4源代码学习。本文参考了:https://www.cnblogs.com/shiroe/p/14803859.html 。 设置密钥 在编辑、项目设置中找到下面栏目,并点击“生成新的加密密钥”,就可以为Unreal P…

K210视觉识别模块学习笔记7:多线程多模型编程识别

今日开始学习K210视觉识别模块: 图形化操作函数 亚博智能 K210视觉识别模块...... 固件库: canmv_yahboom_v2.1.1.bin 训练网站: 嘉楠开发者社区 今日学习使用多线程、多模型来识别各种物体 这里先提前说一下本文这次测试实验的结果吧:结果是不太成…

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH?

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 目录 ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/61780…

详解程序的预处理与编译与连接

文章目录 1.程序的翻译环境和执行环境2.详解编译链接2.1 翻译环境2.2 编译本身也分为几个阶段2.3 运行环境 3.预处理详解3.1 预处理符号3.2 \#define3.2.1 \#define 定义标识符3.2.2 \#define定义宏3.2.3 \#define 替换规则 3.2.4 \#和\#\#3.2.5 带副作用的宏参数3.2.6 宏和函数…

数据结构之判断二叉树是否为搜索树(C/C++实现)

文章目录 判断二叉树是否为搜索树方法一:递归法方法二:中序遍历法总结 二叉树是一种非常常见的数据结构,它在计算机科学中有着广泛的应用。二叉搜索树(Binary Search Tree,简称BST)是二叉树的一种特殊形式&…

【VUE】封装一个追随鼠标的漂浮组件框架

红色箭头代表鼠标位置&#xff0c;蓝色区域跟随鼠标出现&#xff0c;鼠标进行其他操作的时候&#xff0c;蓝色区域隐藏。 vue全码 <template><divmousemove"updatePosition"mouseleave"hideDiv"class"container":style"{ positi…

AXI总线

目录 一、AXI接口特点二、AXI接口的握手机制2.1 握手原理2.2 握手机制的三种情形 三、AXI接口的通道3.1 AXI4-Stream3.1.1 通道信号3.1.2 数据字节类型3.1.3 流格式 3.2 AXI4-Lite和AXI4-Full3.1.1 读地址通道3.1.2 读数据通道3.1.3 写地址通道3.1.4 写数据通道3.1.5 写响应通道…

MybatisPlus分页插件

分页查询是一个很常见的需求&#xff0c;故Mybatis-Plus提供了一个分页插件&#xff0c;使用它可以十分方便的完成分页查询。下面介绍Mybatis-Plus分页插件的用法&#xff0c;详细信息可参考官方链接。 配置分页插件 创建com.atguigu.hellomp.config.MPConfiguration配置类&a…

奇异值分解(SVD)时间复杂度分析与优化

奇异值分解是一种矩阵分解的方法&#xff0c;大学线性代数里面也讲过奇异值分解的方法&#xff0c;因此这是一个为大家所熟知的算法。 1 SVD 时间复杂度分析 给定一个 m n m \times n mn 的矩阵 a \boldsymbol{a} a&#xff0c;按照下面公式做分解&#xff0c;其中 Σ \S…

python语言利用Tkinter实现GUI计算器|(二)优化计算器:过滤用户不合理的输入

python语言利用Tkinter实现GUI计算器 python语言利用Tkinter实现GUI计算器|&#xff08;一&#xff09;计算器基本功能设计 python语言利用Tkinter实现GUI计算器|&#xff08;二&#xff09;优化计算器 python语言利用Tkinter实现GUI计算器|&#xff08;三&#xff09;pyinstal…