一.AlexNet的概述

AlexNet由Geoffrey和他的学生Alex提出,并在2012年的ILSVRC竞赛中获得了第一名。Alexnet共有8层结构,前5层为卷积层,后三层为全连接层。

AlexNet网络结构具有如下特点:

1.AlexNet在激活函数上选取了非线性非饱和的relu函数,在训练阶段梯度衰减快慢方面,relu函数比传统神经网络所选取的非线性饱和函数(如sigmoid函数,tanh函数)要快许多。

2.AlexNet在双gpu上运行,每个gpu负责一半网络的运算

3.采用局部响应归一化(LRN)。对于非饱和函数relu来说,不需要对其输入进行标准化,但Alex等人发现,在relu层加入LRN,可形成某种形式的横向抑制,从而提高网络的泛华能力。

4.池化方式采用overlapping pooling。即池化窗口的大小大于步长,使得每次池化都有重叠的部分。(ps:这种重叠的池化方式比传统无重叠的池化方式有着更好的效果,且可以避免过拟合现象的发生)

二.AlexNet网络结构

第一个卷积层

    输入的图片大小为:224*224*3,为后续处理方便,普遍改为227*227*3

    第一个卷积层为:11*11*3即卷积核尺寸为11*11,有96个卷积核,步长为4,卷积层后跟ReLU,因此输出的尺寸为 (227-11)/4+1=55,因此其输出的每个特征图 为 55*55*96,同时后面经过LRN层处理,尺寸不变.

    最大池化层,池化核大小为3*3,步长为2,输出的尺寸为 (55-3)/2+1=27,因此特征图的大小为:27*27*96。由于双gpu处理,故每组数据有27*27*48个特征图,共两组数据,分别在两个gpu中进行运算

第二层卷积层

    每组输入的数据为27*27*48,共两组数据

    每组数据都被128个卷积核大小为: 5*5*48进行卷积运算,步长为1,尺寸不会改变,同样紧跟ReLU,和LRN层进行处理.

    最大池化层,核大小为3*3,步长为2,因此输出两组特征图:13*13*128

第三层至第五层卷积层

    输入的数据为13*13*128,共两组

    第三层每组数据都被尺寸为 3*3*192的卷积核进行卷积运算,步长为1,加上ReLU,得到两组13*13*192的像素层

    第四层经过padding=1填充后,每组数据都被尺寸大小为 3*3*192的卷积核卷积运算,步长为1,加上ReLU,输出两组13*13*192的像素层

    第五层经过padding=1填充后,每组数据都被尺寸大小为 3*3*128的卷积核进行卷积运算,步长为1,加上ReLU,输出两组13*13*128的像素层

   经过3*3池化窗口,步长为2,池化后输出两组6*6*256的像素层

第六层至第八层全连接层

接下来的三层为全连接层,分别为:
6层. 4096 个神经元+ ReLU
7层. 4096个神经元 + ReLU
8层. 1000 个神经元,最后一层为softmax为1000类的概率值.

三.AlexNet的代码实现

该代码是用搭建好的AlexNet网络来实现MNIST手写体数字的识别(采用keras框架)

from keras.datasets import mnist
from matplotlib import pyplot as plt
from keras.utils import np_utils
from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPool2D,BatchNormalization
from keras.models import Sequential
from matplotlib import pyplot as plt

(X_train,Y_train),(X_test,Y_test)=mnist.load_data()
X_test1=X_test
Y_test1=Y_test
#处理图像特征
X_train=X_train.reshape(-1,28,28,1).astype("float32")/255.0
X_test=X_test.reshape(-1,28,28,1).astype("float32")/255.0
#处理标签
Y_train=np_utils.to_categorical(Y_train,10)
Y_test=np_utils.to_categorical(Y_test,10)
#print(X_train)
#print("-----------")
#print(Y_train)

#搭建AlexNet网络模型
#建立第一层卷积
model=Sequential()
model.add(Conv2D(
    filters=96,
    kernel_size=(11,11),
    strides=4,
    padding="same",
    input_shape=(28,28,1),
    activation="relu"
))

#搭建BN层
model.add(BatchNormalization())
#搭建第一层重叠最大池化层
model.add(MaxPool2D(
    pool_size=(3,3),
    strides=2,
    padding="same"
))

#建立第二层卷积
model.add(Conv2D(
    filters=256,
    kernel_size=(5,5),
    strides=1,
    padding="same",
    activation="relu"
))
#搭建BN层
model.add(BatchNormalization())
#搭建第二层池化层
model.add(MaxPool2D(
    pool_size=(3,3),
    strides=2,
    padding="same",
))

#搭建第三层卷积
model.add(Conv2D(
    filters=384,
    kernel_size=(3,3),
    strides=1,
    padding="same",
    activation="relu",
))

#搭建第四层卷积
model.add(Conv2D(
    filters=384,
    kernel_size=(3,3),
    strides=1,
    padding="same",
    activation="relu"
))

#搭建第五卷积层
model.add(Conv2D(
    filters=256,
    kernel_size=(3,3),
    strides=1,
    padding='same',
    activation="relu"
))
model.add(MaxPool2D(
    pool_size=(3,3),
    strides=2,
    padding="same"
))

#搭建第六层:全连接层
#在搭建全连接层之前,必须使用Flatten()降维
model.add(Flatten())
#全连接层
model.add(Dense(4096,activation="relu"))
model.add(Dropout(0.5))
#搭建第七层:全连接层
model.add(Dense(2048,activation="relu"))
model.add(Dropout(0.5))
#搭建第八层:全连接层即输出层
model.add(Dense(10,activation="softmax"))
model.summary()

#编译
model.compile(
    loss="categorical_crossentropy",
    optimizer="sgd",
    metrics=["accuracy"]
)

#训练
n_epoch=10
n_batch=128
training = model.fit(
    X_train,
    Y_train,
    epochs=n_epoch,
    batch_size=n_batch,
    verbose=1,
    validation_split=0.20
)

#画出准确率随着epoch的变化图
def show_train(tr,train,validation):
    plt.plot(training.history[train],linestyle="-",color="b")
    plt.plot(training.history[validation],linestyle="--",color="r")
    plt.title("trianing_history")
    plt.xlabel("epoch")
    plt.ylabel("accuracy")
    plt.legend(["train","validation"],loc="lower right")
    plt.show()
show_train(training,"accuracy","val_accuracy")
#画出误差随着epoch的变化图
def show_train(tr,train,validation):
    plt.plot(training.history[train],linestyle="-",color="b")
    plt.plot(training.history[validation],linestyle="--",color="r")
    plt.title("trianing_history")
    plt.xlabel("epoch")
    plt.ylabel("accuracy")
    plt.legend(["train","validation"],loc="upper right")
    plt.show()
show_train(training,"loss","val_loss")

#评估
test=model.evaluate(X_train,Y_train,verbose=1)
print("误差:",test[0])
print("准确率:",test[1])

#预测
def image_show(image):  #画图
    fig=plt.gcf()
    fig.set_size_inches(2,2)
    plt.imshow(image,cmap="binary")
    plt.show()
prediction=model.predict_classes(X_test)
def pre_result(i):
    image_show(X_test1[i])
    print("Y-test:",Y_test1[i])
    print("预测值:",prediction[i])
pre_result(0)
pre_result(1)

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐