【每日算法】理论:图像分割相关 刷题:设计链表

上期文章

【每日算法】理论:AIGC微调技术 刷题:滑动窗口、循环


一、上期问题

  • dreambooth微调模型的原理
  • lora微调模型的原理
  • controlnet模型的创新点
  • 解释focal loss
  • 如何判断GAN收敛或者不稳定
  • stable diffusion模型的图像优化模块是什么架构

二、理论问题

1、变形自注意力模块的特别之处

变形自注意力模块主要由两个组成部分构成:偏移模块和注意力模块。在将向量集成到偏移模块之前,必须将其转换为特征图,然后生成输入 Query 向量,同时考虑参考点的坐标。将输入特征图和Query向量进行线性变换后一同输入到偏移模块中,将偏移模块产出的结果与Query向量输入到注意力模块中得到最终结果。可变形注意力的运用可以动态地调整注意力模型的形状和大小,以更好地适应不同任务和输入数据的特点。

可变形注意力(Deformable Attention)及其拓展

2、GroundingDino模型的损失函数是什么?

Grounding DINO的损失函数由定位损失localization loss(也就是回归损失)和分类损失两部分组成。其中定位损失使用的是L1损失及GIOU损失,分类损失使用的是预测目标和文字token之间的对比损失(交叉熵损失)。

前序问题:GroundingDino模型的网络架构

Grounding DINO:开放集目标检测,将基于Transformer的检测器DINO与真值预训练相结合

3、Dice Loss

Dice Loss主要是为了解决语义分割中正负样本极度不平衡问题。Dice Loss是由Dice系数而得名的,Dice Loss=1-Dice Coefficient。Dice系数是一种用于评估两个样本相似性的度量函数,其值越大意味着这两个样本越相似,Dice系数的数学表达式如下:

d i c e = 2 ∣ X ⋂ Y ∣ ∣ X ∣ + ∣ Y ∣ dice=\frac{2|X\bigcap Y|}{|X|+|Y|} dice=X+Y2∣XY

4、UNet的网络架构

UNet架构是专门为图像分割任务设计的深度学习模型。 UNet架构对称的编码器和解码器组成。编码器由一系列卷积层和最大池化层组成,用于对输入图像进行下采样并提取特征。解码器由卷积层和上采样层组成,它们对收缩路径中的特征图进行上采样,并将它们与输入图像中的特征组合以生成最终的分割图。另外,unet架构中还有一个跳跃连接的部分,用于将编码器中的特征与解码器的对应层相结合,以便恢复图像的分辨率,提高分割图的精度。

5、VQVAE模型相对于VAE的改进

VQVAE通过Encoder学习出中间编码,然后通过最邻近搜索将中间编码映射为codebook中K个向量之一,然后通过Decoder对 latent code进行重建。VQ-VAE与VAE的最主要的区别是VQ-VAE采用离散隐变量。对于encoder的输出通过向量量化(vector quantisation,VQ)的方法来离散化。简单来说, 就是要先有一个codebook, 这个codebook是一个embedding table. 我们在这个table中找到和vector最接近(比如欧氏距离最近)的一个embedding, 用这个embedding的index来代表这个vector。

AutoEncoder自动编码器、VAE变分自编码器、VQVAE量子化(离散化)的自编码器

6、Deepfloyd-if模型

DeepFloyd-if模型解决了文生图场景中绘制文字和理解空间关系这两大难题。DeepFloyd IF是一个模块化的、级联的、像素扩散模型。它由一个固定的文本编码器和三个级联的像素扩散模块组成。基本扩散模型根据用户输入的文本提示生成 64x64 像素的图像,之后的两个超分辨率模型分别用于生成分辨率256x256像素和1024x1024像素的图像。模型的所有阶段都使用基于 T5 变换器的固定文本编码器提取文本嵌入,然后将其输入到增强了跨注意力和注意力池化的 UNet 架构中。最终得到的是一种高效的模型。

DeepFloyd IF:由文本生成图像的强大模型,能够绘制文字的 AI 图像工具

三、力扣刷题回顾-链表

上期涉及题目:

本期题目:


707.设计链表

选择使用单链表或者双链表,设计并实现自己的链表。

实现 MyLinkedList 类需要包括的内容:

  • 初始化 MyLinkedList 对象的函数。
  • 获取链表中下标为 index 的节点的值的函数。
  • 将一个值为 val 的节点插入到链表中第一个元素之前的函数。
  • 将一个值为 val 的节点追加到链表中作为链表的最后一个元素的函数。
  • 将一个值为 val 的节点插入到链表中下标为 index 的节点之前的函数。
  • 删除链表中下标为 index 的节点的函数

单链表法:

  • 先要定义一个创建节点的类

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

  • 在对链表类MyLinkedList进行初始化时,定义一个虚拟头节点会方便很多
class ListNode:
    def __init__(self,val=0,next=None):
        self.val=val
        self.next=next

class MyLinkedList:

    def __init__(self):
        self.dummy_head=ListNode()
        self.size=0

    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:
            return -1
        current=self.dummy_head.next
        for i in range(index):
            current=current.next
        return current.val

    def addAtHead(self, val: int) -> None:
        self.dummy_head.next=ListNode(val,self.dummy_head.next)
        self.size+=1

    def addAtTail(self, val: int) -> None:
        current=self.dummy_head
        while current.next:
            current=current.next
        current.next=ListNode(val)
        self.size+=1

    def addAtIndex(self, index: int, val: int) -> None:
        if index < 0 or index > self.size:
            return 
        current=self.dummy_head
        for i in range(index):
            current=current.next
        current.next=ListNode(val,current.next)
        self.size+=1

    def deleteAtIndex(self, index: int) -> None:
        current=self.dummy_head
        if index < 0 or index >= self.size:
            return 
        for i in range(index):
            current=current.next
        current.next=current.next.next
        self.size-=1



# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

双链表法:

双链表中的节点应该具备三个属性:val、next 和 prev 。val 是当前节点的值,next 是指向下一个节点的指针/引用, prev 是指示链表中的上一个节点。

class ListNode:
    def __init__(self,val=0,prev=None,next=None):
        self.val=val
        self.prev=prev
        self.next=next

class MyLinkedList:

    def __init__(self):
        self.head=None
        self.tail=None
        self.size=0

    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:
            return -1

        if index < self.size // 2:
            current=self.head
            for i in range(index):
                current=current.next
        else:
            current=self.tail
            for i in range(self.size-index-1):
                current=current.prev
        return current.val

    def addAtHead(self, val: int) -> None:
        newnode=ListNode(val,None,self.head)
        if self.head:
            self.head.prev=newnode
        else:
            self.tail=newnode
        self.head=newnode
        self.size+=1

    def addAtTail(self, val: int) -> None:
        newnode=ListNode(val,self.tail,None)
        if self.tail:
            self.tail.next=newnode
        else:
            self.head=newnode
        self.tail=newnode
        self.size+=1

    def addAtIndex(self, index: int, val: int) -> None:
        if index < 0 or index > self.size:
            return 
        if index == 0:
            self.addAtHead(val)
        elif index==self.size:
            self.addAtTail(val)
        else:
            if index < self.size // 2:
                current=self.head
                for i in range(index-1):
                    current=current.next
            else:
                current=self.tail
                for i in range(self.size-index):
                    current=current.prev
            newnode=ListNode(val,current,current.next)
            current.next.prev=newnode
            current.next=newnode
            self.size+=1

    def deleteAtIndex(self, index: int) -> None:
        if index < 0 or index >=self.size:
            return
        if index == 0:
            self.head=self.head.next
            if self.head:
                self.head.prev=None
            else:
                self.tail=None
        elif index ==self.size-1:
            self.tail=self.tail.prev
            if self.head:
                self.tail.next=None
            else:
                self.head=None
        else:
            if index < self.size // 2:
                current=self.head
                for i in range(index):
                    current=current.next
            else:
                current=self.tail
                for i in range(self.size-index-1):
                    current=current.prev
            current.prev.next=current.next
            current.next.prev=current.prev
        self.size-=1



# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

参考:代码随想录算法训练营第三天|链表理论基础,203.移除链表元素,707.设计链表,206.反转链表

  • 22
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值