上期文章
文章目录
一、上期问题
- 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∣+∣Y∣2∣X⋂Y∣
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)