Social LSTM 实现代码分析

Social LSTM最早提出于文献 “Social LSTM: Human Trajectory Prediction in Crowded Spaces”,但经过资料查阅目前暂未找到原文献作者所提供的程序代码和数据,而在github上有许多针对该文献的实现版本代码。

本文接下来的实现代码来自https://github.com/xuerenlv/social-lstm-tf,代码语言为Python3,代码大体实现了原论文中核心原创部分的模型,包括Vanilla LSTM(没有考虑行人轨迹之间关联性的LSTM)和Social LSTM(使用池化层考虑了行人轨迹之间关联性的LSTM模型)的模型构建、训练和小样本测试的代码,但对横向对比的其他模型、模型量化评估方法等暂未实现。

本文下面将从代码中矩阵数据和列表(list)数据的维度细说实现过程和模型的特点。

Vanilla LSTM 模型

训练数据

主要功能代码文件:util.py

数据格式:

input_data, target_data = dataLoader.next_batch()
# input_data : [batch_size, seq_length, 2]
# target_data : [batch_size, seq_length, 2]

批量处理数据大小 x 序列长度大小 x 二维地址数据(已经过标准化处理,介于\(0 - 1\))

数据解释:

  1. 模型在实际使用时,对于每个输入的位置数据(源于已知数据/上一步预测数据)LSTM Cell将该运行后得到的输出就可用于下一时刻位置的预测,因此从dataLoader获得的input_datatarget_data从数据维度上只在seq_length维度上有1个大小的错位,对于行人已知的\(t_0 - t_{obs}\)的轨迹,训练时参与损失函数计算的是网络预测的\(t_1 - t_{obs+1}\)轨迹。
  2. 同时,其在由于训练采用Minibatch,因此输入和目标数据的有大小为batch_size的第一维度。

模型中间变量

LSTM序列网络是模型的核心部分,输入数据需要修改结构以满足数据要求,同时序列网络的输出结果也需要经过处理才能够使用,为此,模型主要有以下中间变量:

inputs, embedding_inputs

inputsinput_data的拆分版,将其拆解为序列模型每步运行时的输入数据。

embedding_inputs是将inputs使用embedding层后得到的输入数据,默认满足embedding_size = rnn_size = 128,因此数据可直接用于lstm的输入数据了。

# inputs : [N_0, N_1, N_2, ....], N_i = [batch_size, 2]
# embedding_inputs = [M_0, M_1, M_2, ....], M_i = [batch_size, embedding_size]

# embedding
embedding_w = tf.get_variables("embedding_w", [2, embedding_size])
embedding_b = tf.get_variables("embedding_b", [embedding_size])
for input in embedding_inputs:
    x = tf.nn.relu(tf.nn.xw_plus_b(input, embedding_w, embedding_b))
    embedding_inputs.append(x)

seq2seq.rnn_decoder

由于该源码相比tensorflow的版本更迭还是有一定的年代感,其在运行LSTM模型时使用了不常用的方法:

outputs, last_state = tf.contrib.legacy_seq2seq.rnn_decoder(embedded_inputs, self.initial_state, cell, loop_function=None, scope="rnnlm")

此LSTM模型严格来说并不是seq2seq模型,其只是借用了seq2seq中decoder相同的操作步骤用在这里(手动实现也不复杂),具体来说,就是在for循环迭代embedded_inputs列表中的元素,使LSTM的cell运行对应的次数,而后将序列模型的每步运行输出生成outputs列表,并返回最后一步运行的finial_state

output_w, output_b

LSTM模型输出的原始outputs数据需经线性变换为合适结构才被进一步使用,在此是对于每个大小为rnn_size的输出向量,线性变为为大小为\(5\)的结果向量,有关使用目的请参见下一节。

output_size = 5 # 具体赋值目的请参见下文与原文献
# output : [batch_size * seq_length, rnn_size]
output = tf.reshape(tf.concat(outputs, 1), [-1, rnn_size])

output_w = tf.get_variable("output_w", [rnn_size, output_size])
output_b = tf.get_variable("output_b", [output_size])
# output : [batch_size * seq_length, 5]
output = tf.nn.xw_plus_b(output, output_w, output_b)

*output数据中最终含有\(batch\_size * seq\_length\)个预测的位置(每个位置由5个参数表述),相同的reshape策略可确保output中预测位置与target中实际位置的排列顺序是相同的。

模型输出

将序列模型每步输出结果合并、线性变换和变形后得到output,传入的target_data经过变形后得到flat_target_data

# model.py
# output : [batch_size * seq_length, 5]
# flat_target_data : [batch_size * seq_length, 2]

outputflag_target_data就是最终用于(训练时)计算损失/(采样时,不依赖于target)计算下一时刻位置的数据。

两个变量的第一维度大小均为batch_size * seq_length(在reshape策略相同情况下,第二维度数据在数据批次和时间点上一一对应),而两个变量在第二维度数据量的差异是:原文献中假设了LSTM Cell输出的rnn_size大小(默认为128)的结果满足二维高斯分布(bivariate Gaussian distribution),因此使用线性变换矩阵后得到的恰是刻画二维高斯分布的5个参数$\mu_x, \mu_y, \sigma_x, \sigma_y, \rho $(有关如何基于二维高斯分布求出预测点和损失值请原文献的引用)。

Social LSTM模型

此部分暂时未完全整理出来,根据初步的代码阅读,Social LSTM与Vanilla LSTM整体的代码框架和模型构建方法是相似的,具体有下述几方面的差异:

  1. batch_sizemax pedestrian number,批量训练数据的差异:在Vanilla LSTM训练时,采用了Mini Batch的数据方式使每次模型迭代时具备一定的数量规模;而Social LSTM中由于池化层的加入使得同一时刻需要有MPN个LSTM序列迭代,而纵使存在多个LSTM序列,其实共享的是同一个Cell,因此同一场景的多位行人的轨迹(在代码中称作frame)其实就可以等价于一个batch,从而使训练Cell时有一定的数据规模。

    # input_data format in vanilla lstm
    input_data = tf.placeholder(tf.float32, [None, seq_length, 2])
    ----
    # input_data format in social lstm
    input_data = tf.placeholder(tf.float32, [seq_length, maxNumPeds, 3])
  2. social tensor池化层:

    social LSTM结构从本质上就是vanilla lstm添加了池化层,在源代码的grid.py包含主要的social tensor的支持方法。social tensor在原文中用\(H_i^t\)表示,每个行人\(i\)在不同时间点\(t\)中都有不同的social tensor

    对于每个张量中的值,实际是由上一时刻其他行人的Hidden State加和得到,Hidden State只有LSTM Cell真正跑起来才能得到,因此最终的social tensor是在模型运算中所得到的(这也是为什么运算量较大的原因以至原文献中又提出了一种能够在运算前得到张量的O-LSTM模型),不过在模型运行前,Hidden State的加和方式就可以通过输入数据推算得出,grid.py做得主要就是这部分工作,其生成了数据为01真值的Grid Mask矩阵,在模型迭代时作为参数传入,从而简化生成social tensor的过程。

原文地址:https://www.cnblogs.com/sinoyou/p/11219618.html

时间: 2024-10-12 21:47:31

Social LSTM 实现代码分析的相关文章

深度学习之六,基于RNN(GRU,LSTM)的语言模型分析与theano代码实现

引言 前面已经介绍过RNN的基本结构,最基本的RNN在传统的BP神经网络上,增加了时序信息,也使得神经网络不再局限于固定维度的输入和输出这个束缚,但是从RNN的BPTT推导过程中,可以看到,传统RNN在求解梯度的过程中对long-term会产生梯度消失或者梯度爆炸的现象,这个在这篇文章中已经介绍了原因,对于此,在1997年 的Grave大作[1]中提出了新的新的RNN结构:Long Short Term Dependency.LSTM在传统RNN的基础上加了许多的"门",如input

开源项目kcws代码分析--基于深度学习的分词技术

http://blog.csdn.net/pirage/article/details/53424544 分词原理 本小节内容参考待字闺中的两篇博文: 97.5%准确率的深度学习中文分词(字嵌入+Bi-LSTM+CRF) 如何深度理解Koth的深度分词? 简单的说,kcws的分词原理就是: 对语料进行处理,使用word2vec对语料的字进行嵌入,每个字特征为50维. 得到字嵌入后,用字嵌入特征喂给双向LSTM, 对输出的隐层加一个线性层,然后加一个CRF就得到本文实现的模型. 于最优化方法,文本

java代码分析及分析工具

java代码分析及分析工具 一个项目从搭建开始,开发的初期往往思路比较清晰,代码也比较清晰.随着时间的推移,业务越来越复杂.代码也就面临着耦合,冗余,甚至杂乱,到最后谁都不敢碰. 作为一个互联网电子商务网站的业务支撑系统,业务复杂不言而喻.从09年开始一直沿用到现在,中间代码经过了多少人的手,留下了多少的坑,已经记不清楚了,谁也说不清了. 代码的维护成本越来越高.代码已经急需做调整和改善.最近项目组专门设立了一个小组,利用业余时间做代码分析的工作,目标对核心代码进行分析并进行设计重构. 代码分析

Java静态代码分析工具Infer

Java静态代码分析工具Infer 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.Infer介绍 Infer是Facebook最新开源的静态程序分析工具,用于在发布移动应用之前对代码进行分析,找出潜在的问题.目前Facebook使用此工具分析Facebook的App,包括Android.iOS.Facebook Messenger和Instagram等. Facebook称该工具帮助其每个月检查出应用潜在的数百个Bug,例如一些空指针访问.资源

$*和[email protected]之间区别代码分析

#!/bin/bash set 'apple pie' pears peaches for i in $*           /*单引号被去掉,循环单个字符输出*/ do echo $i done [[email protected] Ex_14.02-14.31]# sh 14-14-1 apple pie pears peaches -------------------------------------------------------------- #!/bin/bash set

《linux 内核完全剖析》 keyboard.S 部分代码分析(key_map)

keyboard.S 部分代码分析(key_map) keyboard中间有这么一段,我一开始没看明白,究竟啥意思 key_map: .byte 0,27 .ascii "1234567890-=" .byte 127,9 .ascii "qwertyuiop[]" .byte 13,0 .ascii "asdfghjkl;'" .byte '`,0 .ascii "\\zxcvbnm,./" .byte 0,'*,0,32

20145234黄斐《网络对抗技术》实验四,恶意代码分析

恶意代码 概述 恶意代码是指故意编制或设置的.对网络或系统会产生威胁或潜在威胁的计算机代码.最常见的恶意代码有计算机病毒(简称病毒).特洛伊木马(简称木马).计算机蠕虫(简称蠕虫).后门.逻辑炸弹等. 特征: 恶意的目的,获取靶机权限.用户隐私等 本身是计算机程序,可以执行,并作用于靶机 通过执行发生作用,一般来说不运行是没问题的 恶意代码分析 在大多数情况下,进行恶意代码分析时,我们将只有恶意代码的可执行文件本身,而这些文件并不是我们人类可读的.为了了解这些文件的意义,你需要使用各种工具和技巧

20145326蔡馨熠《网络对抗》——恶意代码分析

20145326蔡馨熠<网络对抗>--恶意代码分析 1.实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所以想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控.. 需要监控什么? 系统中各种程序.文件的行为. 还需要注意是否会出现权限更改的行为. 注册表. 是否有可疑进程. 如果有网络连接的情况,需要注意这个过程中的IP地址与端口. 用什么来监控? 最先想到的肯定是使用wireshark抓包了,再进行进一步分析. Sysinternals

代码分析—“CA0052 没有选择要分析的目标”(VS2012)

情况: 1.未采用代码分析时程序正常编译 2.采用代码分析,会提示"没有选择分析目标"或"未加载制定版本的程序集"...的错误 分析: 是由于代码分析依赖程序集的强签名,包括版本 解决方案: 1.修改代码分析工具的配置项: FxCopCmd.exe.config里节点AssemblyReferenceResolveMode的Value值StrongName修改为StrongNameIgnoringVersion或None 2.修改当前分析的项目: .csproj增加