Tensorflow实现AlexNet及原理

    AlexNet包含6亿3000万个连接,6000万个参数和65万个神经元,拥有5个卷积层,其中3个卷积层后面连接了最大池化层,最后还有3个全连接层。

  AlexNet将LeNet的思想发扬光大,主要用到的新技术如下:

(1)成功使用ReLU作为CNN的激活函数,并验证其效果再较深的网络中超过Sigmoid,成功解决了Sigmoid在网络较深时的梯度弥散问题。

(2)训练时使用Dropout随即忽略一部分神经元,以避免模型过拟合。

(3)在CNN只使用重叠的最大池化。

(4)提出LRN层,提出了LRN层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。

(5)提出了  AlexNet层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。

(6)数据增强,随机地从256*256的原始图像中截取224*224大小的区域(以及水平翻转的镜像),相当于增加了2*(256-224)^2=2048倍的数据量。如果没有数据增强,仅靠原始的数据量,参数众多的CNN会陷入过拟合中,使用了数据增强后可以大大减轻过拟合,提升泛化能力。进行预测时,则是取图片的四个角加中间共5个位置,并进行左右翻转,一共获得10张图片,对他们进行预测并对10次结果求均值。同时,AlexNet论文中提到了会对图像的RGB数据进行PCA处理,并对主成分做一个标准差为0.1的高斯扰动,增加一些噪声,这个Trick可以让错误率再下降1%。

整个 AlexNet有8个需要训练参数的层,前5层为卷积层,后3层为全连层,  LRN层出现在第一个及第二个卷积层后,最大池化层出现在两个 LRN层及最后一个卷积层后。ReLU激活函数则应用在这8层每一层的后面。如图所示: AlexNet

AlexNet每层的参数如图:其中输入的图片尺寸为224*224,第一个卷积层使用的卷积核尺寸为11*11,步长为4,有96个卷积核,紧接着一个LRN层,然后一个3*3的最大池化层,步长为2,之后的卷积核尺寸都比较小,都是5*5或者3*3的大小,并且步长都为1。

 

因为使用ImageNet数据训练一个完整的AlexNet耗时长,所以下面不涉及实际数据的训练。建立一个完整的AlexNet卷积神经网络, 然后对他每个batch的前馈计算forward和反馈计算backward的速度进行测试。

先导入接下来会用到的库:

from datetime import datetime
import math
import tensorflow as tf
import time

总共测试100个batch的数据: 

batch_size=32
num_batches=100

定义显示网络每一层结构的函数print_actications, 展示每一个卷积层或池化层输出tensor的尺寸,

def print_activations(t):
    print(t.op.name,' ',t.get_shape().as_list())

接下来设计AlexNet的网络结构:

def inference(images):
    parameters=[]
    
    with tf.name_scope('conv1') as scope:
        kernel=tf.Variable(tf.truncated_normal([11,11,3,64],
                                               dtype=tf.float32,stddev=1e-1),name='weights')
        conv=tf.nn.conv2d(images,kernel,[1,4,4,1],padding='SAME')
        biases=tf.Variable(tf.constant(0.0,shape=[64],dtype=tf.float32),
                                       trainable=True,name='biases')
        bias=tf.nn.bias_add(conv,biases)
        conv1=tf.nn.relu(bias,name=scope)
        print_activations(conv1)
        parameters +=[kernel,biases]
    lrn1=tf.nn.lrn(conv1,4,bias=1.0,alpha=0.001/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_activations(pool1)
       
    with tf.name_scope('conv2') as scope:
        kernel=tf.Variable(tf.truncated_normal([5,5,64,192],
                                               dtype=tf.float32,stddev=1e-1),name='weights')
        conv=tf.nn.conv2d(pool1,kernel,[1,1,1,1],padding='SAME')
        biases=tf.Variable(tf.constant(0.0,shape=[192],dtype=tf.float32),
                                       trainable=True,name='biases')
        bias=tf.nn.bias_add(conv,biases)
        conv2=tf.nn.relu(bias,name=scope)
        parameters +=[kernel,biases]
    print_activations(conv2)
    lrn2=tf.nn.lrn(conv2,4,bias=1.0,alpha=0.001/9,beta=0.75,name='lrn2')
    pool2=tf.nn.max_pool(lrn2,ksize=[1,3,3,1],strides=[1,2,2,1],
                padding='VALID',name='pool2')
    print_activations(pool2)        

    with tf.name_scope('conv3') as scope:
        kernel=tf.Variable(tf.truncated_normal([3,3,192,384],
                                               dtype=tf.float32,stddev=1e-1),name='weights')
        conv=tf.nn.conv2d(pool2,kernel,[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)
        conv3=tf.nn.relu(bias,name=scope)
        parameters +=[kernel,biases]
        print_activations(conv3) 
          
    with tf.name_scope('conv4') as scope:
        kernel = tf.Variable(tf.truncated_normal([3, 3, 384,256],
                                             dtype=tf.float32,
                                             stddev=1e-1), name='weights')
        conv = tf.nn.conv2d(conv3, kernel, [1, 1, 1, 1], padding='SAME')
        biases = tf.Variable(tf.constant(0.0, shape=[256],dtype=tf.float32),
                         trainable=True, name='biases')
        bias = tf.nn.bias_add(conv, biases)
        conv4 = tf.nn.relu(bias, name=scope)
        parameters += [kernel, biases]
        print_activations(conv4)
        
    with tf.name_scope('conv5') as scope:
        kernel=tf.Variable(tf.truncated_normal([3,3,256,256],
                                               dtype=tf.float32,stddev=1e-1),name='weights')
        conv=tf.nn.conv2d(conv4,kernel,[1,1,1,1],padding='SAME')
        biases=tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),
                                       trainable=True,name='biases')
        bias=tf.nn.bias_add(conv,biases)
        conv5=tf.nn.relu(bias,name=scope)
        parameters +=[kernel,biases]
        print_activations(conv5) 
    pool5=tf.nn.max_pool(conv5,ksize=[1,3,3,1],strides=[1,2,2,1],
                         padding='VALID',name='pool5')
    print_activations(pool5)
    return pool5,parameters

def time_tensorflow_run(session,target,info_string):
    num_steps_burn_in=10
    total_duration=0.0
    total_duration_squared=0.0
    for i in range(num_batches+num_steps_burn_in):
        start_time=time.time()
        _=session.run(target)
        duration=time.time() - start_time
        if i>=num_steps_burn_in:
            if not i % 10:
                print('%s:step %d,duration=%.3f'%
                      (datetime.now(),i-num_steps_burn_in,duration))
                total_duration+=duration
                total_duration_squared+=duration*duration
    mn=total_duration/num_batches
    vr=total_duration_squared/num_batches-mn*mn
    sd=math.sqrt(vr)
    print('%s:%s across %d steps,%.3f +/- %.3f sec /batch'%
          (datetime.now(),info_string,num_batches,mn,sd))

接下来是主函数run_benchmark:

def run_benchmark():
    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=1e-1))
        pool5,parameters=inference(images)
        init=tf.global_variables_initializer()
        sess=tf.Session()
        sess.run(init)
        time_tensorflow_run(sess,pool5,"Forward")
        objective=tf.nn.l2_loss(pool5)
        grad=tf.gradients(objective,parameters)
        time_tensorflow_run(sess,grad,"Forward-backward")
        
run_benchmark()
conv1   [32, 56, 56, 64]
pool1   [32, 27, 27, 64]
conv2   [32, 27, 27, 192]
pool2   [32, 13, 13, 192]
conv3   [32, 13, 13, 384]
conv4   [32, 13, 13, 256]
conv5   [32, 13, 13, 256]
pool5   [32, 6, 6, 256]
2018-11-21 20:02:46.049800:step 0,duration=0.270
2018-11-21 20:02:48.779797:step 10,duration=0.260
2018-11-21 20:02:51.489796:step 20,duration=0.270
2018-11-21 20:02:54.199795:step 30,duration=0.280
2018-11-21 20:02:56.904185:step 40,duration=0.270
2018-11-21 20:02:59.624187:step 50,duration=0.270
2018-11-21 20:03:02.344184:step 60,duration=0.270
2018-11-21 20:03:05.064195:step 70,duration=0.270
2018-11-21 20:03:07.784187:step 80,duration=0.270
2018-11-21 20:03:10.584184:step 90,duration=0.290
2018-11-21 20:03:13.264184:Forward across 100 steps,0.027 +/- 0.082 sec /batch
2018-11-21 20:03:26.464180:step 0,duration=1.190
2018-11-21 20:03:38.424179:step 10,duration=1.210
2018-11-21 20:03:50.394177:step 20,duration=1.200
2018-11-21 20:04:02.374176:step 30,duration=1.180
2018-11-21 20:04:14.324174:step 40,duration=1.190
2018-11-21 20:04:26.277548:step 50,duration=1.190
2018-11-21 20:04:38.256889:step 60,duration=1.190
2018-11-21 20:04:50.179339:step 70,duration=1.190
2018-11-21 20:05:02.580086:step 80,duration=1.307
2018-11-21 20:05:14.734489:step 90,duration=1.220
2018-11-21 20:05:25.551670:Forward-backward across 100 steps,0.121 +/- 0.362 sec /batch

 

参考文献:

Tensorflow实战( 黄文坚)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值