在需要缓存的时候,谨慎使用python的负下标

Python的下标从0开始,那么当我们不想把初项放到递推的数组中的时候,我们可以使用负下标来方便地初始化。比如设f(x)=f(x-1)+something,我们就可以写

a = np.zeros(N)
a[-1] = some_initial_value
for i in range(N)
    a[i]=f(a[i-1]) + something

这样就避免了单独对a[0]进行初始化。

但是这样有一个危险:因为a[-1]实际上是a的最后一个值,所以如果你需要把每次运算时候的a给记住的话,当你计算到最后一个值的时候记忆的a[-1]会被改掉。例如,

def f(x):
  #return value is x**2, cache is x
  return x**2, x

def __main__:  
  a[-1] = some_initial_value
  cache = []
  for i in range(N): 
    a[i], cache_now = f(a[i-1])
    cache.append(cache_now)

如果这么写的话,那么你希望的cache[0] = a[-1] = some_initial_value,但是计算到最后一个a的时候,a[-1]会被改成a[N-1],这样你的输出a[N-1]是正确的,查不出错误;但是你的cache[0]也同样被改掉了。这样,当你需要cache的时候,最后一个cache就会出问题。

这个问题在神经网络的反向传播里面特别容易犯错,当前向传播完全正确,但是反向传播却总是莫名其妙地出错,还总是只错一个参数的时候,检查一下是不是这里出问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值