Tensorflow 什么';s tf.nn.ctc_损耗与pytorch.nn.CTCLoss之间的差异

Tensorflow 什么';s tf.nn.ctc_损耗与pytorch.nn.CTCLoss之间的差异,tensorflow,machine-learning,neural-network,pytorch,ctc,Tensorflow,Machine Learning,Neural Network,Pytorch,Ctc,对于相同的输入和标签: pytorch.nn.CTCLoss的输出为5.74 tf.nn.ctc_loss的输出为129.69 但是math.log(tf-ctc-loss)的输出是4.86 那么pytorch.nn.CTCLoss与tf.nn.ctc\u loss之间有什么区别呢 tf: 1.13.1 pytorch: 1.1.0 我曾尝试过: log_softmax记录输入,然后将其发送到pytorch.nn.CTCLoss tf.nn.log\u softmax输入,然后将其发送到t

对于相同的输入和标签:

  • pytorch.nn.CTCLoss的输出为5.74
  • tf.nn.ctc_loss
    的输出为129.69
  • 但是
    math.log(tf-ctc-loss)
    的输出是4.86
那么
pytorch.nn.CTCLoss
tf.nn.ctc\u loss
之间有什么区别呢

tf: 1.13.1
pytorch: 1.1.0
我曾尝试过:

  • log_softmax
    记录输入,然后将其发送到
    pytorch.nn.CTCLoss

  • tf.nn.log\u softmax
    输入,然后将其发送到
    tf.nn.ctc\u loss

  • 直接将输入发送到
    tf.nn.ctc\u loss

  • 直接将输入发送到
    tf.nn.ctc\u loss
    ,然后
    math.log(tf.nn.ctc\u loss的输出)

  • 在案例2、案例3和案例4中,计算结果与
    pytorch.nn.CTCLoss

    来自火炬导入nn的
    
    进口火炬
    导入tensorflow作为tf
    输入数学
    时间步长=50#输入序列长度
    vocab_size=20#课程数
    批量大小=16#批量大小
    目标序列长度=30#目标序列长度
    def稠密到稀疏(稠密张量、序列长度):
    索引=tf.where(tf.sequence\u mask(sequence\u length))
    值=tf.聚集(密集张量,索引)
    shape=tf.shape(稠密张量,out-type=tf.int64)
    返回tf.SparseTensor(索引、值、形状)
    def计算损耗(x,y,x长度):
    ctcloss=tf.nn.ctc\u损耗(
    Y
    tf.cast(x,dtype=tf.float32),
    x_len,
    预处理\u折叠\u重复=错误,
    ctc\u merge\u repeated=False,
    忽略比输入更长的输出=错误
    )
    CTCLOSES=tf.减少平均值(CTCLOSES)
    使用tf.Session()作为sess:
    ctcloss=sess.run(ctcloss)
    打印(f“tf ctc丢失:{CTCLOSES}”)
    打印(f“tf日志(ctc丢失):{math.log(ctclosses)}”)
    最小目标长度=10
    ctc_loss=nn.CTCLoss(空白=vocab_size-1)
    x=火炬。randn(时间步长、批次大小、声音大小)#[大小]=T,N,C
    y=torch.randint(0,vocab_大小-2,(批量大小,目标序列长度),dtype=torch.long)#低,高,[size]
    x_长度=火炬。完整((批次大小),时间步进,数据类型=火炬。长)#输入长度
    y长度=torch.randint(最小目标长度,目标序列长度,(批次大小,),
    dtype=torch.long)#目标的长度可以是可变的(即使目标序列的长度是恒定的)
    损耗=ctc_损耗(x.log_softmax(2).detach(),y,x_长度,y_长度)
    打印(f“丢失:{loss}”)
    x=x.numpy()
    y=y.numpy()
    x_length=x_length.numpy()
    y_长度=y_长度。numpy()
    x=tf.cast(x,dtype=tf.float32)
    y=tf.cast(密集到稀疏(y,y长度),dtype=tf.int32)
    计算损耗(x,y,x_长度)
    

    我希望
    tf.nn.ctc_loss
    的输出与
    pytorch.nn.CTCLoss
    的输出相同,但实际上它们不是,但我如何才能使它们相同?

    pytorch的CTCLoss的自动平均减少与计算所有单个损失,然后进行平均值计算不同(正如您在Tensorflow实现中所做的那样)。事实上,来自CTCLoss(pytorch)的文档:

    要获得相同的值,请执行以下操作:

    1-将减少方法更改为总和:

    ctc_loss = nn.CTCLoss(reduction='sum')
    
    2-将计算的损失除以批次大小:

    loss = ctc_loss(x.log_softmax(2).detach(), y, x_lengths, y_lengths)
    loss = (loss.item())/batch_size
    
    3-将Tensorflow的参数ctc_merge_repeated更改为True(我假设pytorch ctc中也是如此)

    现在,您将获得pytorch损失和tensorflow损失之间非常接近的结果(不需要记录值)。剩下的微小差异可能来自实现之间的细微差异。 在最近三次跑步中,我得到了以下值:

    pytorch loss : 113.33 vs tf loss = 113.52
    pytorch loss : 116.30 vs tf loss = 115.57
    pytorch loss : 115.67 vs tf loss = 114.54
    
        ctclosses = tf.nn.ctc_loss(
        y,
        tf.cast(x, dtype=tf.float32),
        x_len,
        preprocess_collapse_repeated=False,
        ctc_merge_repeated=True,
        ignore_longer_outputs_than_inputs=False
    )
    
    pytorch loss : 113.33 vs tf loss = 113.52
    pytorch loss : 116.30 vs tf loss = 115.57
    pytorch loss : 115.67 vs tf loss = 114.54