Keras, high-level 的 Neural Network 框架.

简介

一些特点:

  • 提供了对 tensorflow low-level api 的高级封装,用户代码更清爽, 简洁.

  • 各种新式trick都有,比如Batch normalization,PReLU等等

  • 架构灵活,model基于一层层的layer叠加,可插拔性十分强

  • 作者简介
    keras 之父, google brain 研究员 François Chollet, 他也参与了 TensorFlow 的框架研发.

一. Layer

类比于 torch 中的 Module, 是一个计算子图的抽象与封装, 面向对象的风格更易阅读维护.

1.1 api

  • class tf.keras.layers.Layer, 位于 tensorflow.python.keras.engine.base_layer.Layer. 是抽象类.

    • __init__(self, trainable=True, name=None, dtype=None, **kwargs)
    • build(), 创建 variable 并 构图. Called once from __call__(). 子类覆写时, 用户逻辑后要调用 super’s build().
    • call(), 用户自定义逻辑写在这里.
  • 简明源码

    @tf_export('keras.layers.Layer')
    class Layer(checkpointable.CheckpointableBase):
    	@property
    	def name(self):
    		return self._name
    	@property
    	def variables(self):
    		return self.weights
    		
    	def build(self, input_shape):
    		"""Creates the variables of the layer."""
    		self.built = True
    
    	def add_weight(self,
                     name,
                     shape,
                     dtype=None,
                     initializer=None,
                     regularizer=None,
                     trainable=None,
                     constraint=None,
                     partitioner=None,
                     use_resource=None,
                     synchronization=tf_variables.VariableSynchronization.AUTO,
                     aggregation=tf_variables.VariableAggregation.NONE,
                     **kwargs):
    		pass
    		return variable
    
    
    	def call(self, inputs, **kwargs): 
    		return inputs
    	
    	def __call__(self, inputs, *args, **kwargs):
    		with ops.name_scope(self._name_scope()):
    			if not self.built:
    				self.build(input_shapes)
    				self.built = True
    			outputs = self.call(inputs, *args, **kwargs)
    		return outputs
    	  	
    
  • class tensorflow.python.layers.base.Layer, 过时的 class, 要用 keras Layer 替代.

1.2 库中自带子类

1.2.1 Dense

  • keras.layers.core.Dense(Layer)
    普通的全连接神经网络层.
  • Dense#__init__(self, units,
    activation=None,
    use_bias=True,
    kernel_initializer=‘glorot_uniform’,
    bias_initializer=‘zeros’,
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None,
    **kwargs)
# 以下两行等价
model.add(Dense(32, input_shape=(784,)))
model.add(Dense(32, input_dim=784))
# 只有首层需要指定输入维度. 后续各层只需指定神经元个数.
Dense(10, activation='relu', input_dim=4)

1.2.2 activation

  • keras.layers.advanced_activations.PReLU(Layer)
  • keras.activations 模块
    有 softplus, relu, tanh 等.

1.2.3 dropout

  • keras.layers.core.Dropout(Layer)
    类.
  • Dropout#__init__(self, rate, noise_shape=None, seed=None, **kwargs)
    rate 指的是要扔掉的占比, 而不是keep_rate.

1.2.4 batach nomarlization

  • keras.layers.normalization.BatchNormalization(Layer)
    类. 对前面一层每个batch的输出作正规化.
  • BatchNormalization#__init__(self,
    axis=-1,
    momentum=0.99,
    epsilon=1e-3,
    center=True,
    scale=True,
    beta_initializer=‘zeros’,
    gamma_initializer=‘ones’,
    moving_mean_initializer=‘zeros’,
    moving_variance_initializer=‘ones’,
    beta_regularizer=None,
    gamma_regularizer=None,
    beta_constraint=None,
    gamma_constraint=None,
    **kwargs)

1.3 用户自定义子类

为了代码重用, 风格一致,可以自定义 layer. 详见参考[3].
一般地, 在build()中创建参数, 在call()中基于已创建的参数(即 trainable variables) 作逻辑实现.

命名空间 variable_scope 的讨论: 若没有给 self._scope 赋值, 则 tf 会解析你的大驼峰格式类名(如FeedForward) 转化为小写字符串加下划线的格式(如 feed_forward).

class FeedForward(tf.keras.layers.Layer):
    """position-wise feed forward net. See 3.3

    inputs: A 3d tensor with shape of [N, T, C].
    num_units: A list of two integers.

    Returns:
      A 3d tensor with the same shape and dtype as inputs
    """

    def __init__(self, num_units, scope='position_wise_feed_forward',**kwargs):
        # self._scope = scope
        self.num_units = num_units
        super(FeedForward,self).__init__(**kwargs)

    def call(self, inputs, **kwargs):
        # Inner layer, ReLU
        outputs = Dense(self.num_units[0], activation=tf.nn.relu)(inputs)
        # Outer layer, linear
        outputs = Dense(self.num_units[1])(outputs)
        # Residual connection
        outputs += inputs
        # Normalize
        outputs = layer_norm(outputs)

        return outputs

build() 方法

可以把 self.add_weight() 这样的调用从 构造方法中 下放到 build() 方法中. 一方面逻辑更清晰, 还可以做到 shape 的延迟(lazy)确定.

def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units))

1.4. layer 重用

多个不同的输入共享同样的网络处理. 详见参考[3].
使用举例: 在DSSM中, 输入是[query, {doc_1,doc_2,…,doc_n}]. 只有两个网络, 分别映射两种不同类型的文本. 所以多个doc的输入就要共享第二个网络.
可以与tf的API搭配使用. 比如

self.keras_shared_content_sideinfo_linear_layer = tf.keras.layers.Dense(units=128, input_shape=[128+64+128, ],name='keras_shared_content_sideinfo_linear_layer')
def get_content_emb(self):
	# ...
	content_side_info_concat = tf.concat(content_side_info_tensors, axis=-1)
	emb = self.keras_shared_content_sideinfo_linear_layer(content_side_info_concat)

二. Model

2.1 api

  • class tensorflow.python.keras.engine.training.Model
    存在 keras.Layer <- keras.Network <- keras.Model 的派生关系.

2.2 用户自定义子类

详见参考[3].

2.3 model 搭建

序列模型函数式模型 两种网络拓扑搭建法.
在处理像TextCNN这种 先分支再融合 的网络, 函数式模型更灵活.

Sequential 序列风格

  • keras.models.Sequential(Model)
    类. 代表普通的多层前馈神经网络.
  • keras.models.Sequential#add(self,layer)
    方法. 像搭积木一样, 往后加上一层.
model = Sequential()
model.add(Dense(10, activation='relu', input_dim=4))
model.add(Dropout(0.8))
model.add(Dense(5, activation='relu'))
model.add(Dense(3, activation='softmax'))

函数式风格

与上面对比.

inputs=Input(shape=(FEATURE_DIM,))
dense1=Dense(10, activation='relu', input_dim=4)(inputs)
dense2=Dense(5, activation='relu')(dense1)
outpus=Dense(3, activation='softmax')(dense2)
# type(dense2) 是 Tensor类型, tensorflow.python.framework.ops.Tensor ,与backend有关.
model=Model(inputs=inputs,outputs=outpus)

这种调用方法看起来比较特殊, 因为Layer类拥有__call__()方法, 它的对象就变成了可调用对象.

模型拓扑

model.summary()
"""
会得到以下输出: 各层的out_shape
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         (None, 4)                 0         
_________________________________________________________________
dense_5 (Dense)              (None, 10)                50        
_________________________________________________________________
dense_6 (Dense)              (None, 5)                 55        
_________________________________________________________________
dense_7 (Dense)              (None, 3)                 18        
=================================================================
Total params: 123
Trainable params: 123
Non-trainable params: 0
_________________________________________________________________
"""

#边写边调试的时候, 可以用`dense2._keras_shape`字段来查看output_shape.
dense2._keras_shape #(None, 5)
# 也可以直接print tensor
print (embedding) #Tensor("embedding_1/Gather:0", shape=(?, 10, 10), dtype=float32)

还可以画图, 见我的另一篇博文,keras 的可视化

三. train loop 相关

5. compile

  • keras.models.Sequential#compile(self, optimizer, loss,
    metrics=None,
    … )
    对模型描述进行编译, 然后才能训练.
  • metrics
    常用的有 ‘accuracy’, ‘mae’
  • loss
    详见 keras.losses模块, 常用的有:
    mse = MSE = mean_squared_error
    mae = MAE = mean_absolute_error
    mape = MAPE = mean_absolute_percentage_error

6.fit

  • keras.engine.training.Model#fit(self, x=None,
    y=None,
    batch_size=None,
    epochs=1,
    verbose=1,
    callbacks=None,
    validation_split=0.,
    validation_data=None,
    shuffle=True,
    class_weight=None,
    sample_weight=None,
    initial_epoch=0,
    steps_per_epoch=None,
    validation_steps=None,
    **kwargs)
    训练模型, 类 sklearn 的写法.
    可以加入validation_data, 观察各种指标在训练期间在验证集上的表现. 如 validation_data=([x_1,x_2],[y_1,y_2]),也支持多输入和多输出.
  • verbose
    建议设置为2, 表示每个epoch只输出一行.

7. callback

fit()函数中的callbacks参数可以传入一个list, 包含丰富的callbacks.
keras自带了一些使用的callback实现类.

  • EarlyStopping
    keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, verbose=1, mode='auto')
    并使用各种callback来达到early stop的目的.
  • ModelCheckpoint
    keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)
  • save_best_only:当设置为True时,将只保存在验证集上性能最好的模型

8. evaluate

  • keras.engine.training.Model#metrics_names
    字段. 一个模型的多个metric值. 同 compile 阶段的 metric.
  • keras.engine.training.Model#evaluate(self, x, y,
    batch_size=None,
    verbose=1,
    sample_weight=None,
    steps=None)
    Returns the loss value & metrics values for the model in test mode. 与 keras.engine.training.Model#metrics_names 一 一对应.

参考

  1. keras 官方文档
  2. keras 官方文档, shared-layers
  3. keras&tf 官方文档, making_new_layers_and_models_via_subclassing
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值