前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Alexnet论文解读及代码实现

Alexnet论文解读及代码实现

作者头像
墨明棋妙27
发布2022-08-24 15:55:50
6250
发布2022-08-24 15:55:50
举报
文章被收录于专栏:1996

文章标题

ImageNet classification with deep revolutional Neural Networks(也就是经典的Alexnet网络)

论文链接:http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf

Summary

  作者使用ImageNet更大的数据集来训练神经网络。

激活函数

  与传统论文使用的tanh和sigmoid激活函数不同,本论文使用的是非线性函数Relu(Rectified Linear Units)函数。

  论文中称ReLU会使训练误差下降的更快。如下图所示

在多GPU中运行

  论文中使用了两块GTX580训练,两个GPU会在特定的层进行通信。双GPU会使得提高1.7%的top-1和1.2%的top-5准确度。并且会加快训练速度。

局部响应归一化

  ReLU本不需要对输入进行标准化,但是作者发现进行局部相应归一化能够提升性能。归一化公式如下:

重叠池化

  在传统方法中,相邻池化单元之间互不重叠,但是实验表示使用带交叠的Pooling的效果比的传统要好,在top-1和top-5上分别提高了0.4%和0.3%,在训练阶段有避免过拟合的作用。

神经网络结构

  该网络包含了八层权重:前五个是卷积层,其余三个为全连接层。最后的全连接层的输出被送到1000维的softmax函数,其产生1000个类的预测。我们的网络最大化多项逻辑回归目标,这相当于在预测的分布下最大化训练样本中正确标签对数概率的平均值。第二,第四和第五个卷积层的内核仅与上一层存放在同一GPU上的内核映射相连。第三个卷积层的内核连接到第二层中的所有内核映射。全连接层中的神经元连接到前一层中的所有神经元。响应归一化层紧接着第一个和第二个卷积层,后面连接响应归一化层以及第五个卷积层。将ReLU应用于每个卷积层和全连接层的输出。

减少过拟合

  减少过拟合有两种方法:一种是数据增强,一种是Dropout。

  ①数据增强:对图片进行水平映射、垂直映射、旋转等等变换。由于是对图片进行较小的计算,所以增强后的图片不用保存到硬盘里。

  ②Dropout:在训练期间,只需要消耗1/2的参数。它会以50%的概率将隐含层的神经元输出置为0。以这种方法被置0的神经元不参与网络的前馈和反向传播。因此,每次给网络提供了输入后,神经网络都会采用一个不同的结构,但是这些结构都共享权重。这种技术减少了神经元的复杂适应性,因为神经元无法依赖于其他特定的神经元而存在。因此,它被迫学习更强大更鲁棒的功能,使得这些神经元可以与其他神经元的许多不同的随机子集结合使用。

训练细节

  论文中使用随机梯度下降,权重衰减为0.005,momentum为0.9,batch_size=128。

  使用标准差=0.01,均值为0的高斯分布来初始化权重。在第二、四、五还有全连接层使用偏差为1来加速前期的训练,在其余层使用偏差为0。对每个层使用相同的学习率,learning_rate=0.01,训练过程进行3次的手动调整。

Evaluation

  去掉任一层都会使得结果降低,说明深度很重要。

  没有使用无监督方法去预训练数据。对视频序列效果不明显,因为时间结构往往在静态图像中丢失了。

结合代码看更容易理解网络结构

代码语言:javascript
复制
import pandas as pd
import numpy as np
from keras.callbacks import EarlyStopping, ModelCheckpoint
from matplotlib import pyplot as plt
from skimage.io import imread, imshow
from skimage import transform
import warnings
from tqdm import tqdm
from keras.layers import Input, Lambda, Conv2D, MaxPool2D, BatchNormalization, Dense, Flatten, Dropout
from keras.models import Model
from keras.utils import to_categorical
 
warnings.filterwarnings('ignore')
 
image_path = 'F:\\Keras_cnn\\images\\'  #文件路径这样写才正确,刚开始以为是'/'一直显示找不到该文件
IMG_HEIGHT = 400
IMG_WIDTH = 500
IMG_CHANNELS = 1
'''
    处理label
'''
train_csv = pd.read_csv('train.csv')
train_label_string = train_csv['species'].values
train_id = train_csv['id'].values
 
laber_number_dict = {}
train_label_number = []
number = 0
for i in train_label_string:
    if i in laber_number_dict:
        train_label_number.append(laber_number_dict[i])
    else:
        laber_number_dict.update({i: number})
        train_label_number.append(number)
        number += 1
 
id_label_dict = dict(zip(train_id, train_label_number))
 
test_csv = pd.read_csv('test.csv')
test_id = test_csv['id'].values
 
train_data = np.zeros((len(train_id), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)
train_label = np.zeros((len(train_id), 1), dtype=np.uint8)
test_data = np.zeros((len(test_id), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)
 
for n, i in tqdm(enumerate(train_id), total=len(train_data)):
    image_data = imread(image_path + str(i) + '.jpg')
    image_data = transform.resize(image_data, (IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
    train_data[n] = image_data
    train_label[n] = id_label_dict[i]
 
train_label = to_categorical(train_label, 99)
 
for n, i in tqdm(enumerate(test_id), total=len(test_id)):
    image_data = imread(image_path + str(i) + '.jpg')
    image_data = transform.resize(image_data, (IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))
    test_data[n] = image_data
 
random_number = np.random.randint(len(train_id))
show_train_data = train_data[random_number].reshape(IMG_HEIGHT, IMG_WIDTH)
imshow(show_train_data)
plt.show()
 
'''
    开始搭建 AlexNet
'''
 
inputs = Input((IMG_HEIGHT, IMG_WIDTH, 1))
c1 = Conv2D(48, (11, 11), strides=4, activation='relu', kernel_initializer='uniform', padding='valid')(inputs)
c2 = BatchNormalization()(c1)
c3 = MaxPool2D((3, 3), strides=2, padding='valid')(c2)
 
c4 = Conv2D(128, (5, 5), strides=1, padding='same', activation='relu', kernel_initializer='uniform')(c3)
c5 = BatchNormalization()(c4)
c6 = MaxPool2D((3, 3), strides=2, padding='valid')(c5)
 
c7 = Conv2D(192, (3, 3), strides=1, padding='same', activation='relu', kernel_initializer='uniform')(c6)
c8 = Conv2D(192, (3, 3), strides=1, padding='same', activation='relu', kernel_initializer='uniform')(c7)
c9 = Conv2D(128, (3, 3), strides=1, padding='same', activation='relu', kernel_initializer='uniform')(c8)
c10 = MaxPool2D((3, 3), strides=2, padding='valid')(c9)
 
c11 = Flatten()(c10)
c12 = Dense(256, activation='relu')(c11)  # 论文中是2048
c13 = Dropout(0.5)(c12)
 
c14 = Dense(256, activation='relu')(c13)  # 论文中是2048
c15 = Dropout(0.5)(c14)
outputs = Dense(99, activation='softmax')(c15)  # 论文中是1000
 
model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
 
earlystopper = EarlyStopping(patience=5, verbose=1)
checkpointer = ModelCheckpoint('model-1.h5', verbose=1, save_best_only=True)
model.fit(train_data, train_label, validation_split=0.1, batch_size=256, epochs=256,
          callbacks=[earlystopper, checkpointer])
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 计算机视觉CV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章标题
  • Summary
    • 激活函数
      • 在多GPU中运行
        • 局部响应归一化
          • 重叠池化
            • 神经网络结构
              • 减少过拟合
                • 训练细节
                • Evaluation
                • 结合代码看更容易理解网络结构
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档