如何沿着轴线指数衰减一个数值?

2024-04-20 07:27:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个(sequence_length,batch_size,1)形状的张量(在下面的例子中是(5,5,1))。每个序列都有一个条目,我想沿着序列指数衰减(例如,衰减因子为0.99),以n步(这里:n = 2)。你知道吗

示例

enter image description here

有没有一种有效的方法来实现这样的事情(在PyTorchnumpy)。你知道吗

编辑(可视化相加性质):

enter image description here


Tags: 方法numpy示例sizebatch条目序列pytorch
2条回答

给出最后的评论,基于numpy的问题解决方案是可行的:

虽然可能有更聪明的numpy矢量化trics可行,在一个基于.view的跨步技巧数据上无干扰地添加许多一维“扩散”核似乎不确定,因为叠加值的重新传播(而不是仅仅是数据的一维“扩散”核传播)不会引入原始加核附加值的倾斜叠加的不必要副作用原始张量值(在添加任何内核产品之前,因为这些产品可能到达相同的张量单元位置)


-第0步:创建一个基于Q-学习伽玛的常量“内核”向量kernelRESULT_TENSORORIGINAL_TENSOR的零拷贝


>>> N_STEPS  = 2
>>> Q_FACTOR = 0.99
>>> kernel = np.ones( N_STEPS )
>>> for i in range( 1, kernel.shape[0] ):
...     kernel[:i] *= Q_FACTOR
... 
>>> kernel
array([0.9801, 0.99  , 1.    ])
>>> RESULT_TENSOR = np.zeros( ORIGINAL_TENSOR.shape )

在与[SPACE]域相关的问题的情况下,临时加法器存储器可以保持更小的方式,仅使用当前的列映射,以便最小化总体RAM占用。你知道吗


-步骤1:对于每个张量列,使用numpy跨步技巧来形成每个此类张量列的二维元视图,深度等于n步的(对于反向传播的q-奖励)like在这个rolling_window()例子中用于2D矩阵(需要进行调整,以便在向量列上使用,或者如果有点疯狂,则直接穿过while原始张量)


def rolling_window( aMatrix, aRollingWindowLENGTH ):                    #
    """                                                                 __doc__
    USAGE:   rolling_window( aMatrix, aRollingWindowLENGTH )

    PARAMS:  aMatrix                a numpy array
             aRollingWindowLENGTH   a LENGTH of a Rolling Window

    RETURNS: a stride_trick'ed numpy array with rolling windows

    THROWS:  n/a

    EXAMPLE: >>> x = np.arange( 10 ).reshape( ( 2, 5 ) )

             >>> rolling_window( x, 3 )
             array([[[0, 1, 2], [1, 2, 3], [2, 3, 4]],
                    [[5, 6, 7], [6, 7, 8], [7, 8, 9]]])

             >>> np.mean( rolling_window( x, 3 ), -1 )
             array([[ 1.,  2.,  3.],
                    [ 6.,  7.,  8.]])
    """
    new_shape   = aMatrix.shape[:-1] + ( aMatrix.shape[-1]
                                       - aRollingWindowLENGTH + 1,
                                         aRollingWindowLENGTH
                                         )
    new_strides = aMatrix.strides    + ( aMatrix.strides[-1], )
    return np.lib.stride_tricks.as_strided( aMatrix,
                                            shape   = new_shape,
                                            strides = new_strides
                                            )

meta2D = rolling_window( aTensorCOLUMN_to_PROCESS, N_STEPS )

-步骤2:对于逐列张量处理的情况,将kernel乘以标量-乘以每个当前列的2D元视图矩阵“rows”[-1]值,并将+=存储这样产生的“缩放”内核到一个单独的RESULT_TENSOR(或上述[SPACE]域驱动的可重用/可擦除的临时文件中列加法器)累积累加结果(IMHO这是不可能的,因为内核“反向传播”的奖励不能“增加”另一个(虽然在结果中是累加的)Q-奖励,还没有被kernel处理,因为跨步技巧只是一个视图,存储在适当的位置会干扰ORIGINAL_TENSOR尚未处理的部分。你知道吗


-第3步:完成后,使用RESULT_TENSOR累积结果,因为它现在保存了所有非零值的Q学习n步深度传播,并避免了任何交叉干扰副作用。你知道吗

在我看来,这就像是一个卷积:

import numpy as np
from scipy.ndimage import convolve1d

# just for printing:
import numpy.lib.recfunctions as nlr
def show(x): print(nlr.unstructured_to_structured(x))

a = "00000","00100","10000","03502","00010"
A = np.array(a).view('U1').reshape(5,5,1).astype(float)

show(A)
# [[(0.,) (0.,) (0.,) (0.,) (0.,)]
#  [(0.,) (0.,) (1.,) (0.,) (0.,)]
#  [(1.,) (0.,) (0.,) (0.,) (0.,)]
#  [(0.,) (3.,) (5.,) (0.,) (2.,)]
#  [(0.,) (0.,) (0.,) (1.,) (0.,)]]

show(convolve1d(A,np.r_[np.logspace(2,0,3,base=0.99),0,0],axis=0,mode="constant"))
# [[(0.9801,) (0.    ,) (0.99  ,) (0.    ,) (0.    ,)]
#  [(0.99  ,) (2.9403,) (5.9005,) (0.    ,) (1.9602,)]
#  [(1.    ,) (2.97  ,) (4.95  ,) (0.9801,) (1.98  ,)]
#  [(0.    ,) (3.    ,) (5.    ,) (0.99  ,) (2.    ,)]
#  [(0.    ,) (0.    ,) (0.    ,) (1.    ,) (0.    ,)]]

相关问题 更多 >