TensorFlow2.0——Sequential模型与函数式API构建神经网络结构

一、数据集与模型的介绍

  数据集的来源是Fashion MNIST数据集,Fashion MNIST是衣物图数据,该数据集包含 10 个类别的 70,000 个灰度图像。我们用这个数据构建一个神经网络模型,并训练它,模型的结构为input=784,layer1=128,output=10。

  数据集的图像以低分辨率(28x28 像素)展示了单件衣物,如下所示:

 

 

二、Sequential序列化模型

1、网络结构的构建

  tensorflow中构建网络结构的方法之一就是利用Sequential序列化模型,Sequential可以认为是一个序列容器,里面封装了神经网络的结构。下面来看一下实例代码:

# 用keras.Sequential构建神经网络的结构,方法一,用列表直接构建
model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),  # 输入图片的像素是28*28,将其转化为1维作为输入
    tf.keras.layers.Dense(128, activation='relu'),  # 隐藏层128个神经元
    tf.keras.layers.Dense(10)   # 输出为10个类别,这里不用激活函数,是为了后续计算损失时用softmax与
])

# 用keras.Sequential构建神经网络的结构,方法二,用add()方法加入神经网络层
model=tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10))

  上面就是用tf.keras.Sequential封装,用tf.keras.layers构建网络层,下面介绍一下这两个函数:

 

 

  1)、tf.keras.Sequential(layers=None,name=None)
  • layers:一个tf.keras.layers的list或者tuple。

  用来创建一个Sequential的模型。可以用add()方法加入层结构,summary()方法查看模型结构。

 

  2)、tf.keras.layers.Flatten(input_shape)
  • input_shape:输入的形状。

  用来将多维数据转化为一位数据,相当于numpy的np.reval()函数。

 

  3)、tf.keras.layers.Dense(units,activation)
  • units:隐藏层神经元的个数
  • activation:激活函数

  用来构建隐藏层、输出层的内部结构,还有其他详细参数可以查看官方说明。

 

2、查看模型结构

  当我们创建好模型之后,最好能查看模型的网络结构是怎么样子的,这时候就有一个方法tf.keras.Sequential().summary()就可以查看我们模型的结构。

  现在用代码构建一个模型并查看他的结构:

# 用keras.Sequential构建神经网络的结构,方法二,用add()方法加入神经网络层
model=tf.keras.Sequential(layers=None,name=None)
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(10))

# 输出网络结果情况
model.summary()

输出结果:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0         
_________________________________________________________________
dense (Dense)                (None, 128)               100480    
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________

 

3、编译模型

  模型的结构构建好之后,我们还需要构建模型的训练内容,如:优化器、损失函数、评估准则,这时候可以用complie()方法来编译

# 用sequential类的compile方法编译模型:优化器为adam,
model.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), # from_logits=True表示损失是经过softmax函数的
    metrics=['accuracy']    # 评价方法为准确度
)

 

4、传入训练数据训练模型

  模型编译好之后就可以对模型进行训练,模型训练的使用的是fit()方法。fit()方法可以对模型训练时的epoch、batch、validation_data进行调整。

# 训练模型,通过fit方法传入数据进行训练,训练10代,每代批次大小为200,每批次取训练集0.1的数据做验证集
model.fit(x=train_images, y=train_labels, epochs=10,batch_size=200,validation_split=0.1)

 

 

三、Sequential构建模型总结

  下面对Sequential构建神经网络机构进行一个步骤总结:

  1. model=tf.keras.Sequential()封装一个神经网络结构,model.summary()用来查看模型结构。
  2. .compile()方法编译模型。
  3. .fit()方法对模型进行训练。

 

  

 四、函数式API

1、什么是函数式API

  函数式API构建模型是一种比较推荐的方法,相较于Sequential方法来说更加灵活,Sequential方法只有一个输入一个输出,且隐藏层的输入必须是要顺序的,当我们有多输出多输出,或者引入残差网络的时候,这个方法就不好实现了,为此tensorflow提供了函数式API。

  为什么称之为函数式API呢?首先python里面有一个功能叫类的调用,就是定义一个类的时候,我们定义这个类内的函数__call__(),当我们声明这个类的时候,就可以像函数一样调用这个类。如下:

class can_call:
    def __init__(self,name='can_call'):
        self.name=name

    def __call__(self):
        print('my name is %s'%self.name)

myclass=can_call()
myclass()

# 输出结果为 : my name is can_call

  我们在Sequential中顶一个各个层,如tf.keras.layers.Dense()是一个类,同样可以实现类的调用,相当于函数的调用,这就是所谓的函数式API。

 

2、函数式API的实现

  函数式API需要定义一个输入类tf.keras.Input(),主要其参数如下:

  tf.keras.Input( shape=None, batch_size=None, name=None, dtype=None, sparse=False, tensor=None, **kwargs )

  • shape:形状元组(整数),不包括批量大小.例如,shape=(32,),表示预期的输入将是32维向量的批次
  • batch_size:可选的静态批量大小(整数)
  • name:图层的可选名称字符串.在模型中应该是唯一的(不要重复使用相同的名称两次).如果未提供,它将自动生成
  • dtype:数据类型由输入预期的,作为字符串(float32,float64,int32...)
  • sparse:一个布尔值,指定是否创建占位符是稀疏的
  • tensor:可选的现有张量包裹到Input图层中.如果设置,图层将不会创建占位符张量
  • **kwargs:不支持的参数

  函数式API的流程:

  1. 定义输入net_input=tf.keras.Input()类,设定输入的shape。
  2. 用函数式API构建网络结构,如l1=tf.keras.layers.Flatten()(net_input),最后得到输出层net_output
  3. 创建Model类,并传入输出与输出,如tf.keras.Model(inputs=net_input,outputs=net_output)
import tensorflow as tf
import os
import numpy as np

# 读取数据集
(train_images,train_labels),(test_images,test_labels)=tf.keras.datasets.fashion_mnist.load_data()

# 定义一个模型的输入,shape输入为元祖,不包含批次数,向量的输入形状为(n,),矩阵的输入为(n,m)
net_input=tf.keras.Input(shape=(28,28),)

# 所谓的函数式API就是我们把每一层layer类都当层一个函数,可以调用,如下面的代码就调用了tf.keras.layers.Flatten()
# 建立模型结构,这里只是建立结构,不创建模型类,在L2层实现一个droupout
x=tf.keras.layers.Flatten()(net_input)  # 将图片数据由二维平整化为一维
l1=tf.keras.layers.Dense(64,activation='relu',name='layer1')(x)
l2_dropout=tf.keras.layers.Dropout(0.5)(l1)
l2=tf.keras.layers.Dense(32,activation='relu',name='layer2')(l2_dropout)
net_output=tf.keras.layers.Dense(10,activation='softmax',name='net_output')(l2)

# 创建模型类
model=tf.keras.Model(inputs=net_input,outputs=net_output)

# 查看模型的结构
model.summary()

 

posted @ 2020-11-18 18:18  我不是高斯分布  阅读(2199)  评论(0编辑  收藏  举报