【每日算法】理论:深度学习基础 刷题:KMP算法思想

news2024/11/16 22:26:15

上期文章

【每日算法】理论:常见网络架构 刷题:力扣字符串回顾

文章目录

  • 上期文章
  • 一、上期问题
  • 二、本期理论问题
      • 1、注意力机制
      • 2、BatchNorm 和 LayerNorm 的区别
      • 3、Bert 的参数量是怎么决定的。
      • 4、为什么现在的大语言模型都采用Decoder only架构?
      • 5、什么是梯度消失和爆炸
      • 6、梯度消失和梯度爆炸产生的原因
  • 三、力扣刷题回顾-字符串
      • 151.翻转字符串里的单词
      • 右旋字符串
      • KMP算法
      • 28. 实现 strStr()
      • 459.重复的子字符串


一、上期问题

  • clip编码优缺点
  • Torch 和 Tensorflow 的区别
  • RNN
  • 1x1卷积在卷积神经网络中有什么作用
  • AIGC 存在的问题
  • AlexNet

二、本期理论问题

1、注意力机制

注意力机制是一种机制,用于在处理序列数据时动态地给予不同位置的输入不同的权重。在Transformer模型中,注意力机制通过计算查询、键和值之间的关联性来实现,从而在编码器和解码器之间传递信息并捕捉输入序列中的关键信息。自注意力机制允许模型在不同位置上关注不同程度的信息,有助于解决长距离依赖问题。

2、BatchNorm 和 LayerNorm 的区别

LN中同层神经元输入拥有相同的均值和方差,不同的输入样本有不同的均值和方差;BN中则针对不同神经元输入计算均值和方差,同一个batch中的输入拥有相同的均值和方差。

LN不依赖于batch的大小和输入sequence的深度,因此可以用于batchsize为1和RNN中对变长的输入sequence的normalize操作。由于NLP中的文本输入一般为变长,所以使用layernorm更好。

3、Bert 的参数量是怎么决定的。

Bert的参数量由其模型结构以及隐藏层的大小、层数等超参数所决定。具体来说,Bert 模型由多个 Transformer Encoder 层组成,每个 Encoder 层包含多个注意力头以及前馈神经网络层。因此,Bert 的参数量主要由这些层的数量、每层的隐藏单元数、注意力头的数量等因素决定。

4、为什么现在的大语言模型都采用Decoder only架构?

大模型从模型架构上主要分为三种:Only-encoder, Only-Decoder, Encoder-Decoder三种模型架构

  • Only-encoder:例如BERT,通过在大规模无标签文本上进行预训练,然后在下游任务上进行微调,具有强大的语言理解能力和表征能力。
  • Only-Decoder: 例如GPT,通过在大规模无标签文本上进行预训练,然后在特定任务上进行微调,具有很强的生成能力和语言理解能力。
  • Encoder-Decoder:例如T5,可以用于多种自然语言处理任务,如文本分类、机器翻译、问答等。

LLM之所以主要都用Decoder-only架构,除了训练效率和工程实现上的优势外,在理论上是因为Encoder的双向注意力会存在低秩问题,这可能会削弱模型表达能力,就生成任务而言,引入双向注意力并无实质好处。而Encoder-Decoder架构之所以能够在某些场景下表现更好,大概只是因为它多了一倍参数。所以,在同等参数量、同等推理成本下,Decoder-only架构就是最优选择了。

5、什么是梯度消失和爆炸

梯度消失是指在深度学习训练的过程中,梯度随着 BP 算法中的链式求导逐层传递逐层减小,最后趋近于0,导致对某些层的训练失效;梯度爆炸与梯度消失相反,梯度随着 BP 算法中的链式求导逐层传递逐层增大,最后趋于无穷,导致某些层无法收敛;

6、梯度消失和梯度爆炸产生的原因

出现梯度消失和梯度爆炸的问题主要是因为参数初始化不当以及激活函数选择不当造成的。其根本原因在于反向传播训练法则,前面层上的梯度是来自于后面层上梯度的乘积,属于先天不足。当训练较多层数的模型时,一般会出现梯度消失问题和梯度爆炸问题。

三、力扣刷题回顾-字符串

上期涉及题目:

  • 344.反转字符串
  • 541. 反转字符串II
  • 替换数字

本期题目:

  • 151.翻转字符串里的单词
  • 右旋字符串
  • 28. 实现 strStr()
  • 459.重复的子字符串

151.翻转字符串里的单词:

  • 给定输入:一个字符串 s
  • 要求输出:反转字符串中单词的顺序

右旋字符串:

  • 给定输入:一个字符串 s 和一个正整数 k
  • 要求输出:将字符串中的后面 k 个字符移到字符串的前面

28. 实现 strStr():

  • 给定输入:两个字符串 haystack 和 needle
  • 要求输出:在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标。如果 needle 不是 haystack 的一部分,则返回 -1 。

459.重复的子字符串:

  • 给定输入:一个非空的字符串 s
  • 要求输出:检查是否可以通过由它的一个子串重复多次构成

对比分析:
151.翻转字符串里的单词右旋字符串两道题都是字符串章节较为简单的题目,151.翻转字符串里的单词可以采用双指针的思想解决,右旋字符串使用字符串切片即可。28. 实现 strStr()459.重复的子字符串是两道运用KMP算法的字符串题。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。


151.翻转字符串里的单词

class Solution:
    def reverseWords(self, s: str) -> str:
        lst=s.split()
        left,right=0,len(lst)-1
        while left < right:
            lst[left],lst[right] = lst[right],lst[left]
            left += 1
            right -= 1
        return " ".join(lst)

右旋字符串

k=int(input())
s=input()
left=len(s)-k
right=len(s)
s=s[left:right]+s[:left]
print(s)

KMP算法

  • KMP算法是用来解决字符串匹配的问题: 在一个串中查找是否出现过另一个串。
  • KMP的经典思想: 当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
  • KMP中记录已经匹配的文本内容的关键是前缀表: 前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。前缀表中下标i对应的值就是记录了下标i之前(包括i)的字符串中有多大长度的相同前缀后缀。
  • 前缀表为什么可以记录下一次匹配的位置:

下标5之前这部分的字符串(也就是字符串aabaa)的最长相等的前缀 和 后缀字符串是 子字符串aa ,因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面重新匹配就可以了。
在这里插入图片描述

  • 前缀表的计算:
    长度为前1个字符的子串a,最长相同前后缀的长度为0。(注意字符串的前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。)
    在这里插入图片描述
    长度为前2个字符的子串aa,最长相同前后缀的长度为1。
    在这里插入图片描述
    长度为前3个字符的子串aab,最长相同前后缀的长度为0。
    在这里插入图片描述
    以此类推: 长度为前4个字符的子串aaba,最长相同前后缀的长度为1。 长度为前5个字符的子串aabaa,最长相同前后缀的长度为2。 长度为前6个字符的子串aabaaf,最长相同前后缀的长度为0。

那么把求得的最长相同前后缀的长度就是对应前缀表的元素在这里插入图片描述

28. 实现 strStr()

  • 定义next数组(前缀表):
    • 初始化
    • 定义两个指针分别遍历前缀和后缀
    • 然后分别处理前后缀相同和不同的情况
    • 更新next数组的值
  • 进行匹配
    • 获得子串的next数组
    • 定义两个指针分别遍历子串和父串
    • 依次匹配,分别处理匹配成功和匹配不成功的情况
class Solution:
    def getNext(self,next,s):
        # 初始化next数组
        next[0] = 0
        # 定义两个指针i和j,j指向前缀末尾位置,i指向后缀末尾位置
        j = 0
        for i in range(1,len(s)):
            # 前后缀末尾不相同的情况,就要向前回退
            while j > 0 and s[i] != s[j]:
                j = next[j-1]
            # 前后缀相同时,就同时向后移动i 和j
            if s[i] == s[j]:
                j += 1
            # 将j(前缀的长度)赋给next[i], 因为next[i]要记录相同前后缀的长度
            next[i] = j

    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) == 0:
            return 0
        next = [0] * len(needle)
        self.getNext(next,needle)
        j=0
        for i in range(len(haystack)):
            while j > 0 and haystack[i] != needle[j]:
                j = next[j-1]
            if haystack[i] == needle[j]:
                j += 1
            if j == len(needle):
                return i-len(needle)+1
        return -1

459.重复的子字符串

  • 定义next数组(前缀表):
    • 初始化
    • 定义两个指针分别遍历前缀和后缀
    • 然后分别处理前后缀相同和不同的情况
    • 更新next数组的值
  • 进行匹配
    数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。
class Solution:
    def getNext(self,next,s):
        # 初始化next数组
        next[0] = 0
        # 定义两个指针i和j,j指向前缀末尾位置,i指向后缀末尾位置
        j = 0
        for i in range(1,len(s)):
            # 前后缀末尾不相同的情况,就要向前回退
            while j > 0 and s[i] != s[j]:
                j = next[j-1]
            # 前后缀相同时,就同时向后移动i 和j
            if s[i] == s[j]:
                j += 1
            # 将j(前缀的长度)赋给next[i], 因为next[i]要记录相同前后缀的长度
            next[i] = j


    def repeatedSubstringPattern(self, s: str) -> bool:
        if len(s) == 0:
            return False
        next = [0]*len(s)
        self.getNext(next,s)
        if next[-1] != 0 and len(s)%(len(s)-next[-1]) == 0:
            return True
        return False

参考:
代码随想录算法训练营第七天|344.反转字符串,541. 反转字符串II,卡码网:54.替换数字,151.翻转字符串里的单词,卡码网:55.右旋转字符串
代码随想录算法训练营第八天|28. 实现 strStr(),459.重复的子字符串,字符串总结,双指针回顾

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

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

相关文章

【CAD打开提示未处理异常C0000027(c0000027h)的两种解决方法。】

cad打开提示错误c0000027h的第一种解决方法 去掉区域里的beta语言勾选。 https://autodesk8.com/cad/86.html 如果第一种方法没解决&#xff0c;尝试第二种方法大概率能解决 点击autoremove的扩展功能&#xff0c;输入c0000027点击搜索&#xff0c;然后双击出现的这个按钮既可…

键盘打字练习游戏代码

效果图 部分代码 index.html <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width, initial-scale1.0" /> <meta http-equiv"…

初识java——jdk?环境变量?及关于安装jdk的步骤

文章目录 JDK的安装在安装JDK时遇到的问题&#xff1a; 背景知识一 什么是jdkjdk简介jdk文件详解&#xff1a;1 bin目录&#xff1a;2 lib目录&#xff1a;3 include目录.exe文件是可执行的应用程序&#xff0c;这个我们都清楚&#xff0c;但.dll文件又是做什么的呢&#xff1f…

论文笔记:Leveraging Language Foundation Models for Human Mobility Forecasting

SIGSPATIAL 2022 1intro 语言模型POI客流量预测 2 方法 3 实验

Uds诊断协议的请求和响应的寻址

一根总线上挂载着很多ECU&#xff0c;那么基于CAN协议UDS的诊断请求报文&#xff0c;诊断仪是如何发给ECU的&#xff1f;如何精准的找到想要诊断的那个ECU&#xff1f;ECU又是如何将诊断响应的报文返回给诊断仪&#xff1f; 在UDS协议中&#xff0c;规定了诊断请求和响应报文发…

macSubstrate:一款针对macOS的代码注入和打桩测试工具

关于macSubstrate macSubstrate是一款针对macOS的代码注入和打桩测试工具&#xff0c;该工具可以在macOS操作系统上实现进程间代码注入测试&#xff0c;其功能类似于iOS上的Cydia Substrate。 在该工具的帮助下&#xff0c;广大研究人员可以轻松将自己的安全测试插件&#xff…

8-云原生监控体系-PromQL-函数

Prometheus支持几个函数来操作数据。 文章目录 1. 函数语法解释2. count(v instant-vector)3. topk(n, v instant-vector)4. bottomk(n, v instant-vector)5. increase(v range-vector)6. rate(v range-vector)7. rate 和 increase8. irate(v range-vector)9. predict_linear(…

HubSpot流量转化:从访客到客户的转化策略

在当今数字化时代&#xff0c;企业营销获客的关键在于如何将网站访客转化为实际客户。作为HubSpot的合作伙伴&#xff0c;我们深知HubSpot软件在流量转化方面的强大功能。今天运营坛将带领大家深入探讨HubSpot流量转化的核心原理&#xff0c;并介绍如何利用个性化营销策略、构建…

【C++】友元--最全解析(友元是什么?我们应该如何理解友元?友元可以应用在那些场景?)

目录 一、前言 二、友元是什么&#xff1f; 三、友元的感性理解和分类 &#x1f95d;友元的感性理解 &#x1f34b;友元的三种分类 ✨友元 --- 全局函数 ✨友元 --- 成员函数 ✨友元 --- 类 四、友元函数的应用场景 &#x1f34d;操作符重载 :"<<" 与…

【苍穹外卖】HttpClient-快速理解入门

目录 HttpClient-快速理解&入门1. 需求2. 如何使用3. 具体示例4. 大致优点5. 大致缺点 HttpClient-快速理解&入门 1. 需求 在平常访问服务器里面的资源的时候&#xff0c;我们通常是通过浏览器输入网址&#xff08;或者在浏览器点击某个连接&#xff09;这种方式&…

更换本地yum源的步骤

更换本地yum源的流程与命令&#xff1a;

Idea热部署插件JRebel,修改代码无需重启

1. 介绍 JRebel是一个实用的插件&#xff0c;它可以让你在不重启服务器的情况下&#xff0c;修改Java程序并即时生效。相信大家都有这样的经历&#xff1a;每次修改代码后都需要重新编译、打包、部署&#xff0c;然后重启服务器&#xff0c;这个过程非常耗时且繁琐。但是&…

二叉树的实现(前序、中序、后序)(全面)

上一篇我们学习的二叉树的理论&#xff0c;知道了什么是二叉树之后&#xff0c;我们来实现一棵二叉树&#xff0c;二叉树经常考的是前中后序的遍历&#xff0c;这里我们多实现一些功能。 1.二叉树功能 二叉树的实现充分利用了分治思想 1.前序遍历 2.中序遍历 3.后序遍历 4.树的…

Vision Pro零基础教程专栏:校准、对比与结果分析工具

文章目录 CogCalibCheckerboardTool 校准工具介绍校准的基本方法与过程校准的基本作用标定片标定板定义标定板分类基础版标定板校准版标定板DataMatrix代码标定板特殊功能标定板材质分类 使用步骤注意 CogPatInspectTool 对比工具介绍CogPatInspectTool示例图使用场景使用步骤参…

JumpServer搭建堡垒机实战

文章目录 第一步、下载安装第二步、访问异常处理【1】docker方式拉取失败 JumpServer是运维人员可连接内部服务器上进行操作&#xff0c;支持Linux等操作系统的管理工具。 第一步、下载安装 curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver/releases/latest/…

Opencv Python图像处理笔记一:图像、窗口基本操作

文章目录 前言一、输入输出1.1 图片读取显示保存1.2 视频读取保存1.3 文件读取保存 二、GUI2.1 窗口2.2 轨迹条2.3 画图2.4 鼠标回调 三、图像入门操作3.1 颜色空间转化3.2 通道分离合并3.3 添加边框3.4 算数操作 四、二值化4.1 普通4.2 自适应4.3 Otsu 参考 前言 随着人工智能…

227基于matlab的作业调度问题

基于matlab的作业调度问题。采用遗传算法&#xff0c;解决作业调度问题。一共三个作业&#xff0c;每个作业有不同的时间长度和紧急程度&#xff0c;超过时间会有惩罚措施。通过遗传算法计算出最好的作业安排&#xff0c;使得惩罚最小&#xff0c;获益最大。最终结果通过GUI用甘…

了解IPS和IDS:这5个差异将改变你的安全观念!

IPS 代表 入侵防御系统&#xff08;Intrusion Prevention System&#xff09;&#xff0c;它是 IDS 的进一步发展&#xff0c;不仅具备检测攻击的能力&#xff0c;还能在检测到攻击后主动采取措施阻止攻击。IPS 通常部署在防火墙和网络设备之间&#xff0c;能够深度感知并检测流…

第八周学习笔记DAY.1-异常

本课目标 了解异常概念 理解Java异常处理机制 会捕捉异常 会抛出异常 了解Java异常体系结构 什么是异常 异常是指在程序的运行过程中所发生的不正常的事件&#xff0c;它会中断正在运行的程序 生活中&#xff0c;根据不同的异常进行相应的处理&#xff0c;而不会就此中断…

支持中文繁体,支持同时配置并启用飞书和Lark认证,JumpServer堡垒机v3.10.8 LTS版本发布

2024年4月22日&#xff0c;JumpServer开源堡垒机正式发布v3.10.8 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和优化&#xff0c;并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS最新版本&#xff0c;以获得更佳的使用体验。 在v3.10.8 LTS版本中&…