当前位置: 代码迷 >> 综合 >> 09-ResNet-TensorFlow 20 classification of flower identification
  详细解决方案

09-ResNet-TensorFlow 20 classification of flower identification

热度:47   发布时间:2023-12-02 09:34:14.0

一、前言
本篇应该是爬虫获取20分类数据集使用不同网络模型分类的最后一篇,本篇主要讲ResNet的网络架构及实现,具体如何更改相应的文件位置请参考上一篇 ,经过不断的测试与训练博主发现一个不小的问题,就是网络训练了很久都不能拟合实际效果,一开始是以为每个epoch迭代速度慢的原因,后来经过排查发现,实际是因为参数初始化的值与零相近的结果。在链式法则中,这样的参数初始化的值易陷入梯度弥散的情况。相关修改已写入码云中。码云链接 。数据集和网络的梳理见链接07-vgg16-TensorFlow 20 classification of flower identification。
二、介绍
ResNet的层数从GoogLeNet的22层增加到了152层,其主要的创新之处在于使用了残差网络,该创新点主要是为了解决当网络层次加深时网络无法训练的问题。
ResNet在网络中加入了恒等映射层y=x层,其主要作用是使得网络随深度的变化而不会产生权重衰减和梯度衰减或者消失。相当于在网络的中间开辟了多个通道使得输入与输出的层数间隔的均值减小,残差结构的优化的具体实现方式即在原来的拟合输出H(x)编程输出和输入的差值H(x)-x,其中H(x)是某一层原始的期望映射输出,x是输入。
二层残差学习单元,其包括两个3*3大小的卷积层并使用relu的激活方式激活,三层残差学习单元,其将二层残差学习单元中的一个3*3大小的卷积和分解为两个1*1大小的卷积层,放在3*3的卷积层前后,执行先降维再升维的操作。本篇将使用三层残差学习单元来构建此网络模型。
三、具体实现过程
1.定义全局变量

c=0

2.定义卷积层,里面使用到全局变量

def conv(net,kernel_size,out_channels,strides=[1,1,1,1]):in_channels=net.get_shape()[-1]global  cwith tf.variable_scope('c%d'%c):net=tf.nn.conv2d(net,filter=get_variable('w',[kernel_size[0],kernel_size[1],in_channels,out_channels]),strides=strides,padding='SAME')net=tf.nn.bias_add(net,bias=get_variable('b',[out_channels]))net=tf.nn.relu(net)c+=1return net

3.定义残差升维神经元

#定义残差升维神经元
def Res_Unit_increase(net):out_channels=int(net.get_shape()[-1])/2#1*1降维out_net=conv(net,kernel_size=[1,1],out_channels=out_channels)#3*3卷积out_net=conv(out_net,kernel_size=[3,3],out_channels=out_channels)#1*1升维out_net=conv(out_net,kernel_size=[1,1],out_channels=out_channels*4)#net升维net=conv(net,kernel_size=[1,1],out_channels=out_channels*4)return net+out_net

4.定义残差同维神经元

def Res_Unit_same(net):out_channels=int(net.get_shape()[-1])/4#1*1降维out_net=conv(net,kernel_size=[1,1],out_channels=out_channels)#3*3卷积out_net=conv(out_net,kernel_size=[3,3],out_channels=out_channels)#1*1升维out_net=conv(out_net,kernel_size=[1,1],out_channels=out_channels*4)return out_net+net

5.定义5次同残差

def Res_five_same(net):out_net=Res_Unit_same(net)out_net=Res_Unit_same(out_net)out_net=Res_Unit_same(out_net)out_net=Res_Unit_same(out_net)out_net=Res_Unit_same(out_net)return out_net

6.定义残差网络结构

def Res_Net(x,y):conv1_out = 64with tf.variable_scope('input'):network = tf.reshape(x, shape=[-1, 224, 224, 3], name='input')with tf.variable_scope('conv1-64'):network = tf.nn.conv2d(network, filter=get_variable('w', [7, 7, 3, conv1_out]), strides=[1, 1, 1, 1],padding='SAME')network = tf.nn.bias_add(network, bias=get_variable('b', [conv1_out]))network = tf.nn.relu(network)with tf.variable_scope('max_pool_1'):network=tf.nn.max_pool(network,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')with tf.variable_scope('conv2-64'):out_channels=network.get_shape()[-1]network=conv(network,kernel_size=[1,1],out_channels=out_channels)with tf.variable_scope('max_pool_2'):network=tf.nn.max_pool(network,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#每个resnet相当于3层网络#56*56*64with tf.variable_scope('resnet1'):network=Res_Unit_same(network)#56*56*64 5层with tf.variable_scope('max_pool_3'):network=tf.nn.max_pool(network,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#28*28*64with tf.variable_scope('resnet2-6'):network=Res_five_same(network)#28*28*64 20层with tf.variable_scope('resnet7'):network=Res_Unit_increase(network)#28*28*128 21层with tf.variable_scope('max_pool_4'):network=tf.nn.max_pool(network,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#14*14*128with tf.variable_scope('resnet8-12'):network=Res_five_same(network)#14*14*128 36层with tf.variable_scope('resnet13-17'):network=Res_five_same(network)#14*14*128 51层with tf.variable_scope('resnet18'):network=Res_Unit_increase(network)#14*14*256 52层with tf.variable_scope('max_pool_5'):network = tf.nn.max_pool(network, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')#7*7*256with tf.variable_scope('resnet19-23'):network=Res_five_same(network)#7*7*256 67层with tf.variable_scope('resnet24-28'):network=Res_five_same(network)#7*7*256 82层with tf.variable_scope('resnet29-33'):network=Res_five_same(network)#7*7*256 97层with tf.variable_scope('resnet34'):network=Res_Unit_increase(network)#7*7*512 100层with tf.variable_scope('avg_pool_1'):network=tf.nn.avg_pool(network,ksize=[1,7,7,1],strides=[1,7,7,1],padding='VALID')#1*1*512with tf.variable_scope('fc_1'):image_shape = network.get_shape()print(image_shape)network = tf.reshape(network, shape=(-1, image_shape[3]))network = tf.add(tf.matmul(network, get_variable('w', [image_shape[3],20]), ),get_variable('b', [20]))return tf.nn.softmax(network)

四、分析与总结
1.本结构使用100层的ResNet的网络结构,具体调通代码的过程和上一篇 一模一样,这么就不赘述了,附上本次开始运行时的贴图。
这里写图片描述
2.代码中有部分做出了修正,比如说为了保证数据集的泛化能力和鲁棒性,在训练的时候使用了随机的index索引信息,具体方式见码云。
3.欢迎大家的交流与指正,下一篇预计会写关于RNN或者LSTM的分类网络模型代码,是不是很期待呢?

  相关解决方案