python - 如何有效地更新 Keras 变量切片?
问题描述
假设我们有x = K.zeros((4, 6))
,并且我们希望将 1 添加到第 0 行:x[0] += 1
。该变量是通过Layer
's add_weight()
w/创建的training=False
,因此不会通过反向传播更新。什么是最高效的方法?
上下文:我正在实现循环批标准化,RNN 中每个时间步的变量moving_mean
和变量都不同——因此每个时间步的形状为. 目标是通过每步更新一个切片。一种方法如下:moving_variance
(units, timesteps)
timesteps
K.moving_average_update()
import keras.backend as K
units, timesteps = 4, 6
x = K.zeros((units, timesteps), dtype='float32', name='x')
x_new = x[:units, 0].assign(K.ones((units,), dtype='float32')) # dummy example
K.set_value(x, K.get_value(x_new))
print(K.get_value(x))
[[1. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0.]]
看起来不错 - 除了创建了一个新副本。x
在实践中,我们可以有timesteps > 100
(例如 120),所以我们创建了一个比它需要的大 120 倍的数组,120 倍(1 / 步),使其成为一个O(timesteps**2)
操作 - 与通常的切片相反,O(timesteps)
. 检查 Keras 的Backend,它的update_
方法都涉及复制原始数组。
Keras 有什么更高效的吗?如果没有,在 TensorFlow 中?
注意:我知道“附加到列表* 然后在最后一步通过数组分配”替代方案,这更有效,但我们可以做得更好 - 至少就“传统”数组而言(*或填充零数组)。尽管不可否认,还有 GPU 因素,它在批量分配中比迭代更有效 - 但我无法根据我所描述的内容有效地对后者进行基准测试。
解决方案
想出直接切片更新:
x_slice = x[4:5]
x_slice.assign(math_ops.sub(x_slice, some_tensor))
x_slice
似乎很好地引用了原始张量数组;由于某种原因,assign_sub
失败了;见澄清评论。
推荐阅读
- r - 帖子的图片标题未显示在 blogdown 帖子中
- enums - 在 Rust 中使用枚举实现动态多态性
- java - spring-data-mongodb : 从 ($gt, $lt) 到 ($gte, $lte)
- elasticsearch - Elasticsearch:开始和结束日期列表中的匹配范围
- angular - 使用 Angular 8 过滤 Firebase 数据的功能
- objective-c - macOS 以编程方式降低其他应用程序的音量
- spring - 自定义 ConstraintValidator 中的 Spring 服务为空
- vba - 在保存时强制使用文档探测主题
- c++ - 在 Endpoint 中使用 oatpp::Enum 作为路径参数类型的正确方法是什么?
- haskell - Haskell 的 Either Monad 中如何处理类型错误?