将自定义层创建为单个神经元的堆栈 TensorFlow [英] Creating custom layer as stack of individual neurons TensorFlow

查看:33
本文介绍了将自定义层创建为单个神经元的堆栈 TensorFlow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我尝试在 TensorFlow 2.4.1 中创建一个自定义层,使用我定义的神经元函数.

So, I'm trying to create a custom layer in TensorFlow 2.4.1, using a function for a neuron I defined.

# NOTE: this is not the actual neuron I want to use,
# it's just a simple example.
def neuron(x, W, b):
    return W @ x + b

Wb 的形状是 (1, x.shape[0])(1, 1) 分别.这意味着这就像密集层中的单个神经元.因此,我想通过堆叠任意数量的这些单个神经元来创建一个密集层.

Where the W and b it gets would be of shape (1, x.shape[0]) and (1, 1) respectively. This means this is like a single neuron in a dense layer. So, I want to create a dense layer by stacking however many of these individual neurons I want.

class Layer(tf.keras.layers.Layer):
    def __init__(self, n_units=5):
        super(Layer, self).__init__() # handles standard arguments
        
        self.n_units = n_units # Number of neurons to be in the layer

    def build(self, input_shape):
        # Create weights and biases for all neurons individually
        for i in range(self.n_units):
            # Create weights and bias for ith neuron
            ...

    def call(self, inputs):
        # Compute outputs for all neurons
        ...
        # Concatenate outputs to create layer output
        ...
        return output

我如何将层创建为单个神经元的堆栈(也以它可以训练的方式)?我在上面的代码中粗略地概述了层的想法,但答案不需要将其作为蓝图来遵循.

How can I create a layer as a stack of individual neurons (also in a way it can train)? I have roughly outlined the idea for the layer in the above code, but the answer doesn't need to follow that as a blueprint.

最后;是的,我知道要创建一个密集层,您不需要以这种迂回的方式进行(您只需要 1 个权重和偏置矩阵),但在我的实际用例中,这是必要的.谢谢!

推荐答案

所以,在这里问这个问题的人,我已经找到了一种方法,通过动态创建变量和操作.
首先,让我们重新定义神经元以使用张量流操作:

So, person who asked this question here, I have found a way to do it, by dynamically creating variables and operations.
First, let's re-define the neuron to use tensorflow operations:

def neuron(x, W, b):
    return tf.add(tf.matmul(W, x), b)

然后,让我们创建图层(这使用了问题中布置的蓝图):

Then, let's create the layer (this uses the blueprint layed out in the question):

class Layer(tf.keras.layers.Layer):
    def __init__(self, n_units=5):
        super(Layer, self).__init__()

        self.n_units = n_units

    def build(self, input_shape):
        for i in range(self.n_units):
            exec(f'self.kernel_{i} = self.add_weight("kernel_{i}", shape=[1, int(input_shape[0])])')
            exec(f'self.bias_{i} = self.add_weight("bias_{i}", shape=[1, 1])')

    def call(self, inputs):
        for i in range(self.n_units):
            exec(f'out_{i} = neuron(inputs, self.kernel_{i}, self.bias_{i})')
        return eval(f'tf.concat([{", ".join([ f"out_{i}" for i in range(self.n_units) ])}], axis=0)')

如您所见,我们使用 execeval 来动态创建变量并执行操作.
就是这样!我们可以执行一些检查,看看 TensorFlow 是否可以使用它:

As you can see, we're using exec and eval to dynamically create variables and perform operations.
That's it! We can perform a few checks to see if TensorFlow could use this:

# Check to see if it outputs the correct thing
layer = Layer(5) # With 5 neurons, it should return a (5, 6)
print(layer(tf.zeros([10, 6])))

# Check to see if it has the right trainable parameters
print(layer.trainable_variables)

# Check to see if TensorFlow can find the gradients
layer = Layer(5)
x = tf.ones([10, 6])
with tf.GradientTape() as tape:
    z = layer(x)
print(f"Parameter: {layer.trainable_variables[2]}")
print(f"Gradient:  {tape.gradient(z, layer.trainable_variables[2])}")

这个解决方案有效,但不是很优雅......我想知道有没有更好的方法可以做到,一些神奇的TF方法可以映射神经元创建层,我暂时不知道.所以,如果您有(更好的)答案,请回答,我很乐意接受:)

This solution works, but it's not very elegant... I wonder if there's a better way to do it, some magical TF method that can map the neuron to create a layer, I'm too inexperienced to know for the moment. So, please answer if you have a (better) answer, I'll be happy to accept it :)

这篇关于将自定义层创建为单个神经元的堆栈 TensorFlow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆