"ValueError: No gradients provided for any variable" Custom function in layer present

"ValueError: No gradients provided for any variable" Custom function in layer present

我的代码遇到了一些问题。我给 nn 2 个坐标,它必须将这些转换为 3 个变量(角度)。这些角度用于计算应该以给定点结束的一些向量的位置。当我尝试 运行 代码时,出现上述错误。

import tensorflow as tf
from tensorflow.keras import layers, losses
import numpy as np
from tensorflow.keras import Model
from main import robot_arm

r = robot_arm()
r.set_joints([1, 2, 2])

train_points = []
test_points = []

for i in range(1000000):
    element = []

    for i in range(2):
        element.append(np.random.uniform(-5, 5))

    train_points.append(element)

train_points = np.array(train_points)
print(train_points.shape)

for i in range(10000):
    element = []

    for i in range(2):
        element.append(np.random.uniform(-5, 5))

    test_points.append(element)

test_points = np.array(test_points)
print(test_points.shape)


class robot_arm_ai(Model):
    def __init__(self):
        super(robot_arm_ai, self).__init__()
        self.decoder = tf.keras.Sequential([
            layers.Dense(100, activation='linear'),
            layers.Dense(100, activation='linear'),
            layers.Dense(100, activation='linear'),
            layers.Dense(100, activation='linear'),
            layers.Dense(3),
        ])


    def call(self, x):
        x = self.decoder(x)

        return r.calculate_point(x)





model = robot_arm_ai()



model.compile(optimizer="adam", loss=losses.MeanSquaredError(), run_eagerly=True)

model.fit(train_points, train_points,
          epochs=10,
          shuffle=True,
          batch_size=256,
          validation_data=(test_points, test_points))

这是描述机械臂的代码

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf


class joint():

    def __init__(self, j_len=1, j_rot=0):
        self.rot = j_rot
        self.len = j_len
        self.x_component = 0
        self.y_component = 0
        self.set_vector()

    def print(self):
        print("Length: " + str(self.len))
        print("Rotation: " + str(self.rot))

    def set_vector(self):
        self.y_component = self.len * np.sin(self.rot * (2 * np.pi) )
        self.x_component = self.len * np.cos(self.rot * (2 * np.pi) )

    def random_rotation(self):
        self.rot = np.random.uniform(-360, 360)

    def set_rot(self, rot):
        self.rot = rot

    def random_rotation_set(self):
        self.random_rotation()

    def get_x(self):
        return self.x_component

    def get_y(self):
        return self.y_component


class robot_arm():

    def __init__(self):
        self.joints = []
        self.x = 0
        self.y = 0

    def print(self):
        depth = 0

        for i in self.joints:
            print("- " * 30)
            print("Element " + str(depth))
            i.print()
            depth = depth + 1

    def set_joints(self, lens):
        for i in lens:
            self.joints.append(joint(j_len=i))

    def random_rotation(self):
        for i in self.joints:
            i.random_rotation_set()
        self.set_endpoint()

    def get_point(self):
        return self.x, self.y

    def calculate_point(self, rot):
        res = []
        rot = rot.numpy().tolist()
        for i in rot:
            self.set_rot(i)
            self.set_endpoint()
            res.append(self.get_point())

        return tf.convert_to_tensor( res )

    def set_endpoint(self):
        self.x = 0
        self.y = 0

        for i in self.joints:
            i.set_vector()
            self.x = self.x + i.get_x()
            self.y = self.y + i.get_y()

    def set_rot(self, rots):

        if (len(rots) == len(self.joints)):
            for r, j in zip(rots, self.joints):
                j.set_rot(r)
            self.set_endpoint()

        else:

            print("Failure. Passed Rotations unequal to length of joint chain. Rotation not completed.")
            print(rots.shape)

    def draw_plot(self):

        last_x = 0
        last_y = 0

        for i in self.joints:
            x_val = i.get_x() + last_x
            y_val = i.get_y() + last_y

            plt.plot([last_x, x_val], [last_y, y_val])

            last_y = y_val
            last_x = x_val

        plt.show()



我认为这与通过函数传递层有关,但不确定。 (return r.calculate_point(x))

自定义 LayerModel 应该至少有四种方法: __init__buildcallget_config 。 你的图层只有两个 .

可能与方法 robot_arm.calculate_point 在 tensorflow 之外进行计算有关,因此无法进行反向传播,因为梯度磁带无法“跟踪”从 [=11= 进行的计算] 到 r.calculate_point(x)。参见 https://www.tensorflow.org/guide/autodiff#getting_a_gradient_of_none

因为 robot_arm.calculate_point 方法没有什么可训练的,所以我会将该操作移到 robot_arm_ai.call 方法之外。然后你应该可以训练你的模型了。