Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过多个正向过程进行反向传播_Python_Tensorflow_Keras_Tensorflow2.0_Tf.keras - Fatal编程技术网

Python 通过多个正向过程进行反向传播

Python 通过多个正向过程进行反向传播,python,tensorflow,keras,tensorflow2.0,tf.keras,Python,Tensorflow,Keras,Tensorflow2.0,Tf.keras,在通常的backprop中,我们向前推进一次prop,计算梯度,然后应用它们来更新权重。但假设我们希望向前支撑两次,向后支撑两次,然后只应用渐变(先跳过) 假设如下: x=tf.Variable([2.]) w=tf.变量([4.]) 使用tf.GradientTape(persistent=True)作为磁带: w、 分配(w*x) y=w*w#w^2*x 打印(磁带梯度(y,x))#>>无 从中,atf.Variable是一个有状态对象,它阻止梯度,权重是tf.Variables 示例包括

在通常的backprop中,我们向前推进一次prop,计算梯度,然后应用它们来更新权重。但假设我们希望向前支撑两次,向后支撑两次,然后只应用渐变(先跳过)

假设如下:

x=tf.Variable([2.])
w=tf.变量([4.])
使用tf.GradientTape(persistent=True)作为磁带:
w、 分配(w*x)
y=w*w#w^2*x
打印(磁带梯度(y,x))#>>无
从中,a
tf.Variable
是一个有状态对象,它阻止梯度,权重是
tf.Variable
s

示例包括可区分的硬注意(与RL相反),或在后续的正向传递中在层之间传递隐藏状态,如下图所示。TF和KERA都没有API级别的有状态梯度支持,包括
RNN
s,它只保留有状态状态张量;梯度不超过一批

如何做到这一点


我们需要精心地应用
tf.while_loop
;发件人:

此类用于动态迭代原语,如
while\u loop
map\u fn
。它通过特殊的“流”控制流依赖关系支持梯度反向传播

因此,我们试图编写一个循环,这样我们要反向传播的所有输出都被写入
TensorArray
。下面是实现这一点的代码及其高级描述。下面是一个验证示例


说明

  • 代码借用,为了简单和相关性而重写
  • 为了更好地理解,我建议检查
    K.rnn
    ,以及
  • model\u rnn
    为案例3进行了一些不必要的检查;将链接到更干净的版本
  • 其思想如下:我们首先从下到上,然后从左到右遍历网络,然后将整个向前传递写入单个
    tf下的单个
    TensorArray
    ;这确保TF在整个过程中为反向传播缓存张量ops

来自tensorflow.python.util导入嵌套
从tensorflow.python.ops导入数组_ops,tensor_数组_ops
从tensorflow.python.framework导入ops
def模型(模型、输入、状态=无,交换批处理时间步=真):
def step_功能(输入、状态):
输出=模型([输入,*状态],训练=真)
输出,新的_状态=(如果isinstance(输出,(元组,列表))则输出),否则
(外,国家)
返回输出,新状态
定义交换批处理时间步(输入):
#(样本、时间步、通道)->(时间步、样本、通道)
#迭代dim0以馈送RNN期望的(样本、通道)切片
轴=列表(范围(长度(输入形状)))
轴[0],轴[1]=1,0
返回数组操作转置(输入、轴)
如果交换\u批处理\u时间步:
inputs=nest.map\u结构(\u swap\u batch\u timestep,inputs)
如果国家没有:
states=(tf.zeros(model.inputs[0].shape,dtype='float32'),)
初始状态=状态
输入、输出、时间、时间、步骤、过程参数(模型、输入)
定义步骤(时间、输出时间、*状态):
当前输入=输入数据读取(时间)
输出,新状态=步进函数(当前输入,元组(状态))
展平状态=嵌套。展平(状态)
展开新状态=嵌套。展开(新状态)
对于状态,zip中的新状态(展开状态,展开新状态):
如果存在(新状态,运算张量):
新建状态。设置形状(状态。形状)
输出=输出写入(时间,输出)
新状态=嵌套。打包顺序(初始状态、展开状态和新状态)
返回(时间+1,输出数据)+元组(新状态)
最终输出=tf.while\u循环(
正文=_步,
循环变量=(时间,输出)+元组(初始状态),
cond=lambda时间,*.:tf.math.less(时间,时间步数)
新状态=最终输出[2:]
输出=最终输出[1]
outputs=输出_ta.stack()
返回输出,新状态
定义过程参数(模型、输入):
时间步长=tf.constant(inputs.shape[0],dtype='int32')
#假设单输入网络(不包括州)
输入\u ta=张量\u数组\u ops.TensorArray(
dtype=inputs.dtype,
大小=时间步数,
张量数组\u name='input\u ta_0')。取消堆栈(输入)
#假设单输入网络(不包括州)
#如果有状态,则从非状态节点推断信息
输出=张量数组操作张量数组(
dtype=model.outputs[0].dtype,
大小=时间步数,
元素\形状=模型。输出[0]。形状,
张量_数组_name='output_ta_0')
time=tf.constant(0,dtype='int32',name='time')
返回输入、输出、时间、时间步长

示例和验证

案例设计:我们两次输入相同的内容,这使得某些有状态和无状态的比较成为可能;结果也适用于不同的输入

  • 病例0:对照组;其他案例必须与此相匹配
  • 案例1:失败;梯度不匹配,即使输出和损耗匹配。Backprop在馈送减半序列时失败
  • 案例2:渐变匹配案例1。我们似乎只使用了一个
    tf.while_loop
    ,但SimpleRN在3个时间步中使用了自己的一个tf,并写入一个被丢弃的
    TensorArray
    ;这不行。解决方法是自己实现SimpleRN逻辑
  • 案例3:完美匹配
注意,没有有状态的RNN单元;状态性是在
RNN
基类中实现的,我们在
model\u RNN
中重新创建了它。这同样是处理任何其他层的方式——每次向前传递一个阶梯片

随机导入
将numpy作为np导入
导入tensorflow作为tf
来自tensorflow.keras.layers Import