Nur*_*r L 24 python beam-search tensorflow
我使用Tensorflow tf.nn.ctc_beam_search_decoder()来解码RNN的输出,进行一些多对多映射(即每个网络单元的多个softmax输出).
网络输出的简化版本和Beam搜索解码器是:
import numpy as np
import tensorflow as tf
batch_size = 4
sequence_max_len = 5
num_classes = 3
y_pred = tf.placeholder(tf.float32, shape=(batch_size, sequence_max_len, num_classes))
y_pred_transposed = tf.transpose(y_pred,
perm=[1, 0, 2]) # TF expects dimensions [max_time, batch_size, num_classes]
logits = tf.log(y_pred_transposed)
sequence_lengths = tf.to_int32(tf.fill([batch_size], sequence_max_len))
decoded, log_probabilities = tf.nn.ctc_beam_search_decoder(logits,
sequence_length=sequence_lengths,
beam_width=3,
merge_repeated=False, top_paths=1)
decoded = decoded[0]
decoded_paths = tf.sparse_tensor_to_dense(decoded) # Shape: [batch_size, max_sequence_len]
with tf.Session() as session:
tf.global_variables_initializer().run()
softmax_outputs = np.array([[[0.1, 0.1, 0.8], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1]],
[[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
[[0.1, 0.7, 0.2], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
[[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]]])
decoded_paths = session.run(decoded_paths, feed_dict = {y_pred: softmax_outputs})
print(decoded_paths)
Run Code Online (Sandbox Code Playgroud)
这种情况下的输出是:
[[0]
[1]
[1]
[1]]
Run Code Online (Sandbox Code Playgroud)
我的理解是输出张量应该是维度[batch_size, max_sequence_len],每行包含找到的路径中相关类的索引.
在这种情况下,我希望输出类似于:
[[2, 0, 0, 0, 0],
[2, 2, 2, 2, 2],
[1, 2, 2, 2, 2],
[2, 2, 2, 2, 2]]
Run Code Online (Sandbox Code Playgroud)
我怎么不了解ctc_beam_search_decoder工作原理?
Mir*_*ber 24
如tf.nn.ctc_beam_search_decoder文档中所示,输出的形状不是[batch_size, max_sequence_len].相反,它是
[batch_size, max_decoded_length[j]]
Run Code Online (Sandbox Code Playgroud)
(j=0在你的情况下).
根据第2条的开头本文(其在所引用的github库),max_decoded_length[0]从上面所界定max_sequence_len的,但它们不一定相等.相关的引用是:
设S是从固定分布D_ {XxZ}绘制的一组训练样例.输入空间X =(R ^ m)是m维实值向量的所有序列的集合.目标空间Z = L*是标签的(有限)字母L上的所有序列的集合.通常,我们将L*的元素称为标记序列或标记.S中的每个例子由一对序列(x,z)组成.目标序列z =(z1,z2,...,zU)最多与输入序列x =(x1,x2,...,xT)一样长,即U <= T. 由于输入序列和目标序列通常不是相同的长度,因此没有先验的对齐方式.
实际上,max_decoded_length[0]取决于具体的矩阵softmax_outputs.特别是,具有完全相同尺寸的两个这样的矩阵可能导致不同max_decoded_length[0].
例如,如果您替换该行
softmax_outputs = np.array([[[0.1, 0.1, 0.8], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1]],
[[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
[[0.1, 0.7, 0.2], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
[[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]]])
Run Code Online (Sandbox Code Playgroud)
与行
np.random.seed(7)
r=np.random.randint(0,100,size=(4,5,3))
softmax_outputs=r/np.sum(r,2).reshape(4,5,1)
Run Code Online (Sandbox Code Playgroud)
你会得到输出
[[1 0 1]
[1 0 1]
[1 0 0]
[1 0 0]]
Run Code Online (Sandbox Code Playgroud)
(在上面的例子中,softmax_outputs由logits组成,它与你提供的矩阵完全相同).
另一方面,改变种子以np.random.seed(50)产生输出
[[1 0]
[1 0]
[1 0]
[0 1]]
Run Code Online (Sandbox Code Playgroud)
PS
关于你问题的最后部分:
在这种情况下,我希望输出类似于:
Run Code Online (Sandbox Code Playgroud)[[2, 0, 0, 0, 0], [2, 2, 2, 2, 2], [1, 2, 2, 2, 2], [2, 2, 2, 2, 2]]
请注意,根据文档, num_classes实际上代表num_labels + 1.特别:
输入Tensor的最内层维度大小
num_classes表示num_labels + 1类,其中num_labels是真实标签的数量,最大值(num_classes - 1)是为空白标签保留的.例如,对于包含3个标签[a,b,c]的词汇表,
num_classes = 4索引的标签是{a:0,b:1,c:2,blank:3}.
因此,您的案例中的真实标签为0和1,并且为空白标签保留2.空白标签表示没有标签的情况(此处第3.1节):
CTC网络有一个softmax输出层(Bridle,1990),比L中的标签多一个单位.第一个| L |的激活.单位被解释为在特定时间观察相应标签的概率.额外单位的激活是观察"空白"或没有标签的概率.这些输出一起定义了将所有可能的标记序列与输入序列对齐的所有可能方式的概率.
| 归档时间: |
|
| 查看次数: |
3229 次 |
| 最近记录: |