tensorflow实战 Alexnet 笔记

本文深入探讨了AlexNet的优化技巧,包括ReLU激活函数、LRN层、重叠最大池化、数据增强、Dropout及GPU计算。通过具体代码实现,展示了AlexNet在MNIST数据集上的应用,涉及卷积层、池化层、全连接层和softmax层的构建,以及训练过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Alexnet简介

Alexnet的优化手段:

1.使用ReLU作为激活函数,并验证其效果在较深的网络要优于Sigmoid.
2.使用LRN层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变的相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。(LRN层的原理是对前一层的每一个输出进行一定的运算再输入给下一层,这个运算就是让每一个输出除以两侧相邻的不同过滤器相同位置的几个输出的和。)
在这里插入图片描述
3.使用重叠的最大池化,论文中提出让步长比池化核的尺寸小。
4.数据增强,对原始图像随机的截取输入图片尺寸大小(以及对图像作水平翻转操作)。
5.使用Dropout随机忽略一部分神经元,避免模型过拟合。
6.使用GPU计算,加快计算速度。

Alexnet的框架:

在这里插入图片描述

Alexnet的运算流程:

在这里插入图片描述
在这里插入图片描述

代码难点记录

1.lrn函数,在卷积层和池化层之间使用lrn层,用来强化和抑制参数。(这个函数很少使用,基本上被dropout这样的方法取代。)具体原理在该博客中
lrn和feature map

tf.nn.lrn(_x, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75)

2.max_pool函数的进一步理解,当步长是1时,padding模式为SAME,输出和输入的高和宽不会变。(另一种模式valid的含义是不能再边界处进行填充)。

tf.nn.max_pool(_x, [1, f, f, 1], [1, 1, 1, 1], padding='SAME')

3.在with tf.Session() as sess:下运行op和tensor都是用run()函数。第一个参数为要进行的op运算或者要计算其值的tensor,第二个参数是传入进行该计算需要使用的参数。

    with tf.Session() as sess:
        initop = tf.global_variables_initializer()
        sess.run(initop)

        for step in range(STEPS):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

            if step % 50 == 0:
                acc = sess.run(accuracy, feed_dict={x: batch_xs, y_: batch_ys})
                loss = sess.run(cross_entropy, feed_dict={x: batch_xs, y_: batch_ys})
                print('step:%5d. --acc:%.6f. -- loss:%.6f.' % (step, acc, loss))

4.从pool5将输出传入fc层时,需要对输出进行维度处理,将[batch,h,w,c]大小的输入reshape成[batch,hwc]大小。

# FC1层
    shape = pool5.get_shape()  # 获取第五卷基层输出结构,并展开
    reshape = tf.reshape(pool5, [-1, shape[1].value * shape[2].value * shape[3].value])
    fc1 = tf.nn.relu(tf.matmul(reshape, _parameters['fc1']) + _parameters['bc1'])

将Alexnet应用到Minst数据集上

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

STEPS = 1500
batch_size = 64

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

parameters = {
    'w1': tf.Variable(tf.truncated_normal([3, 3, 1, 64], dtype=tf.float32, stddev=1e-1), name='w1'),
    'w2': tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32, stddev=1e-1), name='w2'),
    'w3': tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32, stddev=1e-1), name='w3'),
    'w4': tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32, stddev=1e-1), name='w4'),
    'w5': tf.Variable(tf.truncated_normal([3, 3, 128, 256], dtype=tf.float32, stddev=1e-1), name='w5'),
    'fc1': tf.Variable(tf.truncated_normal([256 * 28 * 28, 1024], dtype=tf.float32, stddev=1e-2), name='fc1'),
    'fc2': tf.Variable(tf.truncated_normal([1024, 1024], dtype=tf.float32, stddev=1e-2), name='fc2'),
    'softmax': tf.Variable(tf.truncated_normal([1024, 10], dtype=tf.float32, stddev=1e-2), name='fc3'),
    'bw1': tf.Variable(tf.random_normal([64])),
    'bw2': tf.Variable(tf.random_normal([64])),
    'bw3': tf.Variable(tf.random_normal([128])),
    'bw4': tf.Variable(tf.random_normal([128])),
    'bw5': tf.Variable(tf.random_normal([256])),
    'bc1': tf.Variable(tf.random_normal([1024])),
    'bc2': tf.Variable(tf.random_normal([1024])),
    'bs': tf.Variable(tf.random_normal([10]))
}


def conv2d(_x, _w, _b):
    '''
         封装的生成卷积层的函数
         因为NNIST的图片较小,这里采用1,1的步长
    :param _x:  输入
    :param _w:  卷积核
    :param _b:  bias
    :return:    卷积操作
    '''
    return tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(_x, _w, [1, 1, 1, 1], padding='SAME'), _b))


def lrn(_x):
    '''
    作局部响应归一化处理
    :param _x:
    :return:
    '''
    return tf.nn.lrn(_x, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75)


def max_pool(_x, f):
    '''
        最大池化处理,因为输入图片尺寸较小,这里取步长固定为1,1,1,1
    :param _x:
    :param f:
    :return:
    '''
    return tf.nn.max_pool(_x, [1, f, f, 1], [1, 1, 1, 1], padding='SAME')


def inference(_parameters, _dropout):
    '''
     定义网络结构和训练过程
    :param _parameters:  网络结构参数
    :param _dropout:     dropout层的keep_prob
    :return:
    '''

    # 搭建Alex模型
    x = tf.placeholder(tf.float32, [None, 784])  # 输入: MNIST数据图像为展开的向量
    x_ = tf.reshape(x, shape=[-1, 28, 28, 1])  # 将训练数据reshape成单通道图片
    y_ = tf.placeholder(tf.float32, [None, 10])  # 标签值:one-hot标签值

    # 第一卷积层
    conv1 = conv2d(x_, _parameters['w1'], _parameters['bw1'])
    lrn1 = lrn(conv1)
    pool1 = max_pool(lrn1, 2)

    # 第二卷积层
    conv2 = conv2d(pool1, _parameters['w2'], _parameters['bw2'])
    lrn2 = lrn(conv2)
    pool2 = max_pool(lrn2, 2)

    # 第三卷积层
    conv3 = conv2d(pool2, _parameters['w3'], _parameters['bw3'])

    # 第四卷积层
    conv4 = conv2d(conv3, _parameters['w4'], _parameters['bw4'])

    # 第五卷积层
    conv5 = conv2d(conv4, _parameters['w5'], _parameters['bw5'])
    pool5 = max_pool(conv5, 2)

    # FC1层
    shape = pool5.get_shape()  # 获取第五卷基层输出结构,并展开
    reshape = tf.reshape(pool5, [-1, shape[1].value * shape[2].value * shape[3].value])
    fc1 = tf.nn.relu(tf.matmul(reshape, _parameters['fc1']) + _parameters['bc1'])
    fc1_drop = tf.nn.dropout(fc1, keep_prob=_dropout)

    # FC2层
    fc2 = tf.nn.relu(tf.matmul(fc1_drop, _parameters['fc2']) + _parameters['bc2'])
    fc2_drop = tf.nn.dropout(fc2, keep_prob=_dropout)

    # softmax层
    y_conv = tf.nn.softmax(tf.matmul(fc2_drop, _parameters['softmax']) + _parameters['bs'])

    # 定义损失函数和优化器
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indices=[1]))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    # 计算准确率
    correct_pred = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

    with tf.Session() as sess:
        initop = tf.global_variables_initializer()
        sess.run(initop)

        for step in range(STEPS):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

            if step % 50 == 0:
                acc = sess.run(accuracy, feed_dict={x: batch_xs, y_: batch_ys})
                loss = sess.run(cross_entropy, feed_dict={x: batch_xs, y_: batch_ys})
                print('step:%5d. --acc:%.6f. -- loss:%.6f.' % (step, acc, loss))

        print('train over!')

        # Test
        test_xs, test_ys = mnist.test.images[:512], mnist.test.labels[:512]

        print('test acc:%f' % (sess.run(accuracy, feed_dict={x: test_xs, y_: test_ys})))


if __name__ == '__main__':
    inference(parameters, 0.9)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值