【TensorFlow2.0】如何搭建网络模型?

栏目: 数据库 · 发布时间: 6年前

内容简介:大家好,这是专栏我们知道在不考虑输入层的情况下,一个典型的卷积神经网络通常由若干个卷积层、激活层、池化层及全连接层组成,无论是最经典的LeNet5,还是前两天刚出现的MobileNet V3,无一不都包含这些层。今天就带大家学习下如何使用TensorFlow2.0搭建卷积神经网络模型。作者&编辑 | 汤兴旺

大家好,这是专栏 《TensorFlow2.0》 的第四篇文章,讲述网络模型的搭建。

我们知道在不考虑输入层的情况下,一个典型的卷积神经网络通常由若干个卷积层、激活层、池化层及全连接层组成,无论是最经典的LeNet5,还是前两天刚出现的MobileNet V3,无一不都包含这些层。今天就带大家学习下如何使用TensorFlow2.0搭建卷积神经网络模型。

作者&编辑 | 汤兴旺 

上一期,我们讲解了如何使用TensorFlow2.0从自己的磁盘读取数据,今天我们就来看看如何使用层来搭建网络。

1 使用Keras API构建网络模型架构

在Keras API中,定义网络是比较简单的,我们主要用到的就是 Sequential类 下面看看如何具体使用它来定义网络:

from tensorflow.keras import Sequential

conv_net = Sequential([

layers.Dense(32,activation = "relu",input_shape = (784,)),

layers.Dense(10,activation = "softmax")])

我们可以把Sequential理解为一个容器,然后把layers搭建的每层模型都送进这个容器中,构成整个网络模型。值得注意的layers搭建的每层模型要想放进这个容器中必须是list结构。

另外我们需要搭建的卷积层,全连接层,池化层等都在layers这个类中。下面我们看一个包含卷积层,全连接层,池化层比较完整的结构,如下:

from tensorflow.keras import Sequential

conv_layers = [

#units1

layers.Conv2D(64, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(64, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.MaxPool2D(pool_size=[2,2],strides=2,padding="same"),

#units2

layers.Conv2D(128, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(128, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.MaxPool2D(pool_size=[2,2],strides=2,padding="same"),

#units3

layers.Conv2D(256, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(256, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(256, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.MaxPool2D(pool_size=[2,2],strides=2,padding="same"),

#units4

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.MaxPool2D(pool_size=[2,2],strides=2,padding="same"),

#units5

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.Conv2D(512, kernel_size=[3,3],padding="same",activation = tf.nn.relu),

layers.MaxPool2D(pool_size=[2,2],strides=2,padding="same")]

conv_net =Sequential(conv_layers)

fc_net = Sequential([

layers.Dense(4096,activation=tf.nn.relu),

layers.Dense(4096, activation=tf.nn.relu),

layers.Dense(1000, activation=None),

])

上面的模型中我们首先通过layers.Conv2D()、layers.MaxPool2D()构建模型的卷积网络层conv_layers,注意看我是把这个层放在了一个list中的,然后我把这个list即conv_layers放进了Sequential这个容器构建成了卷积网络conv_net。

卷积层完成构建后,我们通过layers.Dense添加全连接层,这样一个完整的结构就完成了。

基本的模型完成了搭建后,我们看前向处理是怎么做的,即数据如何从卷积层一步步传到最后的全连接层,最后输出一个预测值。

out = conv_net(x)

out = tf.reshape(out, [-1, 512])

logits = fc_net(out)

上面我们假设输入x是[1,32,32,3],即1张3通道大小为32*32的图片,经过卷积层后的输出为out,现在我们看看out是多少,查看方法如下:

x = tf.random.normal([1,32,32,3])

out = conv_net(x)

print(out.shape)

我们通过上面的代码很容易得到out.shape = [1,1,1,512]

为了能将卷积后的结果与全连接层相连,我们需要将它展平,即out = tf.reshape(out, [-1, 512]),最后我们将打平后的结果传递到全连接层网络fc_net得到预测值。

上面我们通过Sequential类完成了一个完整的模型搭建,你掌握了吗?

2 定义自己的网络层架构

上面我们通过Sequential类完成了一个简单的线性模型的搭建,下面我们看如何搭建自己的一个模型(非线性模型)。这里我们以ResNet系列网络为例。

import tensorflow as tf

from tensorflow import keras

from tensorflow.keras import layers,Sequential

class BasicBlock(layers.Layer):

def __init__(self,filter_num,stride=1):

super(BasicBlock,self).__init__()

self.conv1=layers.Conv2D(

filter_num,(3,3),strides=stride,padding="same")

self.bn1 = layers.BatchNormalization()

self.relu = layers.Activation("relu")

self.conv2 = layers.Conv2D(filter_num, (3, 3), strides=1, padding="same")

self.bn2 = layers.BatchNormalization()

if stride !=1:

self.downsample = Sequential()

self.downsample.add(layers.Conv2D(filter_num,(1,1),strides=stride))

else:

self.downsample =lambda x:x

def call(self,inputs,training=None):

out = self.conv1(inputs)

out = self.bn1(out)

out =self.relu(out)

out = self.conv2(out)

out = self.bn2(out)

identity = self.downsample(inputs)

output = layers.add([out,identity])

output = tf.nn.relu(output)

return output

class ResNet(keras.Model):

def __init__(self,layer_dims,num_classe=100):

super(ResNet,self).__init__()

#预处理层

self.stem = Sequential([layers.Conv2D(64,(3,3),strides=(1,1)),

layers.BatchNormalization(),

layers.Activation("relu"),

layers.MaxPool2D(pool_size=(2,2),strides=(1,1),padding="same")])

self.layer1 = self.build_resblock(64,layer_dims[0])

self.layer2 = self.build_resblock(128, layer_dims[1],stride=2)

self.layer3 = self.build_resblock(256, layer_dims[2], stride=2)

self.layer4 = self.build_resblock(512, layer_dims[3], stride=2)

self.avgpool = layers.GlobalAveragePooling2D()

self.fc = layers.Dense(num_classe)

def call(self, inputs, training=None):

x = self.stem(inputs)

x = self.layer1(x)

x = self.layer2(x)

x = self.layer3(x)

x = self.layer4(x)

x = self.avgpool(x)

x = self.fc(x)

return x

def build_resblock(self,filter_num,blocks,stride=1):

#filter_num是卷积核的数量,blocks是basic_block的数量

res_blocks=Sequential()

res_blocks.add(BasicBlock(filter_num,stride))

for _ in range(1,blocks):

res_blocks.add(BasicBlock(filter_num,stride=1))

return res_blocks

def resnet18():

return ResNet([2,2,2,2])

def resnet34():

return ResNet([3,4,6,3])

我们知道在ResNet中有一个基本的单元叫做basicBlock

【TensorFlow2.0】如何搭建网络模型?

多个basicBlock的叠加就组成了resblock,而ResNet系列网络就是由多个不同resBlock组成的。

上面的代码中我们定义了一个基本的类basicBlock,它必须继承layers.Layer或者keras.Model这个类,也就是说所有的网络自定义都会继承这个类中的一个, 并实现super方法 ,如下:

super(BasicBlock,self).__init__()

basicBlock基本结构完成后,我们需要实现前向运算,即call函数,如下:

def call(self,inputs,training=None):

out = self.conv1(inputs)

out = self.bn1(out)

out =self.relu(out)

out = self.conv2(out)

out = self.bn2(out)

identity = self.downsample(inputs)

output = layers.add([out,identity])

output = tf.nn.relu(output)

return output

从上面的代码可以看出call函数是比较简单的,串接各个网络层就可以了,这里不再详细说明。这样我们resnet的基本结构basicBlock就完成了构建。后面的resBlock实际上就是BasicBlock的叠加,实现的方法是一样的,就是定义个基本的类,并继承layers.Layer或者keras.Model这个类,再实现super方法。最后通过call函数完成前向运算。

总结

本期我们详细介绍了如何使用TensorFlow2.0完成网络模型的搭建。

下期预告:使用TensorFlow2.0完成从模型自定义到测试。

直播预告

【TensorFlow2.0】如何搭建网络模型?

【TensorFlow2.0】如何搭建网络模型?

今日看图猜技术

【TensorFlow2.0】如何搭建网络模型?

网络结构

【TensorFlow2.0】如何搭建网络模型?

有三AI生态

【TensorFlow2.0】如何搭建网络模型?

转载文章请后台联系

侵权必究

更多请关注知乎专栏《有三AI学院》

【TensorFlow2.0】如何搭建网络模型?

【TensorFlow2.0】如何搭建网络模型?


以上所述就是小编给大家介绍的《【TensorFlow2.0】如何搭建网络模型?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code Reading

Code Reading

Diomidis Spinellis / Addison-Wesley Professional / 2003-06-06 / USD 64.99

This book is a unique and essential reference that focuses upon the reading and comprehension of existing software code. While code reading is an important task faced by the vast majority of students,......一起来看看 《Code Reading》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具