自定义层
灵活的构造学习块以适应不同的学习任务是成功的关键
不带参数的层
import tensorflow as tf
class CenteredLayer(tf.keras.Model):
def __init__(self):
super().__init__()
def call(self, inputs):
return inputs - tf.reduce_mean(inputs)
layer = CenteredLayer()
layer(tf.constant([1, 2, 3, 4, 5]))
现在,我们可以将层作为组件合并到更复杂的模型中。
net = tf.keras.Sequential([tf.keras.layers.Dense(128), CenteredLayer()])
作为额外的健全性检查,我们可以在向该网络发送随机数据后,检查均值是否为0。 由于我们处理的是浮点数,因为存储精度的原因,我们仍然可能会看到一个非常小的非零数。
Y = net(tf.random.uniform((4, 8)))
tf.reduce_mean(Y)
<tf.Tensor: shape=(), dtype=float32, numpy=9.313226e-10>
带参数的层
class MyDense(tf.keras.Model):
def __init__(self, units):
super().__init__()
self.units = units
def build(self, X_shape):
self.weight = self.add_weight(name='weight',
shape=[X_shape[-1], self.units],
initializer=tf.random_normal_initializer())
self.bias = self.add_weight(
name='bias', shape=[self.units],
initializer=tf.zeros_initializer())
def call(self, X):
linear = tf.matmul(X, self.weight) + self.bias
return tf.nn.relu(linear)
dense = MyDense(3)
dense(tf.random.uniform((2, 5)))
dense.get_weights()
[array([[ 0.05443877, 0.01740842, 0.04162607],
[ 0.00364623, -0.004619 , -0.0026378 ],
[-0.02005292, 0.01473615, -0.05420518],
[ 0.05924911, -0.09629092, -0.0190375 ],
[-0.03844732, 0.00789924, 0.01320821]], dtype=float32),
array([0., 0., 0.], dtype=float32)]
dense(tf.random.uniform((2, 5)))
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[0.05765551, 0. , 0. ],
[0.02061417, 0. , 0. ]], dtype=float32)>
net = tf.keras.models.Sequential([MyDense(8), MyDense(1)])
net(tf.random.uniform((2, 64)))
<tf.Tensor: shape=(2, 1), dtype=float32, numpy=
array([[0.00316873],
[0.00506903]], dtype=float32)>
小结
-
我们可以通过基本层类设计自定义层。这允许我们定义灵活的新层,其行为与深度学习框架中的任何现有层不同。
-
在自定义层定义完成后,我们就可以在任意环境和网络架构中调用该自定义层。
-
层可以有局部参数,这些参数可以通过内置函数创建。
本文介绍了如何在TensorFlow中创建自定义层,包括不带参数和带参数的层的实现方式。通过实例展示了如何将自定义层集成到更复杂的网络中,并进行了模型的构建和验证。自定义层的灵活性使得能够适应各种学习任务,增强了模型设计的多样性。
1577

被折叠的 条评论
为什么被折叠?



