AlexNet网络实现

AlexNet网络结构
该网络包括五个卷积层和三个全连接层,输入图像经过卷积操作和全连接层的操作,最后输入具有1000个节点的softmax分类器完成图像分类。
该网络通过使用线性整流函数ReLU作为激活函数,引入局部响应归一化缓解梯度消失问题;使用数据增强和Dropout技术大大缓解了过拟合问题。

实验过程
论文中是使用了ImageNet数据集进行训练和测试的,由于设备计算能力有限,我自己选择的了用mnist数据集进行试验,相应的稍微更改了一下网络结构。
训练集:mnist数据集是一组28*28的灰度图像,训练数据集包含 60,000 个样本, 测试数据集包含 10,000 样本。

#coding:utf-8
import tensorflow as tf
#import tensorflow.compat.v1 as tfc
#import tensorflow_datasets
#mnist = tensorflow_datasets.load('mnist')
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
sess = tf.InteractiveSession() #在运行之前先定义一些操作,Session必须在所有操作全部定义完才能是运行


#初始化权值和偏重
def weight_variabe(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)#产生截断的正态分布张量,shape表示产生的张量维度,mean为均值,stddev为标准差
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape = shape)
    return tf.Variable(initial)

#卷积和池化层实现   卷积核3 步长1   池化3,步长2
def conv2d(x,W):
    return tf.nn.conv2d(x,W, strides = [1,1,1,1], padding = 'SAME')

def max_pool_3x3(x):
    return tf.nn.max_pool(x,ksize = [1,3,3,1],strides = [1,2,2,1], padding = 'SAME')

#LRN  局部响应归一化层
def norm(x,lsize = 4):
    #return tf.nn.lrn(x,lsize,bias = 1.0,aplha = 0.001/9.0 ,beta = 0.75)
    return tf.nn.lrn(x,lsize,bias = 1.0, beta = 0.75)

#构建卷积层
                                             #placeholder 在tf暂时储存变量
x = tf.placeholder(tf.float32, [None,784])   #这里我们给它分配一个 [None, 784] 的形状,
                                             # 其中 784 是单个展平的 28 x 28 像素 MNIST 图像的维度,
                                             # None 表示对应于批量大小的第一个维度可以是任何大小。
y_ = tf.placeholder(tf.float32,[None,10])    #10种分类结果
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(x,[-1,28,28,1])         #这里是将一组图像矩阵x重建为新的矩阵,其中-1表示a由实际情况来定
                                             #第二三维是指图像的大小
                                              #灰度图对应1,rgb图对应3.

W_conv1 = weight_variabe([3,3,1,64])    #  前两位3 3表示网格大小,第三位1表示输入通道数目
                                    #第四位64表示输出通道数目(也可以理解为使用的卷积核个数、得到的特征图张数)
b_conv1 = bias_variable([64])  #每个输出通道都有一个偏置项,因此偏置项个数为364
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1) + b_conv1)  #使用Relu进行第一次卷积
h_pool1 = max_pool_3x3(h_conv1)                          #使用3x3的网格最大池化(第一次)
h_norm1 = norm(h_pool1, lsize=4)

W_conv2 = weight_variabe([3,3,64,128])
b_conv2 = bias_variable([128])
h_conv2 = tf.nn.relu(conv2d(h_norm1,W_conv2) + b_conv2) #第二次卷积
h_pool2 = max_pool_3x3(h_conv2)                         #第二次池化
h_norm2 = norm(h_pool2, lsize=4)

W_conv3 = weight_variabe([3,3,128,256])
b_conv3 = bias_variable([256])
h_conv3 = tf.nn.relu(conv2d(h_pool2,W_conv3) + b_conv3)   #第三次卷积
h_pool3 = max_pool_3x3(h_conv3)                           #第三次池化
h_norm3 = norm(h_pool3, lsize=4)

#实现全连接和Dropout
W_fc1 = weight_variabe([4*4*256,1024])   #加入一个有1024个神经元的全连接层
b_fc1 = bias_variable([1024])
h_norm3_flat = tf.reshape(h_norm3,[-1,4*4*256])  #将池化后的结果reshape成一个一维向量
h_fc1 = tf.nn.relu(tf.matmul(h_norm3_flat,W_fc1) + b_fc1)    #在与其权重相乘,加上偏置项,再通过一个ReLU激活函数
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)  #防止过拟合的方法dropout:
# 完全随机选取经过神经网络流一半的数据来训练,在每次训练过程中用0来替代被丢掉的激活值,其它激活值合理缩放。

W_fc2 = weight_variabe([1024,1024])
b_fc2 = bias_variable([1024])
h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop,W_fc2) + b_fc2)
h_fc2_drop = tf.nn.dropout(h_fc2 , keep_prob)

#实现Readout层
W_fc3 = weight_variabe([1024,10])
b_fc3 = bias_variable([10])
y_conv = tf.matmul(h_fc2_drop,W_fc3) +b_fc3

#参数训练与模型评估
cross_entropy = tf.reduce_mean(   #计算交叉熵的代价函数
    tf.nn.softmax_cross_entropy_with_logits(labels = y_,logits=y_conv)
)
#使用优化算法使得代价函数最小化
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#找出预测正确的标签
correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
#得出通过正确个数除以总数得出准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

sess.run(tf.global_variables_initializer())
for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i%100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
            x:batch[0] , y_:batch[1] , keep_prob:1.0
        })
        print('step %d,training accuracy %g'%(i                                                                                                                                                                                                                                                                                                                                                      ,train_accuracy))
    train_step.run(feed_dict = {x:batch[0], y_:batch[1] , keep_prob : 0.5})

print('test accuracy %g'% accuracy.eval(feed_dict = {
    x:mnist.test.images, y_:mnist.test.labels , keep_prob:1.0
}))
sess.close()

在这里插入图片描述
训练集
测试集
LeNet和AlexNet的对比:
本周复现了两个模型,在大结构上,其实两个模型十分相似,但是有一些细节上的差距,对后面的网络结构影响有深刻的意义。
在AlexNet之前,CNN普遍使用平均池化,AlexNet全部使用最大池化,避免平均池化的模糊化效果。并且AlexNet中提出让步长比池化核的尺寸小,这样池化层的输出之间会有重叠和覆盖,提升了特征的丰富性。
AlexNet 优势在于:网络增大(5个卷积层+3个全连接层+1个softmax层),同时解决过拟合(使用了dropout,LRN等技术),并且利用多GPU加速计算(在自己试验是没法实现,所以忽略了这条).。

遇到的问题及解决方法:
①运行代码过程出现的问题,由于TensorFlow版本问题,网上公开的代码在2.0版本的TensorFlow中已经不适用,需要进行语法修改或者版本切换。
②在真正跑代码的过程中发现,虽然已经明白了模型训练的流程,但是面对实际的代码还是无从下手,甚至不知道代码的含义。所以我在跑代码的过程中,不只是单纯的copy网上的代码跑出结果,也会深究每行代码的作用,关键函数的参数含义,并且在注释上一一标注出来。
在这里插入图片描述
参考文章:
https://blog.csdn.net/qq_31278903/article/details/90671908

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值