keras 定义激活函数及layer

简介: 自定义激活函数通过定义个操作 Tensor 的函数,然后将其添加到 keras 系统中即可。from keras.utils.generic_utils import get_custom_objectsdef binary(x): # 注: tf.

自定义激活函数

通过定义个操作 Tensor 的函数,然后将其添加到 keras 系统中即可。

from keras.utils.generic_utils import get_custom_objects

def binary(x):
    # 注: tf.greater 函数没有 gradient 函数,因此在运行时候会报错
    # ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient 
    # defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
    return K.cast(tf.greater(x, 0), tf.uint8)

# custom activation function
get_custom_objects().update({'binary': Activation(binary)})

自定义层

在 keras 层中除去输入层以外,不能使用没有定义 gradient 函数的函数,否则会报错。

因此如下层只能做 Input 层使用:

class MaskLayer(Layer):
    """
    输入与输出维度一致
    输出为 0/1
    """
    def __init__(self, **kwargs):
        self.weight_m = None
        super(MaskLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        self.weight_m = self.add_weight(name='m_weight',
                                        shape=(input_shape[-1], input_shape[-1]),
                                        initializer='glorot_uniform',
                                        trainable=True)
        self.weight_b = self.add_weight(name='m_bias',
                                        shape=(input_shape[-1], ),
                                        initializer='glorot_uniform',
                                        trainable=True)
        super(MaskLayer, self).build(input_shape)

    def call(self, x, **kwargs):
        m = K.dot(x, self.weight_m) + self.weight_b
        m = tf.layers.batch_normalization(m)

        # 注: tf.greater_equal 函数没有 gradient 函数,因此在运行时候会报错
        # ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient 
        # defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
        return K.cast(K.greater_equal(x, 0), tf.uint8)

    def compute_output_shape(self, input_shape):
        return input_shape

对于Layer的定义也可以通过 Activation 定义的方式一样,通过 get_custom_objects 的方式添加到 keras 系统中去。

自定义初始化函数

from keras import backend as K
import numpy as np

def my_init(shape, name=None):
    value = np.random.random(shape)
    return K.variable(value, name=name)

model.add(Dense(64, init=my_init))

这里主要能初始化的内容是 float 数据类型

获取上层输出维度

简单的通过 python 命令行,查看下 Layer 属性相关内容:

>>> from tensorflow.keras.layers import Input, Dense
/srv/anaconda/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
>>> inp = Input(shape=(3,))
>>> inp
<tf.Tensor 'input_1:0' shape=(?, 3) dtype=float32>
>>> inp.shape
TensorShape([Dimension(None), Dimension(3)])
>>> m = Dense(10)(inp)
>>> m.shape
TensorShape([Dimension(None), Dimension(10)])

在 Layer 定义过程中使用上层输出来做为本层的维度定义, 比如:

from keras.models import Model
from keras.layers import Input, Dense, Conv2D, Flatten, MaxPool2D

inp = Input(shape=(20, 20, 1, ))
m = Conv2D(16, kernel_size=(3, inp.shape[2].value))(inp)
m = MaxPool2D(pool_size=(m.shape[1].value, 1))(m)
m = Flatten()(m)
outp = Dense(m.shape[-1].value)(m)
model = Model(inputs=inp, outputs=outp)
model.summary()

输出如下内容:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         (None, 20, 20, 1)         0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 18, 1, 16)         976       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 1, 1, 16)          0         
_________________________________________________________________
flatten (Flatten)            (None, 16)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 16)                272       
=================================================================
Total params: 1,248
Trainable params: 1,248
Non-trainable params: 0
_________________________________________________________________
目录
相关文章
|
6月前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch基础之激活函数模块中Sigmoid、Tanh、ReLU、LeakyReLU函数讲解(附源码)
PyTorch基础之激活函数模块中Sigmoid、Tanh、ReLU、LeakyReLU函数讲解(附源码)
297 0
|
1月前
|
机器学习/深度学习 编解码
深度学习笔记(三):神经网络之九种激活函数Sigmoid、tanh、ReLU、ReLU6、Leaky Relu、ELU、Swish、Mish、Softmax详解
本文介绍了九种常用的神经网络激活函数:Sigmoid、tanh、ReLU、ReLU6、Leaky ReLU、ELU、Swish、Mish和Softmax,包括它们的定义、图像、优缺点以及在深度学习中的应用和代码实现。
129 0
深度学习笔记(三):神经网络之九种激活函数Sigmoid、tanh、ReLU、ReLU6、Leaky Relu、ELU、Swish、Mish、Softmax详解
|
3月前
|
机器学习/深度学习
网络层构建(tf.keras.layers)
【8月更文挑战第20天】网络层构建(tf.keras.layers)。
39 2
|
4月前
ReLU函数
【7月更文挑战第24天】ReLU函数。
97 1
|
6月前
|
机器学习/深度学习 TensorFlow API
Keras 的模型(Model)和层(Layers)的介绍
Keras 的模型(Model)和层(Layers)的介绍
156 1
|
机器学习/深度学习 PyTorch 算法框架/工具
pytorch中nn.ReLU()和F.relu()有什么区别?
pytorch中nn.ReLU()和F.relu()有什么区别?
543 0
|
计算机视觉
Dynamic ReLU:根据输入动态确定的ReLU
这是我最近才看到的一篇论文,它提出了动态ReLU (Dynamic ReLU, DY-ReLU),可以将全局上下文编码为超函数,并相应地调整分段线性激活函数。与传统的ReLU相比,DY-ReLU的额外计算成本可以忽略不计,但表示能力明显增强,并且实现简单,所以可以非常简单的对我们现有的模型进行修改。
145 0
|
机器学习/深度学习 PyTorch 算法框架/工具
Linear Model 线性模型
Linear Model 线性模型
86 0
|
机器学习/深度学习 PyTorch 算法框架/工具
【PyTorch】nn.ReLU()与F.relu()的区别
【PyTorch】nn.ReLU()与F.relu()的区别
155 0
|
机器学习/深度学习
深度学习入门基础CNN系列——池化(Pooling)和Sigmoid、ReLU激活函数
池化是使用某一位置的相邻输出的总体统计特征代替网络在该位置的输出,其好处是当输入数据做出少量平移时,经过池化函数后的大多数输出还能保持不变。比如:当识别一张图像是否是人脸时,我们需要知道人脸左边有一只眼睛,右边也有一只眼睛,而不需要知道眼睛的精确位置,这时候通过池化某一片区域的像素点来得到总体统计特征会显得很有用。由于池化之后特征图会变得更小,如果后面连接的是全连接层,能有效的减小神经元的个数,节省存储空间并提高计算效率。
462 1
深度学习入门基础CNN系列——池化(Pooling)和Sigmoid、ReLU激活函数