使用自定义损失函数的自定义Keras模型出现错误

我在构建一个具有自定义损失和激活函数的三层神经网络时遇到了以下错误:

File "C:\Users\untitled1.py", line 196, in <module>    cModel.fit(X_train, y_train, batch_size=64, epochs=2)  File "C:\Users\\Anaconda3\lib\site-packages\keras\engine\training.py", line 1184, in fit    tmp_logs = self.train_function(iterator)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py", line 885, in __call__    result = self._call(*args, **kwds)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py", line 933, in _call    self._initialize(args, kwds, add_initializers_to=initializers)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py", line 759, in _initialize    self._stateful_fn._get_concrete_function_internal_garbage_collected(  # pylint: disable=protected-access  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 3066, in _get_concrete_function_internal_garbage_collected    graph_function, _ = self._maybe_define_function(args, kwargs)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 3463, in _maybe_define_function    graph_function = self._create_graph_function(args, kwargs)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 3298, in _create_graph_function    func_graph_module.func_graph_from_py_func(  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\framework\func_graph.py", line 1007, in func_graph_from_py_func    func_outputs = python_func(*func_args, **func_kwargs)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\eager\def_function.py", line 668, in wrapped_fn    out = weak_wrapped_fn().__wrapped__(*args, **kwds)  File "C:\Users\\Anaconda3\lib\site-packages\tensorflow\python\framework\func_graph.py", line 994, in wrapper    raise e.ag_error_metadata.to_exception(e)TypeError: in user code:    C:\Users\\Anaconda3\lib\site-packages\keras\engine\training.py:853 train_function  *        return step_function(self, iterator)    TypeError: tf__compile() missing 1 required positional argument: 'loss'

我使用的代码如下所示。我尝试使用自己的自定义损失函数和Keras的损失函数,但都出现了相同的错误。如果我只是初始化一个Keras的顺序模型并加入我的损失函数,它就能正常工作。但对于我的自定义模型就不行,我使用自定义模型是因为我还想在之后自定义优化方法。这个错误该如何解决?

#%% Functionsclass CustomModel(keras.Model):    #initialize the model with the beta needed and the dimensions    def __init__(self, b, input_dim):        #first i initialized it as self, model and without the call function        #but this gave me an error that said i needed a call function thus i changed it to this        super(CustomModel, self).__init__()        self.dim = keras.Input( shape=(input_dim,))        self.dense1 = keras.layers.Dense(20, name='hidden', kernel_initializer=initializer,                  bias_initializer=initializer, activation = lambda x: K.tanh(b*x))        self.dense2 = keras.layers.Dense(2, activation='linear', name='output', use_bias=False, trainable=False,kernel_initializer= lambda shape,                  dtype: initializeOutputWeights(shape, dtype))        def call(self):        x1 = self.dense1(self.dim)        return self.dense2(x1)        def compile(self, optimizer, loss):        #for the use of the custom loss function        super(CustomModel, self).compile()        self.optimizer = optimizer        self.loss = loss            def train_step(self, data):        # Unpack the data. Its structure depends on your model and        # on what you pass to `fit()`.        x, y = data                with tf.GradientTape() as tape:            y_pred = self(x, training=True)  # Forward pass            # Compute the loss value            # (the loss function is configured in `compile()`)            loss = self.loss(y, y_pred, regularization_losses=self.losses)        # Compute gradients        trainable_vars = self.trainable_variables        gradients = tape.gradient(loss, trainable_vars)        # Update weights        self.optimizer.apply_gradients(zip(gradients, trainable_vars))        # Update metrics (includes the metric that tracks the loss)        self.compiled_metrics.update_state(y, y_pred)        # Return a dict mapping metric names to current value        return {m.name: m.result() for m in self.metrics}def initializeOutputWeights(shape, dtype=None):    #output weights are initialized as 1 or -1 and not changed afterwards    randoms = np.random.randint(low=2, size=shape)    new = np.where(randoms==0, -1, randoms)    return K.variable(new, dtype=dtype)class customLoss(keras.losses.Loss):    #the custom loss function of the GVM    def __init__(self, d=10, name = "CustomLoss"):        #need the margin d        super().__init__(name=name)        self.d = d                def call(self,y_true, y_pred):        #calculate the loss        N = len(y_true)        L = len(y_pred[0])        y_dot = y_pred*y_true        y_d = y_dot-self.d        y_square= y_d*y_d        index_replace = y_dot>self.d        idx_replace=tf.where(index_replace==True)        y_loss = tf.tensor_scatter_nd_update(y_square, idx_replace, tf.zeros(len(idx_replace)))        return tf.divide(K.sum(K.sum(y_loss, axis=1)),tf.cast(N*L, tf.float32))seed(1)tf.random.set_seed(2)acc_metric = keras.metrics.SparseCategoricalAccuracy(name="accuracy")initializer = tf.keras.initializers.RandomUniform(minval=-1, maxval=1)b = np.ones(20)cModel = CustomModel(b, 9)Losscustom = customLoss(d=16)cModel.compile(optimizer='adam',loss=Losscustom)cModel.fit(X_train, y_train, batch_size=64, epochs=2)

回答:

您似乎将一些不兼容的构造混淆了。我建议您定义自己的自定义训练循环,这将为您提供所需的灵活性:

首先定义您的模型:

导入tensorflow as tf导入random导入numpy as npdef initializeOutputWeights(shape, dtype=None):    #输出权重被初始化为1或-1,并且之后不会更改    randoms = np.random.randint(low=2, size=shape)    new = np.where(randoms==0, -1, randoms)    return tf.keras.backend.variable(new, dtype=dtype)class CustomModel(tf.keras.Model):   def __init__(self, b, input_dim):        #最初我将其初始化为self, model并且没有call函数        #但这导致了一个错误,说我需要一个call函数,因此我将其更改为这样        super(CustomModel, self).__init__()        initializer = tf.keras.initializers.RandomUniform(minval=-1, maxval=1)        self.dense = tf.keras.layers.Dense(20, name='hidden', kernel_initializer=initializer,                  bias_initializer=initializer, activation = lambda x: tf.tanh(b*x), input_shape=(input_dim,))        self._output = tf.keras.layers.Dense(2, activation='linear', name='output', use_bias=False, trainable=False,kernel_initializer= lambda shape,                  dtype: initializeOutputWeights(shape, dtype))   def call(self, inputs):        x =  self.dense(inputs)        return self._output(x)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注