AlexNet的Tensorflow实现


AlexNet主要针对224行224列深度为3的三维张量变换。AlexNet相比于之前的LeNet网络有了很多改动,如:

  1. 数据增强:水平翻转、随机裁剪、平移变换、颜色和光照变换
  2. Dropout: Dropout方法和数据增强都是防止过拟合,它的作用原理是让 k p k*p (p为概率)个神经元权重置0,同时让剩下的 ( 1 p ) k (1-p)k 个神经元变为原来的 1 / p 1/p 倍,降低运算量的同时降低过拟合程度
  3. ReLU激活函数:用ReLU代替了传统的Tanh或者Logistic。不容易发生梯度发散问题的同时,ReLU关闭了右边,从而会使得很多的隐层输出为0,即网络变得稀疏,起到了类似L1的正则化作用,可以在一定程度上缓解过拟合。
  4. LRN:局部响应归一化,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。
  5. 多GPU并行

AlexNet对三维张量的变换过程:
输入 \rightarrow 与96个高为22、宽为11、深度为3的卷积的核卷积,其中步长为4。然后加偏置。最后使用激活函数。 \rightarrow
3 3 3*3 的池化,步长为2。 \rightarrow 与256个高为5、宽为5、深度为96的卷积核卷积,其中步长为1。然后加偏置,最后使用激活函数。$\rightarrow 3 3 3*3 的池化,步长为2。 \rightarrow 与384个高为3、宽为3、深度为256的卷积的核卷积,其中步长为1。然后加偏置。最后使用激活函数。 \rightarrow 与384个高为3、宽为3、深度为384的卷积的核卷积,其中步长为1。然后加偏置。最后使用激活函数。 \rightarrow 与256个高为3、宽为3、深度为384的卷积的核卷积,其中步长为1。然后加偏置。最后使用激活函数。$\rightarrow 3 3 3*3 的池化,步长为2。 \rightarrow 拉伸 \rightarrow 全连接

Alex网络结构图:
在这里插入图片描述

准备网络

卷积层

def conv(x,filter_height,filter_width,num_filters,stride_y,stride_x,name,padding="SAME",groups=1):
    #获取输入tensor的channel
    input_channels = int(x.get_shape()[-1])

    #创建一个lambda函数
    convolve = lambda i,k:tf.nn.conv2d(i,k,strides=[1,stride_y,stride_x,1],padding=padding)
    with tf.variable_scope(name) as scope:
        #定义权重
        weights = tf.get_variable("weights",shape=[filter_height,filter_width,
                                                   input_channels/groups,num_filters])
        #定义偏置
        biases = tf.get_variable("biases",shape=[num_filters])

    if groups == 1:
        conv = convolve(x,weights)
    else:
        input_groups = tf.split(axis=3,num_or_size_splits=groups,value=x)
        weight_groups = tf.split(axis=3,num_or_size_splits=groups,value=weights)
        output_groups = [convolve(i,k) for i,k in zip(input_groups,weight_groups)]
        #连接卷积层
        conv = tf.concat(axis=3,values=output_groups)
    bias = tf.reshape(tf.nn.bias_add(conv,biases),tf.shape(conv))
    #relu激活函数
    relu = tf.nn.relu(bias,name=scope.name)

    return relu

全连接层

def fc(x,num_in,num_out,name,relu=True):
    with tf.variable_scope(name) as scope:
        #定义权重和偏置
        weights = tf.get_variable("weights",shape=[num_in,num_out],trainable=True)
        biases = tf.get_variable("biases",[num_out],trainable=True)
        fc_out = tf.nn.xw_plus_b(x,weights,biases,name=scope.name)
    if relu:
        fc_out = tf.nn.relu(fc_out)
    return fc_out

池化层

def max_pool(x,filter_height,filter_width,stride_y,stride_x,name,padding="SAME"):
    return tf.nn.max_pool(x,ksize=[1,filter_height,filter_width,1],strides=[1,stride_y,stride_x,1],
                          padding=padding,name=name)

LRNceng

def lrn(x,radius,alpha,beta,name,bias=1.0):
    return tf.nn.local_response_normalization(x,depth_radius=radius,alpha=alpha,beta=beta,bias=bias,name=name)

dropout层

def dropout(x,keep_prob):
    return tf.nn.dropout(x,keep_prob)

构建AlexNet网络

class AlexNet(object):
    '''
    初始化AlexNet网络
    参数:
    x:输入的tensor
    keep_prob:dropout节点保留概率
    num_classes:需要分类的数量
    skip_layer:需要重新训练的层
    weights_path:预训练参数文件的路径
    '''
    def __init__(self,x,keep_prob,num_classes,skip_layer,weights_path="default"):
        self.X = x
        self.KEEP_PROB = keep_prob
        self.NUM_CLASSES = num_classes
        self.SKIP_LAYER = skip_layer

        if weights_path == "default":
            self.WEIGHTS_PATH = "model/bvlc_alexnet.npy"
        else:
            self.WEIGHTS_PATH = weights_path
        self.create()

    '''
    创建AlexNet网络的计算图
    '''
    def create(self):
        #第一层卷积
        conv1 = conv(self.X,11,11,96,4,4,padding="VALID",name="conv1")
        norm1 = lrn(conv1,2,2e-05,0.75,name="norm1")
        pool1 = max_pool(norm1,3,3,2,2,padding="VALID",name="pool1")

        #第二层卷积
        conv2 = conv(pool1,5,5,256,1,1,groups=2,name="conv2")
        norm2 = lrn(conv2,2,2e-05,0.75,name="norm2")
        pool2 = max_pool(norm2,3,3,2,2,padding="VALID",name="pool2")

        #第三层卷积
        conv3 = conv(pool2,3,3,384,1,1,name="conv3")

        #第四层卷积
        conv4 = conv(conv3,3,3,384,1,1,groups=2,name="conv4")

        #第五层卷积
        conv5 = conv(conv4,3,3,256,1,1,groups=2,name="conv5")
        pool5 = max_pool(conv5,3,3,2,2,padding="VALID",name="pool5")

        #第六层,全连接层
        flattened = tf.reshape(pool5,[-1,6*6*256])
        fc6 = fc(flattened,6*6*256,4096,name="fc6")
        dropout6 = dropout(fc6,self.KEEP_PROB)

        #第七层,全连接层
        fc7 = fc(dropout6,4096,4096,name="fc7")
        dropout7 = dropout(fc7,self.KEEP_PROB)

        #第八层,全连接层
        self.fc8 = fc(dropout7,4096,self.NUM_CLASSES,relu=False,name="fc8")

上述的网络结构可以用下图来表示
在这里插入图片描述

发布了9 篇原创文章 · 获赞 23 · 访问量 2117

猜你喜欢

转载自blog.csdn.net/qq_42635142/article/details/100592776
今日推荐