Tensorflow 2.0 keras.models.Sequential() Model() 创建网络的若干方式 及共享权重问题

keras建立网络的方法可以分为keras.models.Sequential() 和keras.models.Model()、继承类三种方式。
注意:tensorflow2.* 以后的版本可以直接使用tf.keras.Sequential()和tf.keras.Model()两个类。不用再使用keras.models的API

目录

    • keras.models.Sequential() ()
    • keras.models.Model()
    • 继承类
    • 共享权重网络

keras.models.Sequential() ()

适用于简单线性堆叠网络。
流程:创建Sequential()对象,逐层堆叠网络

import tensorflow as tf
from tensorflow.keras import layers, models

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

model.summary()

也可以不使用.add方法。直接在Sequntial里放入层列表

import tensorflow as tf
from tensorflow.keras import layers, models

model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

model.summary()

Tensorflow 2.0 keras.models.Sequential() Model() 创建网络的若干方式 及共享权重问题_第1张图片
注意:input_shape=(32, 32, 3),在模型搭建过程中会自动填空Batch维度,即None。而不需要在定义input_shape的时候进行定义。
第一列中的层名是按照层的类型默认1开始的序列后缀命名。

keras.models.Model()

如果我们像实现一些更为复杂的网络,比如多输入多输出的模型就需要使用到keras.models.Model()来构建网络。如下代码同时输出最后卷积层Flatten后提取的特征层,以及分类结构。
流程使用keras.Input定义输入张量shape, 创建网络层;定义每层的输入和输出张量;keras.models.Model确定输入张量和输出层,keras可以根据每一层的输入输出关系完成整个网络图的创建。

import tensorflow as tf
from tensorflow.keras import layers, models, Input

input_tensor = Input(shape=(32, 32, 3))

x = layers.Conv2D(32, (3, 3), activation='relu')(input_tensor)
x = layers.MaxPooling2D((2, 2))(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)
x = layers.MaxPooling2D((2, 2))(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)

output_tensor1=layers.Flatten()(x)
x = layers.Dense(64, activation='relu')(output_tensor1)

output_tensor2 = layers.Dense(10, activation='softmax')(x)

model = models.Model(inputs=input_tensor, outputs=[output_tensor1, output_tensor2])

model.summary()

Tensorflow 2.0 keras.models.Sequential() Model() 创建网络的若干方式 及共享权重问题_第2张图片
第一层卷积核参数:896=((3x3)x3+1)x32
第二层卷积核参数:18496=((3x3)x32+1)x64
第三个卷积核参数:36928=((3x3)x64+1)x64
(卷积核面积x上一层层数+1)x下一层层数
加1表示bias

第一个全连接层参数:1024x(64+1)=65600
第二个全连接层参数:10x(64+1)=650
(上一层层数+1)x下一层层数

继承类

在应对复杂结构的网络的时候,往往会按照采用自定义类(继承keras.models.Model)的方式来建立网络,使得整个网络结构更加规范整洁,同时通过call函数可以方便地处理复杂网络的输入输出关系。(有跟torch搭建思想借鉴的嫌疑)

import  tensorflow as tf
from    tensorflow import keras
from    tensorflow.keras import layers
from    tensorflow.keras.models import Model

class MyNet(Model):

    def __init__(self):
        super(MyNet, self).__init__()
        self.conv1 = layers.Conv2D(32, (3, 3), activation='relu')
        self.pool1 = layers.MaxPooling2D((2, 2))
        
        self.conv2 = layers.Conv2D(64, (3, 3), activation='relu')
        self.pool2 = layers.MaxPooling2D((2, 2))

        self.conv3 = layers.Conv2D(64, (3, 3), activation='relu')
        self.flatten = layers.Flatten()
        
        self.fc1 = layers.Dense(64, activation='relu')
        self.fc2 = layers.Dense(10, activation='softmax')
        
    def call(self, inputs):
        
        out = self.conv1(inputs)
        out = self.pool1(out)
        
        out = self.conv2(out)
        out = self.pool2(out)
        
        out = self.conv3(out)
        out = self.flatten(out)
        
        out = self.fc1(out)
        out = self.fc2(out)
        
        return out

def main():
    
    model = MyNet()
    model.build(input_shape=(None,32, 32,3))
    model.summary()

if __name__ == '__main__':
    main()

Tensorflow 2.0 keras.models.Sequential() Model() 创建网络的若干方式 及共享权重问题_第3张图片
注意:这种方法需要在定义**input_shape=(None,32, 32,3)**时,考虑batch维度。
可以看出不是原生态的方法,导致summary的每层shape参数缺失。

共享权重网络

关键点:对需要共享权重的网络进行实例化
因为调用一次layers就会建立网络图,就会有相应的网络权重参数。
把需要共享权重部分的网络封装到一个子的Sequential() 或Model()中 ,或者单一层进行实例化,建立层的对象。
https://www.jianshu.com/p/4e45c7c4eb43

后续学习到TF1.0的静态图方式,再继续补充

网络训练传送门:
Tensorflow 2.* 网络训练(一) compile(optimizer, loss, metrics, loss_weights)
Tensorflow 2.* 网络训练(二) fit(x, y, batch_size, epochs, verbose, validation_split, initial_epoch… )
Tensorflow 2.* 网络训练(三) keras.callbacks 回调函数

你可能感兴趣的:(Tensorflow,Python,卷积神经网络)