tf系列4——模型构建4种方法
这篇文章有一定借鉴意义
https://panjinquan.blog.csdn.net/article/details/86712328
一共就这4种,足够,别瞎想
模型构建4种方法
- 1 使用现有的预训练模型
- 2 Keras Sequential模式建立模型(不推荐用,跳接结构不行)
- 2.1 Sequential内置
- 2.2 Sequential外置
- 3 Functional API 函数api建立模型(最常用,复杂网络)
- 4 tf构建模型Class
- 4.1 初识
- 4.2 Keras 当中的layer(层)接口
- 4.3 Models
- 4.4 一个小案例
- 5 函数式和class方式实现unet
- 5.1 函数式模型实现unet
- 5.2 class方式实现unet
- 6 补充,深度学习的各种层大全
- 7 模型可视化
1 使用现有的预训练模型
keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',input_tensor=None, input_shape=None,pooling=None,classes=1000)
model = tf.keras.applications.MobileNetV2(weights=None, classes=5)
https://mattzheng.blog.csdn.net/article/details/72859145
这个案例很好https://xercis.blog.csdn.net/article/details/88660053?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&dist_request_id=1330144.35460.16182210027491941&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
2 Keras Sequential模式建立模型(不推荐用,跳接结构不行)
2.1 Sequential内置


参考:https://www.bilibili.com/video/BV1B7411L7Qt?p=33

2.2 Sequential外置
def mnist_cnn(input_shape):'''构建一个CNN网络模型:param input_shape: 指定输入维度:return:'''model=keras.Sequential()model.add(keras.layers.Conv2D(filters=32,kernel_size = 5,strides = (1,1),padding = 'same',activation = tf.nn.relu,input_shape = input_shape))model.add(keras.layers.MaxPool2D(pool_size=(2,2), strides = (2,2), padding = 'valid'))model.add(keras.layers.Conv2D(filters=64,kernel_size = 3,strides = (1,1),padding = 'same',activation = tf.nn.relu))model.add(keras.layers.MaxPool2D(pool_size=(2,2), strides = (2,2), padding = 'valid'))model.add(keras.layers.Dropout(0.25))model.add(keras.layers.Flatten())model.add(keras.layers.Dense(units=128,activation = tf.nn.relu))model.add(keras.layers.Dropout(0.5))model.add(keras.layers.Dense(units=10,activation = tf.nn.softmax))return model
3 Functional API 函数api建立模型(最常用,复杂网络)
多输入模型,
多输出模型,
具有共享层的模型(同一层被调用多次),
具有非序列数据流的模型(例如,剩余连接)
这种方式就是各个层都是一个函数,通过函数的叠加就可以实现,一般使用这种方法,将模型封装成一个模型函数。
inputs = tf.keras.Input(shape=(28, 28, 1))
x = tf.keras.layers.Flatten()(inputs)
x = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)(x)
x = tf.keras.layers.Dense(units=10)(x)
outputs = tf.keras.layers.Softmax()(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
看下面这个FCN构建,结合了迁移学习和函数api建立模型
https://blog.csdn.net/xiaotiig/article/details/110355547
下面这个resnet网络结构的实现,也是用的这种方法实现的,因为有很多的残差结构
https://blog.csdn.net/xiaotiig/article/details/117673634
4 tf构建模型Class
4.1 初识

实例化层然后调用方法,两步
init里实例化各种方法
call调用各种方法

继承 tf.keras.Model 后,我们同时可以使用父类的若干方法和属性,例如在实例化类 model = Model() 后,可以通过 model.variables 这一属性直接获得模型中的所有变量,免去我们一个个显式指定变量的麻烦。
对于上面的 y_pred = w * X + b ,我们可以通过模型类的方式编写如下:这里,我们没有显式地声明a 和 b 两个变量并写出 y_pred = w x X + b 这一线性变换,而是建立了一个继承了 tf.keras.Model 的模型类 Linear 。这个类在初始化部分实例化了一个 全连接层 ( tf.keras.layers.Dense ),并在 call 方法中对这个层进行调用,实现了线性变换的计算。
import tensorflow as tfX = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
y = tf.constant([[10.0], [20.0]])# 1、构建线性模型
class Linear(tf.keras.Model):def __init__(self):super().__init__()self.dense = tf.keras.layers.Dense(units=1,activation=None,kernel_initializer=tf.zeros_initializer(),bias_initializer=tf.zeros_initializer())def call(self, input):output = self.dense(input)return output# 以下代码结构与前节类似
model = Linear()
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for i in range(100):with tf.GradientTape() as tape:y_pred = model(X)loss = 0.5 * tf.reduce_mean(tf.square(y_pred - y))# 使用 model.variables 这一属性直接获得模型中的所有变量grads = tape.gradient(loss, model.variables)optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
print(model.variables)
4.2 Keras 当中的layer(层)接口

4.3 Models

4.4 一个小案例







5 函数式和class方式实现unet
5.1 函数式模型实现unet
# 使用函数式编程实现UNet
import tensorflow as tfdef Unet_model(input_shape=(256,256,3), num_classes=2):inputs = tf.keras.layers.Input(input_shape)x1 = tf.keras.layers.Conv2D(64, kernel_size=3, activation="relu", padding="same")(inputs)x1 = tf.keras.layers.Conv2D(64, kernel_size=3, activation="relu", padding="same")(x1)x2 = tf.keras.layers.MaxPooling2D()(x1)x2 = tf.keras.layers.Conv2D(128, kernel_size=3, activation="relu", padding="same")(x2)x2 = tf.keras.layers.Conv2D(128, kernel_size=3, activation="relu", padding="same")(x2)x3 = tf.keras.layers.MaxPooling2D()(x2)x3 = tf.keras.layers.Conv2D(256, kernel_size=3, activation="relu", padding="same")(x3)x3 = tf.keras.layers.Conv2D(256, kernel_size=3, activation="relu", padding="same")(x3)x4 = tf.keras.layers.MaxPooling2D()(x3)x4 = tf.keras.layers.Conv2D(512, kernel_size=3, activation="relu", padding="same")(x4)x4 = tf.keras.layers.Conv2D(512, kernel_size=3, activation="relu", padding="same")(x4)# 最下面一层x5 = tf.keras.layers.MaxPooling2D()(x4)x5 = tf.keras.layers.Conv2D(1024, kernel_size=3, activation="relu", padding="same")(x5)x5 = tf.keras.layers.Conv2D(1024, kernel_size=3, activation="relu", padding="same")(x5)# 开始上采样x6 = tf.keras.layers.Conv2DTranspose(512, kernel_size=3, strides=2, padding="same")(x5)x6 = tf.concat([x4,x6],axis=-1)x6 = tf.keras.layers.Conv2D(512, kernel_size=3, activation="relu", padding="same")(x6)x6 = tf.keras.layers.Conv2D(512, kernel_size=3, activation="relu", padding="same")(x6)x7 = tf.keras.layers.Conv2DTranspose(256, kernel_size=3, strides=2, padding="same")(x6)x7 = tf.concat([x3, x7], axis=-1)x7 = tf.keras.layers.Conv2D(256, kernel_size=3, activation="relu", padding="same")(x7)x7 = tf.keras.layers.Conv2D(256, kernel_size=3, activation="relu", padding="same")(x7)x8 = tf.keras.layers.Conv2DTranspose(128, kernel_size=3, strides=2, padding="same")(x7)x8 = tf.concat([x2, x8], axis=-1)x8 = tf.keras.layers.Conv2D(128, kernel_size=3, activation="relu", padding="same")(x8)x8 = tf.keras.layers.Conv2D(128, kernel_size=3, activation="relu", padding="same")(x8)x9 = tf.keras.layers.Conv2DTranspose(64, kernel_size=3, strides=2, padding="same")(x8)x9 = tf.concat([x1, x9], axis=-1)x9 = tf.keras.layers.Conv2D(64, kernel_size=3, activation="relu", padding="same")(x9)x9 = tf.keras.layers.Conv2D(64, kernel_size=3, activation="relu", padding="same")(x9)out = tf.keras.layers.Conv2D(num_classes, kernel_size=1, padding="same")(x9)out = tf.keras.layers.Activation('softmax')(out)model = tf.keras.models.Model(inputs,out,name='unet')return model
加载
from nets.unet import Unet_model
model = Unet_model(input_shape=(img_target_size[0], img_target_size[1], 3),num_classes=N_CLASS)
model.summary()
opt = Adam(base_lr)
model_save_dir = os.path.join( './model_unet/unet_320.h5')
checkpoint = ModelCheckpoint(model_save_dir, verbose=True, save_best_only=True, monitor='val_mean_iou', mode='max')
scheduleLR = LearningRateScheduler(lr_schedular, verbose=True)
model.compile(opt, 'categorical_crossentropy', metrics=['accuracy', mean_iou])
model.fit(tr_gen, epochs=40, validation_data=val_gen, callbacks=[checkpoint, scheduleLR])
5.2 class方式实现unet
# 实现了unet模型
import tensorflow as tf
import numpy as np######################################### 2 前向传播
class Downsample(tf.keras.layers.Layer):"先定义,再调用,进行下采样"def __init__(self, units):"units是卷积核的数量"super(Downsample,self).__init__()# 使用了same填充,原论文使用valid填充self.conv1 = tf.keras.layers.Conv2D(units, kernel_size=3,padding="same")self.conv2 = tf.keras.layers.Conv2D(units, kernel_size=3, padding="same")# tf.keras.layers.MaxPooling2D()和tf.keras.layers.MaxPool2D()区别是什么?self.pool = tf.keras.layers.MaxPooling2D()def call(self, x, is_pool = True):if is_pool:x = self.pool(x)x = self.conv1(x)x = tf.nn.relu(x)x = self.conv2(x)x = tf.nn.relu(x)return xclass Upsample(tf.keras.layers.Layer):"先定义,再调用,进行上采样"def __init__(self, units):"units是卷积核的数量"super(Upsample, self).__init__()self.conv1 = tf.keras.layers.Conv2D(units, kernel_size=3, padding="same")self.conv2 = tf.keras.layers.Conv2D(units, kernel_size=3, padding="same")self.deconv = tf.keras.layers.Conv2DTranspose(units//2,kernel_size=3,strides=2,padding="same")def call(self, x):x = self.conv1(x)x = tf.nn.relu(x)x = self.conv2(x)x = tf.nn.relu(x)x = self.deconv(x)x = tf.nn.relu(x)return xclass Unet_model(tf.keras.Model):def __init__(self):"只进行初始化,定义层,还没有进行前向传播"super(Unet_model, self).__init__()# 这步只是进行卷积self.down1 = Downsample(64)# 4次下采样self.down2 = Downsample(128)self.down3 = Downsample(256)self.down4 = Downsample(512)self.down5 = Downsample(1024)# 4次上采样,定义一个上采样层# 第一个上采样只进行上采样,不进行卷积self.up1 = tf.keras.layers.Conv2DTranspose(512, kernel_size=3, strides=2, padding="same")# 上采样加卷积self.up2 = Upsample(512)self.up3 = Upsample(256)self.up4 = Upsample(128)# 进行两次卷积self.conv_last = Downsample(64)# 进行最后的1*1卷积分类,进行城市街景共34个类别的分类,所以输出层为34,,# 如果进行别的任务,是几类就写几,因为需要喝MeanIou一样,否则会报错self.last = tf.keras.layers.Conv2D(21, kernel_size=1, padding="same")def call(self, x):"进行前向传播模型的构建"# 第一次先进行两次卷积x1 = self.down1(x, is_pool = False)# 进行4次下采样加两次卷积x2 = self.down2(x1)x3 = self.down3(x2)x4 = self.down4(x3)x5 = self.down5(x4)# 进行一次上采样x5 = self.up1(x5)# 进行合并,然后卷积卷积上采样x6 = tf.concat([x4, x5], axis=-1)x6 = self.up2(x6)x7 = tf.concat([x3, x6], axis=-1)x7 = self.up3(x7)x8 = tf.concat([x2, x7], axis=-1)x8 = self.up4(x8)# 合并,然后两层卷积x9 = tf.concat([x1, x8], axis=-1)x9 = self.conv_last(x9, is_pool = False)# 输出为34层,共34个类别out = self.last(x9)return out
加载
from nets.unet import Unet_model
model = Unet_model()
opt = Adam(base_lr)
model_save_dir = os.path.join( './model_unet/unet_320.h5')
checkpoint = ModelCheckpoint(model_save_dir, verbose=True, save_best_only=True, monitor='val_mean_iou', mode='max')
scheduleLR = LearningRateScheduler(lr_schedular, verbose=True)
model.compile(opt, 'categorical_crossentropy', metrics=['accuracy', mean_iou])
model.fit(tr_gen, epochs=40, validation_data=val_gen, callbacks=[checkpoint, scheduleLR])
model.summary()
6 补充,深度学习的各种层大全
【1】tensorflow2.0——神经网络的层(层全连接层、卷积层、池化层、BN层、激活层、dropout层及其他层) - 我不是高斯分布 - 博客园
https://www.cnblogs.com/dwithy/p/14028108.html
7 模型可视化
# from keras.utils import plot_model
# import os
# os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'
#
# model = danet_resnet101(height=512, width=512, channel=3, classes=1)
# model.summary()
# plot_model(model, to_file='danet_resnet101.png', show_shapes=True)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
