Learning Memory-guided Normality代码学习笔记

记忆模块核心

Memory部分的核心在于以下定义Memory类的部分。

class Memory(nn.Module):
def __init__(self, memory_size, feature_dim, key_dim, temp_update, temp_gather):
super(Memory, self).__init__()
# Constants
self.memory_size = memory_size
self.feature_dim = feature_dim
self.key_dim = key_dim
self.temp_update = temp_update
self.temp_gather = temp_gather def hard_neg_mem(self, mem, i):
similarity = torch.matmul(mem,torch.t(self.keys_var))
similarity[:,i] = -1
_, max_idx = torch.topk(similarity, 1, dim=1) return self.keys_var[max_idx] def random_pick_memory(self, mem, max_indices): m, d = mem.size()
output = []
for i in range(m):
flattened_indices = (max_indices==i).nonzero()
a, _ = flattened_indices.size()
if a != 0:
number = np.random.choice(a, 1)
output.append(flattened_indices[number, 0])
else:
output.append(-1) return torch.tensor(output) def get_update_query(self, mem, max_indices, update_indices, score, query, train): m, d = mem.size()
if train:
query_update = torch.zeros((m,d)).cuda()
# random_update = torch.zeros((m,d)).cuda()
for i in range(m):
idx = torch.nonzero(max_indices.squeeze(1)==i)
a, _ = idx.size()
if a != 0:
query_update[i] = torch.sum(((score[idx,i] / torch.max(score[:,i])) *query[idx].squeeze(1)), dim=0)
else:
query_update[i] = 0 return query_update else:
query_update = torch.zeros((m,d)).cuda()
for i in range(m):
idx = torch.nonzero(max_indices.squeeze(1)==i)
a, _ = idx.size()
if a != 0:
query_update[i] = torch.sum(((score[idx,i] / torch.max(score[:,i])) *query[idx].squeeze(1)), dim=0)
else:
query_update[i] = 0 return query_update def get_score(self, mem, query):
bs, h,w,d = query.size()
m, d = mem.size() score = torch.matmul(query, torch.t(mem))# b X h X w X m
score = score.view(bs*h*w, m)# (b X h X w) X m score_query = F.softmax(score, dim=0)
score_memory = F.softmax(score,dim=1) return score_query, score_memory def forward(self, query, keys, train=True): batch_size, dims,h,w = query.size() # b X d X h X w
query = F.normalize(query, dim=1)
query = query.permute(0,2,3,1) # b X h X w X d #train
if train:
#losses
separateness_loss, compactness_loss = self.gather_loss(query,keys, train)
# read
updated_query, softmax_score_query,softmax_score_memory = self.read(query, keys)
#update
updated_memory = self.update(query, keys, train) return updated_query, updated_memory, softmax_score_query, softmax_score_memory, separateness_loss, compactness_loss #test
else:
# loss
compactness_loss, query_re, top1_keys, keys_ind = self.gather_loss(query,keys, train) # read
updated_query, softmax_score_query,softmax_score_memory = self.read(query, keys) #update
updated_memory = keys return updated_query, updated_memory, softmax_score_query, softmax_score_memory, query_re, top1_keys,keys_ind, compactness_loss def update(self, query, keys,train): batch_size, h,w,dims = query.size() # b X h X w X d softmax_score_query, softmax_score_memory = self.get_score(keys, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) _, gathering_indices = torch.topk(softmax_score_memory, 1, dim=1)
_, updating_indices = torch.topk(softmax_score_query, 1, dim=0) if train: query_update = self.get_update_query(keys, gathering_indices, updating_indices, softmax_score_query, query_reshape,train)
updated_memory = F.normalize(query_update + keys, dim=1) else:
query_update = self.get_update_query(keys, gathering_indices, updating_indices, softmax_score_query, query_reshape, train)
updated_memory = F.normalize(query_update + keys, dim=1) return updated_memory.detach() def pointwise_gather_loss(self, query_reshape, keys, gathering_indices, train):
n,dims = query_reshape.size() # (b X h X w) X d
loss_mse = torch.nn.MSELoss(reduction='none') pointwise_loss = loss_mse(query_reshape, keys[gathering_indices].squeeze(1).detach()) return pointwise_loss def gather_loss(self,query, keys, train):
batch_size, h,w,dims = query.size() # b X h X w X d
if train:
loss = torch.nn.TripletMarginLoss(margin=1.0)
loss_mse = torch.nn.MSELoss()
softmax_score_query, softmax_score_memory = self.get_score(keys, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) _, gathering_indices = torch.topk(softmax_score_memory, 2, dim=1) #1st, 2nd closest memories
pos = keys[gathering_indices[:,0]]
neg = keys[gathering_indices[:,1]]
top1_loss = loss_mse(query_reshape, pos.detach())
gathering_loss = loss(query_reshape,pos.detach(), neg.detach()) return gathering_loss, top1_loss else:
loss_mse = torch.nn.MSELoss() softmax_score_query, softmax_score_memory = self.get_score(keys, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) _, gathering_indices = torch.topk(softmax_score_memory, 1, dim=1) gathering_loss = loss_mse(query_reshape, keys[gathering_indices].squeeze(1).detach()) return gathering_loss, query_reshape, keys[gathering_indices].squeeze(1).detach(), gathering_indices[:,0] def read(self, query, updated_memory):
batch_size, h,w,dims = query.size() # b X h X w X d softmax_score_query, softmax_score_memory = self.get_score(updated_memory, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) concat_memory = torch.matmul(softmax_score_memory.detach(), updated_memory) # (b X h X w) X d
updated_query = torch.cat((query_reshape, concat_memory), dim = 1) # (b X h X w) X 2d
updated_query = updated_query.view(batch_size, h, w, 2*dims)
updated_query = updated_query.permute(0,3,1,2) return updated_query, softmax_score_query, softmax_score_memory

Update过程

调用get_update_query(self, mem, max_indices, update_indices, score, query, train)函数计算\(query\_ dpdate= \sum_{k \in U_{t}^M} v_t^{'k,m}q_t^k\)

然后计算\(f(P^m+query_dpdate)\)

文中对f的描述为L2正则。

看一下get_update_query函数的定义:

    def get_update_query(self, mem, max_indices, update_indices, score, query, train):

        m, d = mem.size()
if train:
query_update = torch.zeros((m,d)).cuda()
# random_update = torch.zeros((m,d)).cuda()
for i in range(m):
idx = torch.nonzero(max_indices.squeeze(1)==i)
a, _ = idx.size()
if a != 0:
query_update[i] = torch.sum(((score[idx,i] / torch.max(score[:,i])) *query[idx].squeeze(1)), dim=0)
else:
query_update[i] = 0 return query_update else:
query_update = torch.zeros((m,d)).cuda()
for i in range(m):
idx = torch.nonzero(max_indices.squeeze(1)==i)
a, _ = idx.size()
if a != 0:
query_update[i] = torch.sum(((score[idx,i] / torch.max(score[:,i])) *query[idx].squeeze(1)), dim=0)
else:
query_update[i] = 0 return query_update

在定义中,我们需要看到\(v_t^{'k,m}\)的计算。代码是通过(score[idx,i] / torch.max(score[:,i])实现的,进一步,我们需要查看\(v_t^{k,m}\)的计算过程。这个参数与\(w\)一样是权重,文中通过get_score函数计算权重,如下为此函数的定义:

    def get_score(self, mem, query):
#计算权重$w_t^{k,m}$
bs, h,w,d = query.size()
m, d = mem.size() score = torch.matmul(query, torch.t(mem))# b X h X w X m
score = score.view(bs*h*w, m)# (b X h X w) X m score_query = F.softmax(score, dim=0)
score_memory = F.softmax(score,dim=1) return score_query, score_memory

实现了文献中的权重计算

Read过程

def read(self, query, updated_memory):
#Read部分
batch_size, h,w,dims = query.size() # b X h X w X d softmax_score_query, softmax_score_memory = self.get_score(updated_memory, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) concat_memory = torch.matmul(softmax_score_memory.detach(), updated_memory) # (b X h X w) X d
# 权重和memory获得加权均值
updated_query = torch.cat((query_reshape, concat_memory), dim = 1) # (b X h X w) X 2d
# 进行拼接
updated_query = updated_query.view(batch_size, h, w, 2*dims)
updated_query = updated_query.permute(0,3,1,2) return updated_query, softmax_score_query, softmax_score_memory

核心部分在代码中给出了注释。

forward过程

separateness_loss, compactness_loss = self.gather_loss(query,keys, train)
# read
updated_query, softmax_score_query,softmax_score_memory = self.read(query, keys)
#update
updated_memory = self.update(query, keys, train) return updated_query, updated_memory, softmax_score_query, softmax_score_memory, separateness_loss, compactness_loss

分别调用update函数和read函数

需要说明损失函数的定义,\(L = L_{rec} + \lambda _cL_{compact}+ \lambda _sL_{separate}\)

代码中通过gather_loss函数实现。

def gather_loss(self,query, keys, train):
batch_size, h,w,dims = query.size() # b X h X w X d
if train:
loss = torch.nn.TripletMarginLoss(margin=1.0)
# 计算Feature separateness loss的主要函数
loss_mse = torch.nn.MSELoss()
# 计算均方差损失
softmax_score_query, softmax_score_memory = self.get_score(keys, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) _, gathering_indices = torch.topk(softmax_score_memory, 2, dim=1) #1st, 2nd closest memories
pos = keys[gathering_indices[:,0]]
neg = keys[gathering_indices[:,1]]
top1_loss = loss_mse(query_reshape, pos.detach())
gathering_loss = loss(query_reshape,pos.detach(), neg.detach()) return gathering_loss, top1_loss else:
loss_mse = torch.nn.MSELoss() softmax_score_query, softmax_score_memory = self.get_score(keys, query) query_reshape = query.contiguous().view(batch_size*h*w, dims) _, gathering_indices = torch.topk(softmax_score_memory, 1, dim=1) gathering_loss = loss_mse(query_reshape, keys[gathering_indices].squeeze(1).detach()) return gathering_loss, query_reshape, keys[gathering_indices].squeeze(1).detach(), gathering_indices[:,0]

Learning Memory-guided Normality代码学习笔记的更多相关文章

  1. DeepLearnToolbox-master代码学习笔记

    卷积神经网络(CNN)博大精深,网上资料浩如烟海,让初学者无从下手.笔者以为,学习编程还是从代码实例入们最好.目前,学习CNN最好的代码实例就是,DeepLearnToolbox-master,不用装 ...

  2. 《Learning Play! Framework 2》学习笔记——案例研究1(Templating System)

    注解: 这是对<Learning Play! Framework 2>第三章的学习 本章是一个显示聊天记录的项目,只有一个页面,可以自动对聊天记录进行排序.分组和显示,并整合使用了less ...

  3. Machine Learning In Action 第二章学习笔记: kNN算法

    本文主要记录<Machine Learning In Action>中第二章的内容.书中以两个具体实例来介绍kNN(k nearest neighbors),分别是: 约会对象预测 手写数 ...

  4. C# 好代码学习笔记(1):文件操作、读取文件、Debug/Trace 类、Conditional条件编译、CLS

    目录 1,文件操作 2,读取文件 3,Debug .Trace类 4,条件编译 5,MethodImpl 特性 5,CLSCompliantAttribute 6,必要时自定义类型别名 目录: 1,文 ...

  5. 1.JAVA中使用JNI调用C++代码学习笔记

    Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI?  Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 ( ...

  6. APM代码学习笔记1

    libraries目录 传感器 AP_InertialSensor 惯性导航传感器 就是陀螺仪加速计 AP_Baro 气压计 居然支持BMP085 在我印象中APM一直用高端的MS5611 AP_Co ...

  7. boost timer代码学习笔记

    socket连接中需要判断超时 所以这几天看了看boost中计时器的文档和示例 一共有五个例子 从简单的同步等待到异步调用超时处理 先看第一个例子 // timer1.cpp: 定义控制台应用程序的入 ...

  8. Hands on Machine Learning with Sklearn and TensorFlow学习笔记——机器学习概览

    一.什么是机器学习? 计算机程序利用经验E(训练数据)学习任务T(要做什么,即目标),性能是P(性能指标),如果针对任务T的性能P随着经验E不断增长,成为机器学习.[这是汤姆米切尔在1997年定义] ...

  9. cc代码学习笔记1

    #define #define INT32 int #define INT8 char #define CHAR char #define SSHORT signed short #define IN ...

随机推荐

  1. @MockBean 注解后 bean成员对象为 null?

    笔者在写自测的时候遇到的问题: 我想模拟一个Bean,并在之后使用Mockito打桩,于是使用了 @MockBean 注解(spring集成mockito的产物),但代码编写好了后启动测试却报Null ...

  2. 在go中通过cmd调用python命令行参数量级过大问题解决

    问题描述如下: 在go中使用cmd调用python命令行 cmd := exec.Command("python", "dimine/Kriging/matrix.py& ...

  3. 正则表达式-Python实现

    1.概述: Regular Expression.缩写regex,regexp,R等: 正则表达式是文本处理极为重要的工具.用它可以对字符串按照某种规则进行检索,替换. Shell编程和高级编程语言中 ...

  4. 如何优雅地学习计算机编程-C++1

    如何优雅的学习计算机编程--C++ 0.导入 如何优雅地学习计算机编程.我们得首先了解编程是什么?打个比方--写信. 大家都知道写信所用的语言双方都懂,这样的信才做到了信息交流,人和计算机也是如此人和 ...

  5. [源码解析] 并行分布式框架 Celery 之架构 (2)

    [源码解析] 并行分布式框架 Celery 之架构 (2) 目录 [源码解析] 并行分布式框架 Celery 之架构 (2) 0x00 摘要 0x01 上文回顾 0x02 worker的思考 2.1 ...

  6. 【原创】Linux虚拟化KVM-Qemu分析(十一)之virtqueue

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  7. vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...

  8. Jmeter(四十一) - 从入门到精通进阶篇 - Jmeter配置文件的刨根问底 - 下篇(详解教程)

    1.简介 为什么宏哥要对Jmeter的配置文件进行一下讲解了,因为有的童鞋或者小伙伴在测试中遇到一些需要修改配置文件的问题不是很清楚也不是很懂,就算修改了也是模模糊糊的.更有甚者觉得那是禁地神圣不可轻 ...

  9. ASP.NET网页开发基础(7)

    整理了一点的小知识点: 1.ASP.NET网页扩展名:    .asax 全局应用程序类的扩展名     .xml 访问网页时的扩展名     .htm     .ascx Web用户控件的扩展名   ...

  10. 【笔记】《Redis设计与实现》chapter9 数据库

    9.1 服务器中的数据库 Redis服务器将所有都保存在服务器状态redis.h/redisServer结构中 struct redisServer{ //... // 一个数组,保存着服务器中所有数 ...