Alexnet论文解读及代码实现

举报
小小谢先生 发表于 2022/04/13 23:36:58 2022/04/13
【摘要】 本文首发于微信公众号“计算机视觉cv” # Title文章标题  ImageNet classification with deep revolutional Neural Networks(也就是经典的Alexnet网络) # Summary 作者使用ImageNet更大的数据集来训练神经网络。 1、激活...

本文首发于微信公众号“计算机视觉cv”

# Title文章标题

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

# Summary

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

1、激活函数

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

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

2、在多GPU中运行

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

3、局部响应归一化

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

4、 重叠池化

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

5、神经网络结构

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

6、减少过拟合

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

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

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

7、训练细节

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

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

# Evaluation

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

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

 

# Code

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])

 

文章来源: blog.csdn.net,作者:小小谢先生,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/xiewenrui1996/article/details/103306379

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。