Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 Keras历史平均自定义损失函数_Python_Tensorflow_Keras_Loss Function_Generative Adversarial Network - Fatal编程技术网

Python Keras历史平均自定义损失函数

Python Keras历史平均自定义损失函数,python,tensorflow,keras,loss-function,generative-adversarial-network,Python,Tensorflow,Keras,Loss Function,Generative Adversarial Network,我目前正在Keras试验生成性对抗网络。 正如本文所提出的,我想使用历史平均损失函数。这意味着我想惩罚网络权重的变化。 我不知道如何巧妙地实现它 我正在根据post的答案实现自定义丢失功能 def历史平均值包装(当前权重、上一权重): def历史平均值(y_真,y_pred): 差异=0 对于范围内的i(len(当前_权重)): 差异+=abs(np.和(当前权重[i])+np.和(上一权重[i])) 返回K.binary_交叉熵(y_真,y_pred)+diff 返回历史平均值 网络的权值被

我目前正在Keras试验生成性对抗网络。 正如本文所提出的,我想使用历史平均损失函数。这意味着我想惩罚网络权重的变化。 我不知道如何巧妙地实现它

我正在根据post的答案实现自定义丢失功能

def历史平均值包装(当前权重、上一权重):
def历史平均值(y_真,y_pred):
差异=0
对于范围内的i(len(当前_权重)):
差异+=abs(np.和(当前权重[i])+np.和(上一权重[i]))
返回K.binary_交叉熵(y_真,y_pred)+diff
返回历史平均值
网络的权值被惩罚,并且权值在每一批数据之后发生变化

我的第一个想法是在每批之后更新损失函数。 大致如下:

prev_weights=model.get_weights()
对于范围内的i(长度(数据)/批次长度):
当前权重=模型。获取权重()
compile(损失=历史平均包装(当前权重、上一权重),optimizer='adam')
模型拟合(训练数据[i*批量大小:(i+1)*批量大小],训练标签[i*批量大小:(i+1)*批量大小],年代=1,批量大小=批量大小)
上一个权重=当前权重
这合理吗?在我看来,这种方法似乎有点“混乱”。 是否还有其他可能以“更聪明”的方式实现这一点? 比如更新数据生成器中的损失函数并使用fit_generator()?
提前感谢。

损失函数是使用张量对图形进行的操作。 可以在损失函数中定义其他张量来保存以前的值。这是一个例子:

import tensorflow as tf
import tensorflow.keras.backend as K
keras = tf.keras

class HistoricalAvgLoss(object):
  def __init__(self, model):
    # create tensors (initialized to zero) to hold the previous value of the
    # weights
    self.prev_weights = []
    for w in model.get_weights():
      self.prev_weights.append(K.variable(np.zeros(w.shape)))

  def loss(self, y_true, y_pred):
    err = keras.losses.mean_squared_error(y_true, y_pred)
    werr = [K.mean(K.abs(c - p)) for c, p in zip(model.get_weights(), self.prev_weights)]
    self.prev_weights = K.in_train_phase(
        [K.update(p, c) for c, p in zip(model.get_weights(), self.prev_weights)],
        self.prev_weights
    )
    return K.in_train_phase(err + K.sum(werr), err)

变量
prev_weights
保存以前的值。请注意,在计算权重误差后,我们添加了一个
K.update
操作

用于测试的示例模型:

model = keras.models.Sequential([
    keras.layers.Input(shape=(4,)),
    keras.layers.Dense(8),
    keras.layers.Dense(4),
    keras.layers.Dense(1),
])

loss_obj = HistoricalAvgLoss(model)

model.compile('adam', loss_obj.loss)
model.summary()

一些测试数据和目标函数:

import numpy as np

def test_fn(x):
  return x[0]*x[1] + 2.0 * x[1]**2 + x[2]/x[3] + 3.0 * x[3]

X = np.random.rand(1000, 4)
y = np.apply_along_axis(test_fn, 1, X)

hist = model.fit(X, y, validation_split=0.25, epochs=10)

在我的测试中,模型损耗随着时间的推移而减少。

谢谢你回答佩德罗。使用类跟踪以前的权重是个好主意。我还有一个小问题。损失函数中的
模型
变量未定义。我实现了一个包装器函数,如传递模型的问题语句中所示。这似乎奏效了。