不登陆不收费的网站链接,宁波网站制作服务,企业官网seo,百度seo关键词排名查询工具#x1f9e1;#x1f49b;#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 Resnet实战1 Resnet实战2 Resnet实战3
4、训练脚本train.py解读------创建模型
def …TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 Resnet实战1 Resnet实战2 Resnet实战3
4、训练脚本train.py解读------创建模型
def get_model():model resnet50.ResNet50()if config.model resnet34:model resnet34.ResNet34()if config.model resnet101:model resnet101.ResNet101()if config.model resnet152:model resnet152.ResNet152()model.build(input_shape(None, config.image_height, config.image_width, config.channels))model.summary()tf.keras.utils.plot_model(model, to_filemodel.png)return model# create model
model get_model()调用get_model()函数构建模型
get_model()函数
通过resnet50.py调用ResNet50类构建ResNet50模型如果在配置参数中设置的是resnet34、“resnet101”、“resnet152”则会对应使用resnet34.py调用ResNet34类构建ResNet34模型、resnet101.py调用ResNet101类构建ResNet101模型、resnet152.py调用ResNet152类构建ResNet152模型准备模型以供训练或评估,输出模型的概览创建了模型的结构图plot_model 函数从 Keras 工具包中生成模型的可视化表示指定了保存路径
5、模型构建解析------models/resnet50.py
import tensorflow as tf
from models.residual_block import build_res_block_2
from config import NUM_CLASSESclass ResNet50(tf.keras.Model):def __init__(self, num_classesNUM_CLASSES):super(ResNet50, self).__init__()self.pre1 tf.keras.layers.Conv2D(filters64, kernel_size(7, 7), strides2, paddingsame)self.pre2 tf.keras.layers.BatchNormalization()self.pre3 tf.keras.layers.Activation(tf.keras.activations.relu)self.pre4 tf.keras.layers.MaxPool2D(pool_size(3, 3), strides2)self.layer1 build_res_block_2(filter_num64, blocks3)self.layer2 build_res_block_2(filter_num128, blocks4, stride2)self.layer3 build_res_block_2(filter_num256, blocks6, stride2)self.layer4 build_res_block_2(filter_num512, blocks3, stride2)self.avgpool tf.keras.layers.GlobalAveragePooling2D()self.fc1 tf.keras.layers.Dense(units1000, activationtf.keras.activations.relu)self.drop_out tf.keras.layers.Dropout(rate0.5)self.fc2 tf.keras.layers.Dense(unitsnum_classes, activationtf.keras.activations.softmax)def call(self, inputs, trainingNone, maskNone):pre1 self.pre1(inputs)pre2 self.pre2(pre1, trainingtraining)pre3 self.pre3(pre2)pre4 self.pre4(pre3)l1 self.layer1(pre4, trainingtraining)l2 self.layer2(l1, trainingtraining)l3 self.layer3(l2, trainingtraining)l4 self.layer4(l3, trainingtraining)avgpool self.avgpool(l4)fc1 self.fc1(avgpool)drop self.drop_out(fc1)out self.fc2(drop)return outclass ResNet50(tf.keras.Model)这个类定义了ResNet50模型的结构以及前向传播的方式、顺序
ResNet50类解析
构造函数传入了预测的类别数初始化pre1 定义一个二维卷积输出64个特征图7x7的卷积步长为2pre2 定义一个批归一化pre3定义一个ReLU激活函数pre4一个二维的最大池化依次通过build_res_block_2()函数定义4个残差块定义一个全局平均池化定义一个全连接层输出维度为1000定义一个dropout定义一个输出层的全连接层前向传播函数传入输入值依次经过pre1、pre2、pre3、pre4即卷积、批归一化、ReLU、最大池化依次经过layer1 、layer2 、layer3 、layer4 等四个残差块将layer4 的输出经过平局池化依次经过两个全连接层
6、模型构建解析------models/residual_block.py
BottleNeck类build_res_block_2()函数build_res_block_2()函数通过调用BottleNeck类构建残差块
class BottleNeck(tf.keras.layers.Layer):def __init__(self, filter_num, stride1,with_downsampleTrue):super(BottleNeck, self).__init__()self.with_downsample with_downsampleself.conv1 tf.keras.layers.Conv2D(filtersfilter_num, kernel_size(1, 1), strides1, paddingsame)self.bn1 tf.keras.layers.BatchNormalization()self.conv2 tf.keras.layers.Conv2D(filtersfilter_num, kernel_size(3, 3), stridesstride, paddingsame)self.bn2 tf.keras.layers.BatchNormalization()self.conv3 tf.keras.layers.Conv2D(filtersfilter_num * 4, kernel_size(1, 1), strides1, paddingsame)self.bn3 tf.keras.layers.BatchNormalization()self.downsample tf.keras.Sequential()self.downsample.add(tf.keras.layers.Conv2D(filtersfilter_num * 4, kernel_size(1, 1), stridesstride))self.downsample.add(tf.keras.layers.BatchNormalization())def call(self, inputs, trainingNone):identity self.downsample(inputs)conv1 self.conv1(inputs)bn1 self.bn1(conv1, trainingtraining)relu1 tf.nn.relu(bn1)conv2 self.conv2(relu1)bn2 self.bn2(conv2, trainingtraining)relu2 tf.nn.relu(bn2)conv3 self.conv3(relu2)bn3 self.bn3(conv3, trainingtraining)if self.with_downsample True:output tf.nn.relu(tf.keras.layers.add([identity, bn3]))else:output tf.nn.relu(tf.keras.layers.add([inputs, bn3]))return outputBottleNeck类解析
继承tf.keras.layers.Layer构造函数传入 特征图个数、步长、是否下采样等参数初始化是否进行下采样参数定义一个1x1步长为1的二维卷积conv1conv1 对应的批归一化定义一个3x3步长为1的二维卷积conv2conv2 对应的批归一化定义一个3x3步长为1的二维卷积conv2conv3 对应的批归一化定义一个下采样层self.downsample这个层是一个包含卷积层和批量归一化的 Sequential 模型用于匹配输入和残差的维度call()函数为前向传播应用下采样应用三层卷积和批量归一化以及对应的ReLUwith_downsample True启用下采样将下采样后的输入identity与最后一个卷积层的输出bn3相加没有启用下采样将原始输入inputs与最后一个卷积层的输出bn3相加
def build_res_block_2(filter_num, blocks, stride1):res_block tf.keras.Sequential()res_block.add(BottleNeck(filter_num, stridestride))for _ in range(1, blocks):res_block.add(BottleNeck(filter_num, stride1,with_downsampleFalse)) return res_blockbuild_res_block_2函数解析
这个函数构建了一个包含多个BottleNeck层的残差块filter_num 是每个瓶颈层内卷积层的过滤器数量blocks 是要添加到顺序模型中的瓶颈层的数量stride 是卷积的步长默认为 1该函数初始化一个 Sequential 模型并添加一个 BottleNeck 层作为第一层然后它迭代地添加额外的 BottleNeck 层每个层的 stride1 且 with_downsampleFalse除第一个之外此函数返回组装好的顺序模型代表一个残差块
Resnet实战1 Resnet实战2 Resnet实战3