Я довольно новичок в TensorFlow (особенно в настройках помимо встроенных потерь / обучения / и т. Д. c), и у меня возникают проблемы с реализацией пользовательской функции потерь для задачи, которую я пытаюсь решить для удовольствия , Я написал простую симуляцию идеализированного планера в двух измерениях, и я хочу обучить нейронную сеть, чтобы летать на ней как можно дальше. Входные данные модели представляют собой массив, содержащий переменные состояния (положение, шаг и их производные), а желаемым выходным значением является управляющая переменная, которая изменяет шаг (по существу, угол моделируемого закрылков лифта ). Для достижения желаемой тренировки функция потерь моделирует полет, а модель обеспечивает контроль и возвращает отрицательный результат пройденного расстояния. Однако, когда я пытаюсь обучить модель, вычисленные градиенты оказываются пустыми. Что я делаю не так, и правильно ли я подхожу к этой проблеме?
Мой код:
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]