Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.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 如何正确使用GradientTape在TensorFlow中创建自定义损失函数?_Python_Tensorflow_Keras - Fatal编程技术网

Python 如何正确使用GradientTape在TensorFlow中创建自定义损失函数?

Python 如何正确使用GradientTape在TensorFlow中创建自定义损失函数?,python,tensorflow,keras,Python,Tensorflow,Keras,我对TensorFlow(特别是内置损耗/培训/等之外的定制)相当陌生,我很难为一个我试图解决的问题实现自定义损耗函数。我写了一个二维理想滑翔机的简单模拟,我想训练一个神经网络,让它尽可能地飞远。模型的输入是一个包含状态变量(位置、俯仰及其导数)的数组,而期望的输出是一个改变俯仰的控制变量(基本上是模拟对象的角度)。为了实现我想要的训练,损失函数模拟飞行,模型提供控制,并返回行程的负数。然而,当我尝试训练模型时,计算出的梯度结果是空的。我做错了什么?我处理这个问题的方式正确吗 我的代码: def

我对TensorFlow(特别是内置损耗/培训/等之外的定制)相当陌生,我很难为一个我试图解决的问题实现自定义损耗函数。我写了一个二维理想滑翔机的简单模拟,我想训练一个神经网络,让它尽可能地飞远。模型的输入是一个包含状态变量(位置、俯仰及其导数)的数组,而期望的输出是一个改变俯仰的控制变量(基本上是模拟对象的角度)。为了实现我想要的训练,损失函数模拟飞行,模型提供控制,并返回行程的负数。然而,当我尝试训练模型时,计算出的梯度结果是空的。我做错了什么?我处理这个问题的方式正确吗

我的代码:

def fall(control_model):
    #initialize physics constants and state variables
    dt, g = 1/25, 9.805
    x, y, theta = 0, 100, np.radians(-15)
    vx, vy, vtheta = 0, 0, 0

    while y > 0: #for each time step until we hit the ground:
        #preliminary calculations for aerodynamics
        vsq, vang, aoa = vx*vx + vy*vy, np.arctan2(vy, vx), theta - vang
        while aoa <= -np.pi:
            aoa += 2*np.pi
        while aoa > np.pi:
            aoa -= 2*np.pi
        aero, aeroang = 1*vsq*np.square(np.sin(aoa)), aoa%np.pi + np.pi/2 + vang

        #make an array of state variables and pass it to the model to get the control variable c
        state = np.asarray([[x/100, y/100, theta/np.pi, vx/10, vy/10, vtheta/np.pi]], dtype = np.float32)
        c = control_model(state).numpy()[0][0]

        #integrate acceleration into speed into position
        vx += aero*np.cos(aeroang)*dt
        vy += (aero*np.sin(aeroang) - g)*dt
        vtheta += (
                0.1*vsq*np.cos(aoa)*0.5*np.sin(2*np.radians(c)) #control term
                -0.05*vsq*np.square(np.sin(aoa))*np.sign(aoa) #angle of attack tends to zero
                -0.8*vtheta)*dt #damping
        x += vx*dt
        y += vy*dt
        theta += vtheta*dt
    return -x #the loss is the negative of distance traveled

control = tf.keras.Sequential() #simple model for MWE
control.add(tf.keras.layers.Dense(4, activation = "relu", input_shape = (6,)))
control.add(tf.keras.layers.Dense(1, activation = "sigmoid"))

with tf.GradientTape() as tape:
    loss2 = tf.Variable(fall(control))
gradients = tape.gradient(loss2, control.trainable_variables)
print(gradients) #prints [None, None, None, None]
def下降(控制模式):
#初始化物理常数和状态变量
dt,g=1/25,9.805
x、 y,θ=01100,np.弧度(-15)
vx,vy,vtheta=0,0,0
当y>0时:#对于每个时间步,直到我们落地:
#空气动力学的初步计算
vsq,vg,aoa=vx*vx+vy*vy,np.arctan2(vy,vx),θ-vg
而aoa np.pi:
aoa-=2*np.pi
aero,aeroang=1*vsq*np.square(np.sin(aoa)),aoa%np.pi+np.pi/2+vang
#创建一个状态变量数组,并将其传递给模型以获得控制变量c
state=np.asarray([[x/100,y/100,theta/np.pi,vx/10,vy/10,vtheta/np.pi]],dtype=np.float32)
c=控制\模型(状态).numpy()[0][0]
#将加速度与速度整合到位置
vx+=航空*np.cos(航空)*dt
vy+=(气动*np.sin(气动)-g)*dt
vtheta+=(
0.1*vsq*np.cos(aoa)*0.5*np.sin(2*np.radians(c))#控制项
-0.05*vsq*np.平方(np.sin(aoa))*np.符号(aoa)#迎角趋于零
-0.8*vtheta)*dt#阻尼
x+=vx*dt
y+=vy*dt
θ+=vtheta*dt
return-x#损失是行驶距离的负数
control=tf.keras.Sequential()#MWE的简单模型
control.add(tf.keras.layers.Dense(4,activation=“relu”,input_shape=(6,))
control.add(tf.keras.layers.density(1,activation=“sigmoid”))
使用tf.GradientTape()作为磁带:
loss2=tf.变量(下降(控制))
梯度=磁带梯度(loss2,控制可训练的变量)
打印(渐变)#打印[无,无,无,无]

您需要为以下每个变量调用g.watch: 参考:

input_images_tensor = tf.constant(input_images_numpy)
with tf.GradientTape() as g:
    g.watch(input_images_tensor)
    output_tensor = model(input_images_tensor)

gradients = g.gradient(output_tensor, input_images_tensor)