【问题标题】:How do I properly use GradientTape to make a custom loss function in TensorFlow?如何正确使用 GradientTape 在 TensorFlow 中制作自定义损失函数?
【发布时间】:2020-08-01 11:29:22
【问题描述】:

我对 TensorFlow 还很陌生(尤其是内置损失/训练/等之外的自定义),我在为我试图解决的问题实现自定义损失函数时遇到了麻烦。我已经编写了一个简单的二维理想化滑翔机模拟,我想训练一个神经网络让它飞得尽可能远。模型的输入是包含状态变量(位置、俯仰及其导数)的数组,所需的输出是改变俯仰的控制变量(本质上是模拟elevator flaps 的角度)。为了实现我想要的训练,损失函数模拟飞行,模型提供控制,并返回飞行距离的负值。但是,当我尝试训练模型时,计算出的梯度变为空。我做错了什么,我是否以正确的方式解决这个问题?

我的代码:

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]

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    您需要为以下每个变量调用 g.watch: 参考:https://www.tensorflow.org/api_docs/python/tf/GradientTape

    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)
    

    【讨论】:

      猜你喜欢
      • 2020-04-11
      • 1970-01-01
      • 2018-11-25
      • 2018-10-28
      • 2017-12-29
      • 2018-04-27
      • 2021-03-11
      • 2018-02-08
      • 2021-06-07
      相关资源
      最近更新 更多