AlexNet总结与Keras实现

这周读了AlexNet的论文,大概总结下论文的内容。

0、论文地址

http://https//papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf

 

1、激活函数

和之前通常使用的softmax或者tanh激活函数不同,论文中使用了ReLU激活函数,论文中称ReLU会使训练误差下降的更快。

 

2、在多GPU中运行

论文中使用了两块GTX580训练,两个GPU会在特定的层进行通信。双GPU会使得提高1.7%的top-1和1.2%的top-5准确度。不过根据cs231n上所说,双GPU更有可能是当时显存不够的无奈之举。

 

3、局部响应归一化

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

其中a代表在feature map中第i个卷积核(x,y)坐标经过了ReLU激活函数的输出,n表示相邻的几个卷积核。N表示这一层总的卷积核数量。k, n, α和β是hyper-parameters,他们的值是在验证集上实验得到的,其中k = 2,n = 5,α = 0.0001,β = 0.75。
 

4、Overlapping Pooling

论文中说Pooling单元在总结提取特征的时候,其输入会受到相邻pooling单元的输入影响,也就是提取出来的结果可能是有重复的(对max pooling而言)。而且,实验表示使用带交叠的Pooling的效果比的传统要好,在top-1和top-5上分别提高了0.4%和0.3%,在训练阶段有避免过拟合的作用。
 

 

5、模型结构

 

6、数据增益

第一种方法是原大小为256*256的图片中随机提取224*224的图片,以及它们水平方向的映像。

第二种方法是是在图像中每个像素的R、G、B值上分别加上一个数,用到的方法为PCA。

对于每个像素增加以下值:

p是主成分,lamda是特征值,alpha是N(0,0.1)高斯分布中采样得到的随机值。此方案名义上得到自然图像的重要特性,也就是说,目标是不随着光照强度和颜色而改变的。此方法降低top-1错误率1%。

 

7、Dropout

在层的输出之后随即丢弃0.5的数据,会减少过拟合,不过也会需要双倍的训练次数。

 

8、训练细节

论文中使用随机梯度下降,

权重衰减为0.005,momentum为0.9。

i是迭代指数,v是动力变量,ε是学习率,是目标关于w、对求值的导数在第i批样例上的平均值。

 

9、讨论

去掉任一层都会使得结果降低,说明深度很重要。之后会把CNN用在视频上。估计这也和之后的LSTM之类的模型有关。

 

10、实现:

以Kaggle上的Leaf Classification一题为例,构建了AlexNet进行测试。

数据地址:

https://www.kaggle.com/c/leaf-classification/data

卷积之后是先归一化再池化还是先池化再归一化好像有不同的说法,代码中以先归一化再池化为例。

正确率能达到0.9926,loss为0.02219。

 

# -*-coding = utf-8 -*-
import os

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 = '../input/images/'
IMG_HEIGHT = 400
IMG_WIDTH = 500
IMG_CHANNELS = 1
'''
    处理label
'''
train_csv = pd.read_csv('../input/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('../input/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])

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值