在 TensorFlow 中使用多对多 LSTM 进行视频分类
Posted
技术标签:
【中文标题】在 TensorFlow 中使用多对多 LSTM 进行视频分类【英文标题】:Video classification using many to many LSTM in TensorFlow 【发布时间】:2018-07-12 05:09:12 【问题描述】:我必须构建一个二元分类器来预测输入视频是否包含动作。
模型的输入将是形状:[batch, frames, height, width, channel]
在这里,batch 是视频的数量,frames 是该视频中的图像数量(对于每个视频都是固定的),height 是该图像中的行数,width 是该图像中的列数,channel 是 RGB 颜色。
我在 Andrej Karpathy 博客中发现多对多递归神经网络最适合此应用程序:http://karpathy.github.io/2015/05/21/rnn-effectiveness/
因此,我需要在 TensorFlow 中实现:
我通过本教程学习了如何实现 LSTM:https://github.com/nlintz/TensorFlow-Tutorials/blob/master/07_lstm.py#L52
但是,它只使用最后一个张量来实现多对一 LSTM 并预测输出并减少损失:outputs[-1]
而且,我想使用许多张量(比如说 4 个)来预测输出并使用它们来减少损失。
这是我的实现:
import tensorflow as tf
from tensorflow.contrib import rnn
import numpy as np
# Training Parameters
batch = 5 # number of examples
frames = time_step_size = 20
height = 60
width = 80
channel = 3
lstm_size = 240
num_classes = 2
# Creating random data
input_x = np.random.normal(size=[batch, frames, height, width, channel])
input_y = np.zeros((batch, num_classes))
B = np.ones(batch)
input_y[:,1] = B
X = tf.placeholder("float", [None, frames, height, width, channel], name='InputData')
Y = tf.placeholder("float", [None, num_classes], name='LabelData')
with tf.name_scope('Model'):
XR = tf.reshape(X, [-1, height*width*channel]) # shape=(?, 14400)
X_split3 = tf.split(XR, time_step_size, 0) # 20 tensors of shape=(?, 14400)
lstm = rnn.BasicLSTMCell(lstm_size, forget_bias=1.0, state_is_tuple=True)
outputs, _states = rnn.static_rnn(lstm, X_split3, dtype=tf.float32) # 20 tensors of shape=(?, 240)
logits = tf.layers.dense(outputs[-1], num_classes, name='logits') # shape=(?, 2)
prediction = tf.nn.softmax(logits)
# Define loss and optimizer
with tf.name_scope('Loss'):
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y))
with tf.name_scope('optimizer'):
optimizer = tf.train.AdamOptimizer(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, use_locking=False, name='Adam')
train_op = optimizer.minimize(loss_op)
# Evaluate model (with test logits, for dropout to be disabled)
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
with tf.name_scope('Accuracy'):
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
with tf.Session() as sess:
tf.global_variables_initializer().run()
logits_output = sess.run(logits, feed_dict=X: input_x)
print(logits_output.shape) # shape=(5, 2)
sess.run(train_op, feed_dict=X: input_x, Y: input_y)
loss, acc = sess.run([loss_op, accuracy], feed_dict=X: input_x, Y: input_y)
print("Loss: ", loss) # loss: 1.46626135e-05
print("Accuracy: ", acc) # Accuracy: 1.0
问题:
1. 我需要帮助来实现多对多 LSTM 并预测某些帧后的输出(比如说 4),但是,我只使用最后一个张量 outputs[-1]
来减少损失。有 20 个张量,frames
或 time_step_size
各一个。如果我每 5 个张量变换一次:outputs[4], outputs[9], outputs[14], outputs[-1]
,我将得到 4 个 logits。那么,我将如何减少这四个方面的损失呢?
2. 另一个问题是,我必须实现二元分类器,但我只有想要识别的动作视频。因此,input_y
是标签的一种热门表示形式,其中第一列始终为 0,第二列始终为 1(我必须确定的操作),并且我没有任何示例视频,其中第一列的值为 1。你认为它会起作用吗?
3. 为什么在上面的实现中,仅在一次迭代中精度为 1?
谢谢
【问题讨论】:
你应该考虑序列到序列模型,像这样tensorflow.org/tutorials/seq2seq 【参考方案1】:对于 1.,Dense
采用任意数量的批次维度,因此您应该能够一次将所有步骤转换为 logits(然后同样对批次进行操作,直到您获得每个步骤的最终损失,然后聚合,例如取平均值)。
对于 2. 和 3.,您似乎需要找到一些反面例子。有一篇关于“积极和未标记 (PU)”学习和“一类分类”的文献可能会有所帮助。
【讨论】:
步数是指张量(outputs
)吗?我正在使用 tf.layers.dense(outputs[-1], num_classes, name='logits')
将最后一个张量 (outputs[-1]
) 转换为 logits。有 20 个张量,frames
或 time_step_size
各一个。如果我每 5 个张量变换一次:outputs[4], outputs[9], outputs[14], outputs[-1]
,我将得到 4 个 logits。那么,我将如何减少这四个方面的损失呢?我不确定您所说的“批量操作,直到每一步都得到最终损失,然后聚合,例如取平均值”是什么意思。你能不能给一些代码来解释一下。以上是关于在 TensorFlow 中使用多对多 LSTM 进行视频分类的主要内容,如果未能解决你的问题,请参考以下文章