【问题标题】:Keras Model nested inside of Custom Keras LayerKeras 模型嵌套在自定义 Keras 层内
【发布时间】:2019-02-18 18:01:38
【问题描述】:

我想构建一个 Keras 模型,该模型使用类似于 SPICE 的数值方法进行前向传播。由于 SPICE 问题无法通过分析解决,因此我构建了以下课程。该类可以很好地实现预测(数值前向prorogation)和确定梯度(分析)。

类:

# "..." notes places where code is ommited for conciseness

class SPICE_solver():
    def __init__(self, num_inputs, num_outputs, ...):
    ...
        self.net = build_model_SPICE_solver(num_inputs, num_outputs, ...)

    def predict(self, activations, weights, ...):
        '''
        :param activations:         shape: (?, num_inputs)
        :param weights:             shape: (1, num_inputs, num_outputs)
        :return: vout               shape: (?, num_outputs)
        '''
        ...
        out = np.zeros([activations.shape[0], weights.shape[-1]])
        self.net.fit(x=[activations, weights],
                     y=[out],
                     epochs=200,
                     callbacks=[EarlyStoppingByLossVal(monitor='loss', value=self.acc, verbose=0)],
                     verbose=0,
                     steps_per_epoch=64)
        self.vout = self.net.get_weights()
        return self.vout    # weights incidate the output of the 'layer'

    def gradients(self, activations, weights, ...):
        '''
        :param activations:         shape: (?, num_inputs)
        :param weights:             shape: (?, num_inputs, num_outputs)
        :return: gradient:          list of gradients for: activations, weights (w.r.t. vout)
        '''
        ...
        outputTensor = self.net.output
        listOfVariableTensors = self.net.input
        gradients = K.gradients(outputTensor, listOfVariableTensors)
        sess = tf.InteractiveSession()
        sess.run(tf.initialize_all_variables())
        self.grad = sess.run(gradients, feed_dict={self.net.input[0]:activations, self.net.input[1]:weights})
        return self.grad

我想使用这个类在自定义的更高级别的 Keras 层中完成前向传播 (SPICE_solver.predict) 和反向传播 (SPICE_solver.gradients)。

自定义 Keras 层:

class mac_nonLin_SPICE(Layer):

    def __init__(self,
                 output_dim,
                 **kwargs):
        self.output_dim = output_dim
        super(mac_nonLin_SPICE, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self.kernel = self.add_weight(name='kernel',
                                      shape=(1, int(input_shape[1]), self.output_dim),
                                      initializer='glorot_uniform',
                                      # constraint='UnitNorm',
                                      trainable=True)
        self.slvr = SPICE_solver(int(input_shape[1]), self.output_dim)
        super(mac_nonLin_SPICE, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        return self.slvr.predict(x, self.kernel)

    # def reutrn gradient():????
    # pass

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)

我在以嵌套方式调用 Keras 模型时遇到了很多问题。有没有一种实用的方法可以在自定义 Keras 层中实现这样的对象?

edit:我的直觉告诉我,用低级 TensorFlow API 重建整个设计是最实用的方法,尽管不方便。仍在寻找简单的 Keras 解决方法。

非常感谢任何帮助!

【问题讨论】:

  • 您能否详细说明您遇到的问题?

标签: keras nested layer


【解决方案1】:

简而言之,我无法使用 Keras 完成此任务。这是我找到的最佳解决方案:

我使用 Tensorflow 低级 API 重新创建了网络并定义了两个损失函数:

  • Lo​​ss1:前馈路径中的均方误差(换句话说,如果 loss1 很高,则 SPICE 解决方案不好)
  • Lo​​ss2:均方误差(预测 - 训练数据)

然后,我将优化器设置为最小化: Loss = Loss1 + Loss2 * (1 - Gaus(a * Loss1))

地点:

  • Gaus() 是高斯函数,归一化为幅度 1
  • “a”是一些因素

这样,只有在 Loss1 较小时(当 SPICE 解决方案良好时),才使 Loss2 最小化。

希望这对某人有所帮助。

【讨论】:

    猜你喜欢
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多