飞道的博客

经典卷积神经网络-AlexNet

423人阅读  评论(0)

AlexNet

学习目标

  • 知道AlexNet网络结构
  • 能够利用AlexNet完成图像分类

 

2012年,AlexNet横空出世,该模型的名字源于论文第一作者的姓名Alex Krizhevsky 。AlexNet使用了8层卷积神经网络,以很大的优势赢得了ImageNet 2012图像识别挑战赛。它首次证明了学习到的特征可以超越手工设计的特征,从而一举打破计算机视觉研究的方向。

1.AlexNet的网络架构

AlexNet与LeNet的设计理念非常相似,但也有显著的区别,其网络架构如下图所示:

 

该网络的特点是:

  • AlexNet包含8层变换,有5层卷积和2层全连接隐藏层,以及1个全连接输出层

  • AlexNet第一层中的卷积核形状是11×1111×11。第二层中的卷积核形状减小到5×55×5,之后全采用3×33×3。所有的池化层窗口大小为3×33×3、步幅为2的最大池化。

  • AlexNet将sigmoid激活函数改成了ReLU激活函数,使计算更简单,网络更容易训练

  • AlexNet通过dropOut来控制全连接层的模型复杂度。

  • AlexNet引入了大量的图像增强,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。

在tf.keras中实现AlexNet模型:


  
  1. # 构建AlexNet模型
  2. net = tf.keras.models.Sequential([
  3. # 卷积层:96个卷积核,卷积核为11*11,步幅为4,激活函数relu
  4. tf.keras.layers.Conv2D(filters= 96,kernel_size= 11,strides= 4,activation= 'relu'),
  5. # 池化:窗口大小为3*3、步幅为2
  6. tf.keras.layers.MaxPool2D(pool_size= 3, strides= 2),
  7. # 卷积层:256个卷积核,卷积核为5*5,步幅为1,padding为same,激活函数relu
  8. tf.keras.layers.Conv2D(filters= 256,kernel_size= 5,padding= 'same',activation= 'relu'),
  9. # 池化:窗口大小为3*3、步幅为2
  10. tf.keras.layers.MaxPool2D(pool_size= 3, strides= 2),
  11. # 卷积层:384个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
  12. tf.keras.layers.Conv2D(filters= 384,kernel_size= 3,padding= 'same',activation= 'relu'),
  13. # 卷积层:384个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
  14. tf.keras.layers.Conv2D(filters= 384,kernel_size= 3,padding= 'same',activation= 'relu'),
  15. # 卷积层:256个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
  16. tf.keras.layers.Conv2D(filters= 256,kernel_size= 3,padding= 'same',activation= 'relu'),
  17. # 池化:窗口大小为3*3、步幅为2
  18. tf.keras.layers.MaxPool2D(pool_size= 3, strides= 2),
  19. # 伸展为1维向量
  20. tf.keras.layers.Flatten(),
  21. # 全连接层:4096个神经元,激活函数relu
  22. tf.keras.layers.Dense( 4096,activation= 'relu'),
  23. # 随机失活
  24. tf.keras.layers.Dropout( 0.5),
  25. # 全链接层:4096个神经元,激活函数relu
  26. tf.keras.layers.Dense( 4096,activation= 'relu'),
  27. # 随机失活
  28. tf.keras.layers.Dropout( 0.5),
  29. # 输出层:10个神经元,激活函数softmax
  30. tf.keras.layers.Dense( 10,activation= 'softmax')
  31. ])

我们构造一个高和宽均为227的单通道数据样本来看一下模型的架构:


  
  1. # 构造输入X,并将其送入到net网络中
  2. X = tf.random.uniform(( 1, 227, 227, 1)
  3. y = net(X)
  4. # 通过net.summay()查看网络的形状
  5. net.summay()

网络架构如下:


  
  1. Model: "sequential"
  2. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  3. Layer (type) Output Shape Param #
  4. =================================================================
  5. conv2d (Conv2D) (1, 55, 55, 96) 11712
  6. _________________________________________________________________
  7. max _pooling2d (MaxPooling2D) (1, 27, 27, 96) 0
  8. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _____
  9. conv2d _1 (Conv2D) (1, 27, 27, 256) 614656
  10. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _____
  11. max _pooling2d_1 (MaxPooling2 (1, 13, 13, 256) 0
  12. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  13. conv2d_2 (Conv2D) (1, 13, 13, 384) 885120
  14. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  15. conv2d_3 (Conv2D) (1, 13, 13, 384) 1327488
  16. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  17. conv2d_4 (Conv2D) (1, 13, 13, 256) 884992
  18. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  19. max_pooling2d _2 (MaxPooling2 (1, 6, 6, 256) 0
  20. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _____
  21. flatten (Flatten) (1, 9216) 0
  22. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  23. dense (Dense) (1, 4096) 37752832
  24. _________________________________________________________________
  25. dropout (Dropout) (1, 4096) 0
  26. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  27. dense_1 (Dense) (1, 4096) 16781312
  28. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  29. dropout_1 (Dropout) (1, 4096) 0
  30. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
  31. dense_2 (Dense) (1, 10) 40970
  32. =================================================================
  33. Total params: 58,299,082
  34. Trainable params: 58,299,082
  35. Non-trainable params: 0
  36. ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _

2.手写数字势识别

AlexNet使用ImageNet数据集进行训练,但因为ImageNet数据集较大训练时间较长,我们仍用前面的MNIST数据集来演示AlexNet。读取数据的时将图像高和宽扩大到AlexNet使用的图像高和宽227。这个通过tf.image.resize_with_pad来实现。

2.1 数据读取

首先获取数据,并进行维度调整:


  
  1. import numpy as np
  2. # 获取手写数字数据集
  3. (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
  4. # 训练集数据维度的调整:N H W C
  5. train_images = np.reshape(train_images,(train_images.shape[ 0],train_images.shape[ 1],train_images.shape[ 2], 1))
  6. # 测试集数据维度的调整:N H W C
  7. test_images = np.reshape(test_images,(test_images.shape[ 0],test_images.shape[ 1],test_images.shape[ 2], 1))

由于使用全部数据训练时间较长,我们定义两个方法获取部分数据,并将图像调整为227*227大小,进行模型训练:


  
  1. # 定义两个方法随机抽取部分样本演示
  2. # 获取训练集数据
  3. def get_train(size):
  4. # 随机生成要抽样的样本的索引
  5. index = np.random.randint( 0, np.shape(train_images)[ 0], size)
  6. # 将这些数据resize成227*227大小
  7. resized_images = tf.image.resize_with_pad(train_images[ index], 227, 227,)
  8. # 返回抽取的
  9. return resized_images.numpy(), train_labels[ index]
  10. # 获取测试集数据
  11. def get_test(size):
  12. # 随机生成要抽样的样本的索引
  13. index = np.random.randint( 0, np.shape(test_images)[ 0], size)
  14. # 将这些数据resize成227*227大小
  15. resized_images = tf.image.resize_with_pad(test_images[ index], 227, 227,)
  16. # 返回抽样的测试样本
  17. return resized_images.numpy(), test_labels[ index]

调用上述两个方法,获取参与模型训练和测试的数据集:


  
  1. # 获取训练样本和测试样本
  2. train_images,train_labels = get_train( 256)
  3. test_images,test_labels = get_test( 128)

为了让大家更好的理解,我们将数据展示出来:


  
  1. # 数据展示:将数据集的前九个数据集进行展示
  2. for i in range( 9):
  3. plt. subplot( 3, 3,i+ 1)
  4. # 以灰度图显示,不进行插值
  5. plt. imshow(train_images[i]. astype(np.int8). squeeze(), cmap= 'gray', interpolation= 'none')
  6. # 设置图片的标题:对应的类别
  7. plt. title( "数字{}". format(train_labels[i]))

结果为:

 

我们就使用上述创建的模型进行训练和评估。

2.2 模型编译


  
  1. # 指定优化器,损失函数和评价指标
  2. optimizer = tf.keras.optimizers.SGD(learning_rate= 0.01, momentum= 0.0, nesterov= False)
  3. net. compile(optimizer=optimizer,
  4. loss= 'sparse_categorical_crossentropy',
  5. metrics=[ 'accuracy'])

2.3 模型训练


  
  1. # 模型训练:指定训练数据,batchsize,epoch,验证集
  2. net.fit(train_images,train_labels,batch_size= 128,epochs= 3,verbose= 1,validation_split= 0.1)

训练输出为:


  
  1. Epoch 1/3
  2. 2/2 [ ==============================] - 3s 2s/step - loss: 2.3003 - accuracy: 0.0913 - val_loss: 2.3026 - val_accuracy: 0.0000e+00
  3. Epoch 2/3
  4. 2/2 [ ==============================] - 3s 2s/step - loss: 2.3069 - accuracy: 0.0957 - val_loss: 2.3026 - val_accuracy: 0.0000e+00
  5. Epoch 3/3
  6. 2/2 [ ==============================] - 4s 2s/step - loss: 2.3117 - accuracy: 0.0826 - val_loss: 2.3026 - val_accuracy: 0.0000e+00

2.4 模型评估


  
  1. # 指定测试数据
  2. net.evaluate(test_images,test_labels,verbose= 1)

输出为:


  
  1. 4/ 4 [==============================] - 1s 168ms/ step - loss: 2.3026 - accuracy: 0.0781
  2. [2.3025851249694824, 0.078125]

如果我们使用整个数据集训练网络,并进行评估的结果:

[0.4866700246334076, 0.8395]

总结

  • 知道AlexNet的网络架构
  • 动手实现手写数字的识别

人工智能学习路线,记得收藏哦


零基础入门:

Python小白基础入门教程 Python入门到精通教程
零基础必备:全套Python教程_Python基础入门视频教程,零基础小白自学Python入门教程

python基础进阶:Python深入浅出进阶教程【敢信?】收藏=点赞十倍
Python实战Djongo项目:python企业级开发项目-手把手从0到1开发《美多商城》
mysql数据库:MySQL全套教程,MySQL从基础到黑马订单案例实战
机器学习算法:3天快速入门python机器学习
聚类算法:360°解读机器学习经典算法——聚类算法
数据挖掘:Python教程,4天快速入门Python数据挖掘,系统精讲+实战案例
Web服务器:Python高级语法进阶教程_python多任务及网络编程,从零搭建网站全套教程
180分钟爬虫入门:180分钟轻松获取疫情数据,Python爬虫入门课
Scrapy框架:Python爬虫基础,快速入门Scrapy爬虫框架
多线程:python多线程编程

人工智能入门:智能机器人软件开发教程基础,从helloworld到神经网络
人工智能深度学习:智能机器人软件开发教程基础,从helloworld到神经网络
图像与视觉处理:人工智能教程|零基础学习计算机视觉快速入门


 


转载:https://blog.csdn.net/m0_57290404/article/details/128580469
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场