创建神经网络之keras与tensorflow方法比较

在一个学习讨论组里被提问到:使用tensorflow创建网络模型时采用 tf.keras 和 tf.layers 哪种比较好?二话没说直接上代码。

把tensorflow官方的MNIST例子直接拿过来比较:

1、tf.layers

def model_fn(features, labels, mode, config):
    """
    用tf.layers创建网络模型
    :param features: 特征数据
    :param labels: 标签
    :param mode: 模式:tf.estimator.ModeKeys:TRAIN、EVAL、PREDICT
    :param config
    :return:
    """
    # 批次为-1 宽高为28x28 通道为1
    batch_size = -1
    image_width = 28
    image_height = 28
    channels = 1
    class_num = 10
    learning_rate = 1e-4
    input_height = image_height
    input_width = image_width
    # 输入层:
    input_layer = tf.reshape(features['x'], [batch_size, image_height, image_width, channels])
    # 卷积层1: 32个 5x5 过滤器 + ReLU激活函数
    conv1 = tf.layers.conv2d(inputs=input_layer,
                             filters=32,
                             kernel_size=[5, 5],
                             padding='same',
                             activation=tf.nn.relu)
    # 池化层1: 2x2 过滤器 + 步长为2
    pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
    input_height = input_height // 2
    input_width = input_width // 2
    # 卷积层2: 64个 5x5 过滤器 + ReLU激活函数
    conv2 = tf.layers.conv2d(inputs=pool1,
                             filters=64,
                             kernel_size=[5, 5],
                             padding='same',
                             activation=tf.nn.relu)
    # 池化层2
    pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
    input_height = int(input_height // 2)
    input_width = int(input_width // 2)
    pool2_flat = tf.reshape(pool2, [-1, input_height * input_width * 64])
    # 密集层: 1024个神经元 + 丢弃正则化率为0.4
    dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
    dropout = tf.layers.dropout(inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
    # 对数层: 10个神经元即分类类别0-9
    logits = tf.layers.dense(inputs=dropout, units=class_num)

2、tf.keras

def create_model(data_format):
    """
    用Keras创建网络模型
    :param data_format:
    :return:
    """
    image_width = 28
    image_height = 28
    channels = 1
    class_num = 10
    if data_format == 'channels_first':
        # (batch, channels, height, width) default
        input_shape = [channels, image_height, image_width]
    else:
        # (batch, height, width, channels)
        assert data_format == 'channels_last'
        input_shape = [image_height, image_width, channels]
    layer = tf.keras.layers
    # 池化层: pool_size=(2,2)  strides=(2,2)
    max_pool = layer.MaxPool2D((2, 2), (2, 2), padding='same', data_format=data_format)
    return tf.keras.Sequential([
        layer.Reshape(target_shape=input_shape,
                      input_shape=(image_height * image_width,)),
        layer.Conv2D(filters=32,
                     kernel_size=5,
                     padding='same',
                     data_format=data_format,
                     activation=tf.nn.relu),
        max_pool,
        layer.Conv2D(filters=64,
                     kernel_size=5,
                     padding='same',
                     data_format=data_format,
                     activation=tf.nn.relu),
        max_pool,
        layer.Flatten(),
        layer.Dense(1024, activation=tf.nn.relu),
        layer.Dropout(0.4),
        layer.Dense(class_num)
    ])

从上面两段代码中可见,tf.layers代码稍多,需要手动计算flat层的shape;而tf.keras就比较简洁,类似流式的网络构建方式将模型的网络展示的简单明了。

tensorflow1.11.0发布时就已经对keras增强了支持,可以发现tensorflow已经有意向将keras升级为一级网络操作API,毕竟keras和tensorflow都是google的,进行合理的资源整合提升tensorflow的生态布局很有必要。其实采用哪种都可以,根据自己喜欢即可,个人比较喜欢keras的API风格。

你可能感兴趣的:(大数据/机器学习/人工智能)