paddlepaddle

news/2024/4/29 19:30:44/文章来源:https://blog.csdn.net/handily_1/article/details/126623999

项目用到了paddlespeech2,学了几天paddlepaddle,简单记录一下:

文章目录

        • 1 手写数字识别任务
        • 2 极简方案构建手写数字识别模型
            • 模型设计
            • 训练配置
            • 训练过程
            • 模型测试
        • 3【手写数字识别】之数据处理
        • 4【手写数字识别】网络结构
          • 4.1 经典的全连接神经网络
          • 4.2 卷积神经网络
        • 5【手写数字识别】损失函数
          • 5.1 Softmax函数
          • 5.2 交叉熵
        • 6【手写数字识别】优化算法
            • 前提条件
            • 设置学习率
            • 学习率的主流优化算法
        • 7【手写数字识别】之资源配置
            • 单GPU训练
            • 分布式训练
            • 单机多卡程序
        • 8【手写数字识别】之训练调试与优化
            • 8.1 计算分类准确率,观测模型训练效果。
            • 8.2 检查模型训练过程,识别潜在训练问题
            • 8.3 加入校验或测试,更好评价模型效果
            • 8.4 加入正则化项,避免模型过拟合
            • 8.5 可视化分析
        • 9【手写数字识别】之恢复训练
        • 10 【手写数字识别】之动转静部署
            • 动态图转静态图训练
            • 动态图转静态图模型保存
            • 动态图转静态图模型保存
    • paddlespeech体验
      • 1.流式语音识别服务
        • 服务端使用方法
        • ASR 客户端使用方法
      • 2.流式语音合成服务

1 手写数字识别任务

在这里插入图片描述

2 极简方案构建手写数字识别模型

首先要加载飞桨平台与“手写数字识别”模型相关的类库

通过paddle.vision.datasets.MNIST API设置数据读取器

# 设置数据读取器,API自动读取MNIST数据训练集
train_dataset = paddle.vision.datasets.MNIST(mode='train')

登录“飞桨官网->文档->API文档”,可以获取飞桨API文档。

模型设计
训练配置
训练过程
模型测试

3【手写数字识别】之数据处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dQTIPeeR-1661928958262)(https://ai-studio-static-online.cdn.bcebos.com/257c74a23cef401c9db75fd2841bb93cdec28f756c6049b7b3e5ec1bf0ed058d)]

处理程序,一般涉及如下五个环节:

  • 数据处理部分之前的代码,加入飞桨平台和数据处理库
  • 读入数据并划分数据集
  • 训练样本乱序、生成批次数据
  • 校验数据有效性
  • 封装数据读取与处理函数

同步数据读取:数据读取与模型训练串行。当模型需要数据时,才运行数据读取函数获得当前批次的数据。在读取数据期间,模型一直等待数据读取结束才进行训练,数据读取速度相对较慢。

异步数据读取:数据读取和模型训练并行。读取到的数据不断的放入缓存区,无需等待模型训练就可以启动下一轮数据读取。当模型训练完一个批次后,不用等待数据读取过程,直接从缓存区获得下一批次数据进行训练,从而加快了数据读取速度。

飞桨实现异步数据读取,两个步骤:

  1. 构建一个继承paddle.io.Dataset类的数据读取器。
  2. 通过paddle.io.DataLoader创建异步数据读取的迭代器。

4【手写数字识别】网络结构

手写数字输入是28x28的像素值,输出是0-9的数字标签

线性回归模型无法捕捉

需要网络来构建:经典的多层全连接神经网络和卷积神经网络。

先进行数据处理

定义数据集读取器加载数据数据区分训练集,验证集,测试集校验数据定义数据集每个数据的序号, 根据序号读取数据定义数据生成器
4.1 经典的全连接神经网络

包含四层网络:输入层、两个隐含层和输出层

手写数字识别的任务,网络层的设计如下:

输入层的尺度为28×28,中间的两个隐含层为10×10的结构,激活函数使用常见的Sigmoid函数。
与房价预测模型一样,模型的输出是回归一个数字,输出层的尺寸设置成1。

4.2 卷积神经网络

卷积神经网络由多个卷积层和池化层组成,卷积层负责对输入进行扫描以生成更抽象的特征表示,池化层对这些特征表示进行过滤,保留最关键的特征信息。

5【手写数字识别】损失函数

损失函数是模型优化的目标,用于在众多的参数取值中,识别最理想的取值。损失函数的计算在训练过程的代码中,每一轮模型训练的过程都相同,分如下三步:

  1. 先根据输入数据正向计算预测输出。
  2. 再根据预测值和真实值计算损失。
  3. 最后根据损失反向传播梯度并更新参数。
5.1 Softmax函数

真实的标签值可以转变成一个10维度的one-hot向量,在对应数字的位置上为1,其余位置为0,比如标签“6”可以转变成[0,0,0,0,0,0,1,0,0,0]。引入Softmax函数可以将原始输出转变成对应标签的概率

对应到代码上,需要在前向计算中,对全连接网络的输出层增加一个Softmax运算,outputs = F.softmax(outputs)

5.2 交叉熵
均方误差(常用于回归问题)、交叉熵误差(常用于分类问题)

基于最大似然思想,交叉熵只计算对应着“正确解”标签的输出的自然对数。

比如,假设正确标签的索引是“2”,与之对应的神经网络的输出是0.6,则交叉熵误差是−log⁡0.6=0.51;若“2”对应的输出是0.1,则交叉熵误差为−log⁡0.1=2.30。正确解标签对应的输出越小,则交叉熵的值越大

交叉熵的代码实现:

手写数字识别任务中,仅改动三行代码,就可以将在现有模型的损失函数替换成交叉熵(Cross_entropy)。

  • 在读取数据部分,将标签的类型设置成int,体现它是一个标签而不是实数值(飞桨框架默认将标签处理成int64)。
  • 在网络定义部分,将输出层改成“输出十个标签的概率”的模式。
  • 在训练过程部分,将损失函数从均方误差换成交叉熵。

6【手写数字识别】优化算法

上一节明确了分类任务的损失函数(优化目标)的相关概念和实现方法,本节主要探讨在手写数字识别任务中,使得损失达到最小的参数取值的实现方法。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXkqVeM9-1661928958264)(https://ai-studio-static-online.cdn.bcebos.com/af41e7b72180495c96e3ed4a370e9e030addebdfd16d42bc9035c53ca5883cd9)]

前提条件

在优化算法之前,需要进行数据处理、设计神经网络结构,代码与上一节保持一致

设置学习率

深度学习神经网络模型中,通常使用标准的随机梯度下降算法更新参数,学习率代表参数更新幅度的大小,即步长。当学习率最优时,模型的有效容量最大,最终能达到的效果最好。

学习率的主流优化算法

SGD、Momentum、AdaGrad和Adam

  • SGD: 随机梯度下降算法,每次训练少量数据,抽样偏差导致的参数收敛过程中震荡。

  • Momentum: 引入物理“动量”的概念,累积速度,减少震荡,使参数更新的方向更稳定。

  • AdaGrad: 根据不同参数距离最优解的远近,动态调整学习率。学习率逐渐下降,依据各参数变化大小调整学习率。

  • Adam: 由于动量和自适应学习率两个优化思路是正交的,因此可以将两个思路结合起来,这就是当前广泛应用的算法。

7【手写数字识别】之资源配置

单GPU训练
分布式训练

分布式训练有两种实现模式:

模型并行,将一个网络模型拆分为多份,拆分后的模型分到多个设备上(GPU)训练,每个设备的训练数据是相同的。适用于模型架构过大、网络模型的结构设计相对独立的场景。

数据并行,每次读取多份数据,读取到的数据输入给多个设备(GPU)上的模型,每个设备上的模型是完全相同的

模型是完全相同,但是输入数据不同,因此每个设备的模型计算出的梯度不同

梯度同步机制保证每个设备的梯度是完全相同:PRC通信方式和NCCL2通信方式

PRC通信方式通常用于CPU分布式训练,它有两个节点:参数服务器Parameter server和训练节点Trainer,parameter server收集来自每个设备的梯度更新信息,并计算出一个全局的梯度更新。Trainer用于训练,每个Trainer上的程序相同,但数据不同。当Parameter server收到来自Trainer的梯度更新请求时,统一更新模型的梯度。

飞桨的GPU分布式训练使用的是基于NCCL2的通信方式,相比PRC通信方式,使用NCCL2(Collective通信方式)进行分布式训练,不需要启动Parameter server进程,每个Trainer进程保存一份完整的模型参数,在完成梯度计算之后通过Trainer之间的相互通信,Reduce梯度数据到所有节点的所有设备,然后每个节点在各自完成参数更新。

单机多卡程序
  1. 初始化并行环境。
  2. 使用paddle.DataParallel封装模型。

启动多GPU的训练,有两种方式:

  1. 基于launch启动;

    python train.py #单机单卡启动,默认使用第0号卡。
    python -m paddle.distributed.launch train.py #单机多卡,默认使用当前可见的所有卡。
    ython -m paddle.distributed.launch --gpus '0,1' --log_dir ./mylog train.py #单机多卡启动,设置当前使用的第0号和第1号卡。
    或者
    export CUDA_VISIABLE_DEVICES='0,1'
    python -m paddle.distributed.launch train.py
    
  2. 基于spawn方式启动。

    # 启动train多进程训练,默认使用所有可见的GPU卡。
    if __name__ == '__main__':dist.spawn(train)# 启动train函数2个进程训练,默认使用当前可见的前2张卡。
    if __name__ == '__main__':dist.spawn(train, nprocs=2)# 启动train函数2个进程训练,默认使用第4号和第5号卡。
    if __name__ == '__main__':dist.spawn(train, nprocs=2, selelcted_gpus='4,5')
    

8【手写数字识别】之训练调试与优化

训练过程优化思路主要有如下五个关键环节:

8.1 计算分类准确率,观测模型训练效果。

交叉熵损失函数只能作为优化目标,无法直接准确衡量模型的训练效果。准确率可以直接衡量训练效果,但由于其离散性质,不适合做为损失函数优化神经网络。通常情况下,交叉熵损失越小的模型,分类的准确率也越高。基于分类准确率,我们可以公平地比较两种损失函数的优劣。

例如在【手写数字识别】之损失函数章节中均方误差和交叉熵的比较。使用飞桨提供的计算分类准确率API,可以直接计算准确率:

class paddle.metric.Accuracy该API的输入参数input为预测的分类结果predict,输入参数label为数据真实的label。

在模型前向计算过程forward函数中计算分类准确率

8.2 检查模型训练过程,识别潜在训练问题

如果模型的损失或者评估指标表现异常,通常需要打印模型每一层的输入和输出来定位问题,以及每层网络的参数,分析每一层的内容来获取错误的原因。

使用check_shape变量控制是否打印“尺寸”,验证网络结构是否正确。

使用check_content变量控制是否打印“内容值”,验证数据分布是否合理。

假如在训练中发现中间层的部分输出持续为0,说明该部分的网络结构设计存在问题,没有充分利用。

8.3 加入校验或测试,更好评价模型效果
  • 校验集:用于对模型超参数的选择,比如网络结构的调整、正则化项权重的选择等。
8.4 加入正则化项,避免模型过拟合

过拟合现象:在训练集上的损失小,在验证集或测试集上的损失较大。反之,如果模型在训练集和测试集上均损失较大,则称为欠拟合。

导致过拟合原因:过拟合表示模型过于敏感,学习到了训练数据中的一些误差,而这些误差并不是真实的泛化规律,主要是训练数据量太少或其中的噪音太多。

过拟合的成因与防控:

​ 情况1:训练数据存在噪音,导致模型学到了噪音,而不是真实规律。——使用数据清洗和修正来解决。

​ 情况2:使用强大模型(表示空间大)的同时训练数据太少,导致在训练数据上表现良好的候选假设太多,锁定了一个“虚假正确”的假设。——限制模型表示能力,或者收集更多的训练数据。

正则化项:

为了防止模型过拟合,在没有扩充样本量的可能下,只能降低模型的复杂度,可以通过限制参数的数量或可能取值(参数值尽量小)实现。

具体来说,在模型的优化目标(损失)中人为加入对参数规模的惩罚项。当参数越多或取值越大时,该惩罚项就越大。通过调整惩罚项的权重系数,可以使模型在“尽量减少训练损失”和“保持模型的泛化能力”之间取得平衡。泛化能力表示模型在没有见过的样本上依然有效。正则化项的存在,增加了模型在训练集上的损失

飞桨支持为所有参数加上统一的正则化项,也支持为特定的参数添加正则化项。前者的实现如下代码所示,仅在优化器中设置weight_decay参数即可实现。使用参数coeff调节正则化项的权重,权重越大时,对模型复杂度的惩罚越高。

8.5 可视化分析
  • Matplotlib库:Matplotlib库是Python中使用的最多的2D图形绘图库,它有一套完全仿照MATLAB的函数形式的绘图接口,使用轻量级的PLT库(Matplotlib)作图是非常简单的。
  • VisualDL:如果期望使用更加专业的作图工具,可以尝试VisualDL,飞桨可视化分析工具。VisualDL能够有效地展示飞桨在运行过程中的计算图、各种指标变化趋势和数据信息。

9【手写数字识别】之恢复训练

只要随时保存训练过程中的模型状态,即使训练过程主动或被动中断,也不用从初始状态重新训练。

模型恢复训练,需要重新组网,所以需要重启AIStudio,运行MnistDataset数据读取和MNIST网络定义、Trainer部分代码,再执行模型恢复代码

  • 使用model.state_dict()获取模型参数。

  • 使用opt.state_dict获取优化器和学习率相关的参数。

  • 调用paddle.save将参数保存到本地。

    何判断模型是否准确的恢复训练呢?

    理想的恢复训练是模型状态回到训练中断的时刻,恢复训练之后的梯度更新走向是和恢复训练前的梯度走向完全相同的。基于此,我们可以通过恢复训练后的损失变化,判断上述方法是否能准确的恢复训练。即从epoch 0结束时保存的模型参数和优化器状态恢复训练,校验其后训练的损失变化(epoch 1)是否和不中断时的训练相差不多。

总结一下:

  • 保存模型时同时保存模型参数和优化器参数;
paddle.save(opt.state_dict(), 'model.pdopt')
paddle.save(model.state_dict(), 'model.pdparams')
  • 恢复参数时同时恢复模型参数和优化器参数。
model_dict = paddle.load("model.pdparams")
opt_dict = paddle.load("model.pdopt")model.set_state_dict(model_dict)
opt.set_state_dict(opt_dict)

10 【手写数字识别】之动转静部署

动态图 交互式编程

静态图 C++提速 性能优势

动态图转静态图训练

动态图转静态图训练其原理是通过分析Python代码,将动态图代码转写为静态图代码,并在底层自动使用静态图执行器运行。

使用方法:在要转化的函数(该函数也可以是用户自定义动态图Layer的forward函数)前添加一个装饰器 @paddle.jit.to_static,使动态图网络结构在静态图模式下运行。

动态图转静态图模型保存

动态图是即时执行即时得到结果,并不会记录模型的结构信息。需要先将动态图模型转换为静态图写法,编译得到对应的模型结构再保存

paddle.jit.save和paddle.jit.load接口

三种文件:保存模型结构的.pdmodel文件;保存推理用参数的.pdiparams文件和保存兼容变量信息的.pdiparams.info文件*

paddle.jit.save API 将输入的网络存储为 paddle.jit.TranslatedLayer 格式的模型

it.to_static,使动态图网络结构在静态图模式下运行。

动态图转静态图模型保存

动态图是即时执行即时得到结果,并不会记录模型的结构信息。需要先将动态图模型转换为静态图写法,编译得到对应的模型结构再保存

paddle.jit.save和paddle.jit.load接口

三种文件:保存模型结构的.pdmodel文件;保存推理用参数的.pdiparams文件和保存兼容变量信息的.pdiparams.info文件*

paddle.jit.save API 将输入的网络存储为 paddle.jit.TranslatedLayer 格式的模型

paddle.jit.load接口,可以把存储的模型载入为 paddle.jit.TranslatedLayer格式


paddlespeech体验

1.流式语音识别服务

服务端使用方法

在 PaddleSpeech/demos/streaming_asr_server 目录启动服务
paddlespeech_server start --config_file ./conf/ws_conformer_wenetspeech_application.yaml

使用方法:
paddlespeech_server start --help
参数:
config_file: 服务的配置文件,默认: ./conf/application.yaml
log_file: log 文件. 默认:./log/paddlespeech.log
注意:
默认部署在 cpu 设备上,可以通过修改服务配置文件中 device 参数部署在 gpu 上。

ASR 客户端使用方法

paddlespeech_client asr_online --server_ip 127.0.0.1 --port 8090 --input ./zh.wav

paddlespeech_client asr_online --help
参数:
server_ip: 服务端ip地址,默认: 127.0.0.1。
port: 服务端口,默认: 8090。
input(必须输入): 用于识别的音频文件。
sample_rate: 音频采样率,默认值:16000。
lang: 模型语言,默认值:zh_cn。
audio_format: 音频格式,默认值:wav。
punc.server_ip 标点预测服务的ip。默认是None。
punc.server_port 标点预测服务的端口port。默认是None。

2.流式语音合成服务

使用http协议的流式语音合成服务端及客户端使用方法
服務端:
paddlespeech_server start --config_file ./conf/tts_online_application.yaml

客戶端:
paddlespeech_client tts_online --server_ip 127.0.0.1 --port 8092 --protocol http --input “您好,欢迎使用百度飞桨语音合成服务。” --output output.wav

使用websocket协议的流式语音合成服务端及客户端使用方法
首先修改配置文件 conf/tts_online_application.yamlprotocol 设置为 websocket
paddlespeech_server start --config_file ./conf/tts_online_application.yaml
paddlespeech_client tts_online --server_ip 127.0.0.1 --port 8092 --protocol http --input “您好,欢迎使用百度飞桨语音合成服务。” --output output.wav

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

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

相关文章

14天刷爆LeetCode算法学习计划——Day02双指针(2)

Day02——双指针一、前言二、知识点三、LeetCode189. 轮转数组1.题目2.解题示意图3.解题思路4.代码实现5.验证代码6.注意点四、结语一、前言 盲目刷题只会让自己心态爆炸,所以本期14天算法学习计划,也是LeetCode上的 [算法] 学习计划,在本专栏…

【LeetCode】统计全 1 子矩形(单调栈)

1504. 统计全 1 子矩形 - 力扣(LeetCode) 一、题目 给你一个 m x n 的二进制矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。 示例 1: 输入:mat [[1,0,1],[1,1,0],[1,1,0]] 输出:13 解释&#x…

TCL基础学习 字符串

基本指令 Tcl将所有的变量值视作字符串,并将他们作为字符串来保存。下标列出了比较有用的字符串操作命令: append将值追加到字符串尾binary二进制字符串操作format字符串格式化regexp正则表达式regsub用字符串模式进行字符串模拟匹配和替换scan字符串分…

计算机网络面试(一)网络分层结构

文章目录为什么使用分层结构OSI参考模型分层结构——OSI参考模型ISO各个分层解析TCP/IP各个分层解析为什么使用分层结构 对网络分层以后,可以将问题细化,使得问题更加容易分析。把一个大的系统分拆成小的体系后,便于在各个层次上制定标准&am…

《三叶虫与其他故事》我的恐惧如涟漪扩散,荡漾过百万年的时光

《三叶虫与其他故事》我的恐惧如涟漪扩散,荡漾过百万年的时光 布里斯D’J.潘凯克 Breece D‘J Pancake(1952-1979),美国作家。二十六岁时自杀身亡,生前仅发表过六篇小说。潘凯克深受美国南方文学传统的影响&#xff0c…

3dmax的Corona的渲染器材质要如何完全转换VRay材质?

经常有伙伴问怎么转化材质,将CR转换成vr或者将VR转换CR~其实这一点需要通过材质转换插件即可转换~ 方法一:cr转vr材质,自带 第一步:确认自己的corona渲染器版本为corona5及以上: ​ 第2步 确认自己的vray渲染器版本…

springboot手机推荐网站毕业设计源码052329

摘 要 随着社会的发展,计算机的优势和普及使得手机推荐网站的开发成为必需。手机推荐网站主要是借助计算机,通过对首页、手机问答、公告消息、手机资讯、手机测评、我的、跳转到后台等信息进行管理。减少管理员的工作,同时也方便广大用户对个…

voip|网络电话,软件实现电信座机

原理 我们办理的宽带一般都含有座机服务,有一个座机号,自己买个座机插到光猫的语音口上就能用。光猫内置语音服务,座机通过电话线接上光猫来打电话,这个语音服务本质上是VOIP,基于IP的语音传输,光猫在VOIP…

Python输入漏洞利用(Python input漏洞)

背景条件 源码为python编写的程序该程序包含input函数,利用用户或自动化输入获取参数进行下一步 漏洞函数 input():接收用户输入且不修改输入的类型raw_input():接收用户输入并强制修改为字符串类型 漏洞源码示例 #!/usr/bin/python3 #-*- …

Revit中模板类图元使用后如何处理?

Revit中模板类图元使用后如何处理? 模板这类图元在使用结束后进行拆除的在正常建模形之后它就会一直存在虽然我们可以进行视图处理,但是新建立视图还会显示这类图元,我们可以用其他方法处理它么? 这里我们可以用阶段化来控制,这里以小别墅为…

通过配置文件修改docker容器端口映射

有时候,我们需要给正在运行的容器添加端口映射,百度一下发现很多都是通过iptables,或者是通过将当前容器通过docker commit命令提交为一个镜像,然后重新执行docker run命令添加端口映射。这种方法虽然可以,但是感觉好像…

java基于ssm课程建设制作服务平台系统

1.分管理员和客户,分别有注册账号,修改密码,等功能。2.管理员模块可以在不同的专业专栏上传视频,word文稿,并修改视频名,文稿,视频的增删功能,并给视频标注A B C三个等级3.用户可以在不同的专业专栏观看视频(可以看到abc等级),可以下载管理员所上传文稿,…

【图解HTTP】HTTP协议基础

【HTTP协议用于客户端和服务器端之间的通信】 【客户端】请求访问文本或图像等资源的一段 【服务器端】提供资源响应的一端 客户端发送请求,服务器端回复响应 从客户端开始建立通信的,服务器端在没有接受到请求之前不会发送响应。 【请求报文】 【响…

Python 测试开发 20+ 项目实战,提升 5 大测试核心技能

⬇️ 点击“下方链接”,提升测试核心竞争力! >>更多技术文章分享和免费资料领取 软件测试行业从业门槛越来越高,传统手工测试人员逐渐被淘汰,而 测试开发工程师 则供不应求,成为 BAT 互联网大厂高薪求聘的稀缺人才,年薪 30W+ 起,年薪 50W-100W+ 也很常见,甚至超越…

【vue3】03. 跟着官网学习vue3

每日鸡汤:所有真实的快乐,都来自很久的努力 前言 这一节我们主要学习【模版语法】相关的知识,上一节,我们说到根目录下面的index.html是我们的根组件模版,所以可见模版语法是基于html的。 一、模版基本语法 1. 使用…

人工智能+工业互联网,如何破圈?

如何破圈? 2022年奥密克戎的袭击还没阻断,金三银四的寒冬还没挺过,大厂裁员就喧嚣尘上,内卷的战争愈演愈烈。 但我认为,自身有一些加分项,对于还击压力还是能有一些优势。 对于每位开发者来说&#xff0c…

Python进阶(三)-图形界面编程Tkinter(3)

三、Tkinter创建图像界面3 3.1 组件介绍 3.1.1 Listbox列表框 首先介绍一下列表框,即 Listbox。在使用 Tkinter 进行 GUI 编程的过程中,如果需要用户自己进行选择时就可以使用列表框控件。列表框中的选项可以是多个条目,也可以是单个唯一条…

Jenkins持续集成部署-配置Harbor机器人账号推送镜像

Jenkins持续集成部署-配置Harbor机器人账号推送镜像 前言1. 新建 Harbor 机器人账号2. 配置到 Jenkins 全局凭证中3. 配置全局参数后记前言 在某些情况下,为了 Harbor仓库的安全性考虑,在 流水线任务中直接配置用户的话,后面还要维护其权限,命名项目是公开的了,登录成功 …

[Java]快速入门二叉树,手撕相关面试题

专栏简介 :java语法及数据结构 题目来源:leetcode,牛客,剑指offer 创作目标:从java语法角度实现底层相关数据结构,达到手撕各类题目的水平. 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 前言 一>树形结…

第三方库

Python拥有活跃的贡献者和用户支持社区,并且根据开放源代码许可条款,其软件可供其他Python开发人员使用,这是python之所以这么受欢迎的原因之一。 第三方库就是非python自带的,由其他人写的python模块。 pypi是python官方的第三方库仓库,所有人都可以下载第三方库或上传自…