tensorflow实现AlexNet

AlexNet是Hinton的学生Alex Krizhevsky在2012年提出的深度卷积神经网络,它是LeNet一种更深更宽的版本。在AlexNet上首次应用了几个trick,ReLU、Dropout和LRN。AlexNet包含了6亿3000万个连接,6000万个参数和65万个神经元,有5个卷积层,3个全连接层。在ILSVRC 2012比赛中,AlexNet以top-5的错误率为16.4%的显著优势夺得冠军,第二名的成绩是26.2%。AlexNet的trick主要包括:

1、成功使用RELU作为CNN的激活函数,并验证其效果在较深的网络中的效果超过了sigmoid,解决了sigmoid在深层的网络中的梯度弥散的问题。

2、使用Dropout来随机使得一部分神经元失活,来避免模型的过拟合,在AlexNet中,dropout主要应用在全连接层。

3、使用重叠的最大池化,以前在卷积神经网络中大部分都采用平均池化,在AlexNet中都是使用最大池化,最大池化可以避免平均池化的模糊化效果。重叠的最大池化是指卷积核的尺寸要大于步长,这样池化层的输出之间会有重叠和覆盖,提升特征的丰富性。在AlexNet中使用的卷积核大小为3×3,横向和纵向的步长都为2。

4、使用LRN层,对局部神经元的活动创建有竞争机制,让响应较大的值变得相对更大,并抑制反馈较小的神经元,来增强模型的泛化能力。

5、使用了CUDA来加速深度神经网络的训练。

6、数据增强,随机从256×256的原始图像中截取224×224的图像以及随机翻转。如果没有数据增强,在参数众多的情况下,卷积神经网络会陷入到过拟合中,使用数据增强可以减缓过拟合,提升泛化能力。进行预测的时候,提取图片的四个角加中间位置,并进行左右翻转,一共10张图片,对它们进行预测并取10次结果的平均值。在AlexNet论文中也提到了,对图像的RGB数据进行PCA处理,并做一个标准差为0.1的高斯扰动,增加一些噪声,可以降低1%的错误率。

论文原文

tensorflow实现AlexNet_第1张图片

1、第一层卷积层

第一层卷积一共有64个11×11×3大小的卷积核,横向和纵向的步长都为4,初始化权重使用截断的正态分布进行初始化,经过ReLU激活函数之后,再通过LRN层,再使用重叠的最大池化。

    #第一层卷积层
    with tf.name_scope("conv1") as scope:
        #设置卷积核11×11,3通道,64个卷积核
        kernel1 = tf.Variable(tf.truncated_normal([11,11,3,64],mean=0,stddev=0.1,
                                                  dtype=tf.float32),name="weights")
        #卷积,卷积的横向步长和竖向步长都为4
        conv = tf.nn.conv2d(images,kernel1,[1,4,4,1],padding="SAME")
        #初始化偏置
        biases = tf.Variable(tf.constant(0,shape=[64],dtype=tf.float32),trainable=True,name="biases")
        bias = tf.nn.bias_add(conv,biases)
        #RELU激活函数
        conv1 = tf.nn.relu(bias,name=scope)
        #输出该层的信息
        print_tensor_info(conv1)
        #统计参数
        parameters += [kernel1,biases]
        #lrn处理
        lrn1 = tf.nn.lrn(conv1,4,bias=1,alpha=1e-3/9,beta=0.75,name="lrn1")
        #最大池化
        pool1 = tf.nn.max_pool(lrn1,ksize=[1,3,3,1],strides=[1,2,2,1],padding="VALID",name="pool1")
        #输出该层信息
        print_tensor_info(pool1)

2、第二层卷积层

第二层卷积层的结构和第一层大致相似,卷积层的大小由11×11变成了5×5,有192个卷积核。

    #第二层卷积层
    with tf.name_scope("conv2") as scope:
        #初始化权重
        kernel2 = tf.Variable(tf.truncated_normal([5,5,64,192],dtype=tf.float32,stddev=0.1)
                              ,name="weights")
        conv = tf.nn.conv2d(pool1,kernel2,[1,1,1,1],padding="SAME")
        #初始化偏置
        biases = tf.Variable(tf.constant(0,dtype=tf.float32,shape=[192])
                             ,trainable=True,name="biases")
        bias = tf.nn.bias_add(conv,biases)
        #RELU激活
        conv2 = tf.nn.relu(bias,name=scope)
        print_tensor_info(conv2)
        parameters += [kernel2,biases]
        #LRN
        lrn2 = tf.nn.lrn(conv2,4,1.0,alpha=1e-3/9,beta=0.75,name="lrn2")
        #最大池化
        pool2 = tf.nn.max_pool(lrn2,[1,3,3,1],[1,2,2,1],padding="VALID",name="pool2")
        print_tensor_info(pool2)

3、第三层卷积层

第三层卷积层卷积核的个数是第二层的一倍,第三层卷积层没有使用LRN层和最大池化。

    #第三层卷积层
    with tf.name_scope("conv3") as scope:
        #初始化权重
        kernel3 = tf.Variable(tf.truncated_normal([3,3,192,384],dtype=tf.float32,stddev=0.1)
                              ,name="weights")
        conv = tf.nn.conv2d(pool2,kernel3,strides=[1,1,1,1],padding="SAME")
        biases = tf.Variable(tf.constant(0.0,shape=[384],dtype=tf.float32),trainable=True,name="biases")
        bias = tf.nn.bias_add(conv,biases)
        #RELU激活层
        conv3 = tf.nn.relu(bias,name=scope)
        parameters += [kernel3,biases]
        print_tensor_info(conv3)

4、第四层卷积层

    #第四层卷积层
    with tf.name_scope("conv4") as scope:
        #初始化权重
        kernel4 = tf.Variable(tf.truncated_normal([3,3,384,256],stddev=0.1,dtype=tf.float32),
                              name="weights")
        #卷积
        conv = tf.nn.conv2d(conv3,kernel4,strides=[1,1,1,1],padding="SAME")
        biases = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[256]),trainable=True,name="biases")
        bias = tf.nn.bias_add(conv,biases)
        #RELU激活
        conv4 = tf.nn.relu(bias,name=scope)
        parameters += [kernel4,biases]
        print_tensor_info(conv4)

5、第五层卷积层

    #第五层卷积层
    with tf.name_scope("conv5") as scope:
        #初始化权重
        kernel5 = tf.Variable(tf.truncated_normal([3,3,256,256],stddev=0.1,dtype=tf.float32),
                              name="weights")
        conv = tf.nn.conv2d(conv4,kernel5,strides=[1,1,1,1],padding="SAME")
        biases = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[256]),name="biases")
        bias = tf.nn.bias_add(conv,biases)
        #REUL激活层
        conv5 = tf.nn.relu(bias)
        parameters += [kernel5,bias]
        #最大池化
        pool5 = tf.nn.max_pool(conv5,[1,3,3,1],[1,2,2,1],padding="VALID",name="pool5")
        print_tensor_info(pool5)

6、最后三层全连接层和softmax层

    #第六层全连接层
    pool5 = tf.reshape(pool5,(-1,6*6*256))
    weight6 = tf.Variable(tf.truncated_normal([6*6*256,4096],stddev=0.1,dtype=tf.float32),
                           name="weight6")
    ful_bias1 = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[4096]),name="ful_bias1")
    ful_con1 = tf.nn.relu(tf.add(tf.matmul(pool5,weight6),ful_bias1))

    #第七层第二层全连接层
    weight7 = tf.Variable(tf.truncated_normal([4096,4096],stddev=0.1,dtype=tf.float32),
                          name="weight7")
    ful_bias2 = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[4096]),name="ful_bias2")
    ful_con2 = tf.nn.relu(tf.add(tf.matmul(ful_con1,weight7),ful_bias2))
    #
    #第八层第三层全连接层
    weight8 = tf.Variable(tf.truncated_normal([4096,1000],stddev=0.1,dtype=tf.float32),
                          name="weight8")
    ful_bias3 = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[1000]),name="ful_bias3")
    ful_con3 = tf.nn.relu(tf.add(tf.matmul(ful_con2,weight8),ful_bias3))

    #softmax层
    weight9 = tf.Variable(tf.truncated_normal([1000,10],stddev=0.1),dtype=tf.float32,name="weight9")
    bias9 = tf.Variable(tf.constant(0.0,shape=[10]),dtype=tf.float32,name="bias9")
    output_softmax = tf.nn.softmax(tf.matmul(ful_con3,weight9)+bias9)

7、评估模型性能

通过使用模拟出来的图片来评估模型在训练过程中的耗时。

#主函数
def run_bechmark():
    with tf.Graph().as_default():
        image_size = 224
        #以高斯分布产生一些图片
        images = tf.Variable(tf.random_normal([batch_size,image_size,image_size,3],
                                              dtype=tf.float32,stddev=0.1))
        output,parameters = inference(images)
        init = tf.global_variables_initializer()
        sess = tf.Session()
        sess.run(init)
        time_tensorflow_run(sess,output,"Forward")
        objective = tf.nn.l2_loss(output)
        grad = tf.gradients(objective,parameters)
        time_tensorflow_run(sess,grad,"Forward-backward") 
打印出来的每层相关信息

tensorflow实现AlexNet_第2张图片

完整代码链接

你可能感兴趣的:(tensorflow实战,tensorflow实战)