背景:AlexNet是2012年提出的,也是当年ImageNet竞赛当年的冠军,是一个很经典的网络结构,里面有用到卷积(C)、批归一化(B)、激活(A)、池化(P)、遗忘(D),可谓是集齐了5颗龙珠CBAPD,并且AlexNet相比较1998年卷积的开山之作的LeNet的创新之处是首次采用批归一化,激活函数从sigmoid改用relu,最后运用了Dropout。
AlexNet的网络结构:
1、卷积1、批归一化1、激活1、池化1
2、卷积2、批归一化2、激活2、池化2
3、卷积3、激活3
4、卷积4、激活4
5、卷积5、激活5、池化5
6、拉平
7、全连接1、遗忘1
8、全连接2、遗忘2
9、全连接3
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Activation, BatchNormalization, Dropout
from tensorflow.keras import Model
# 获得数据集
cifar10 = tf.keras.datasets.cifar10
(x_train,y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train/255.0, x_test/255.0
class AlexNet(Model):
# 构造函数
def __init__(self):
super(AlexNet, self).__init__()
# 卷积
self.c1 = Conv2D(
filters=96,
kernel_size=(3, 3),
padding="valid"
)
# 批归一化
self.b1 = BatchNormalization()
# 激活
self.a1 = Activation('relu')
# 池化
self.p1 = MaxPool2D(
pool_size=(3,3),
strides=2
)
# 卷积
self.c2 = Conv2D(
filters=256,
kernel_size=(3, 3),
padding='valid'
)
# 批归一化
self.b2 = BatchNormalization()
# 激活
self.a2 = Activation('relu')
# 池化
self.p2 = MaxPool2D(
pool_size=(3,3),
strides=2
)
# 卷积
self.c3 = Conv2D(
filters=384,
kernel_size=(3,3),
strides=1,
padding="same"
)
# 激活
self.a3 = Activation('relu')
# 卷积
self.c4 = Conv2D(
filters=384,
kernel_size=(3, 3),
strides=1,
padding="same"
)
# 激活
self.a4 = Activation('relu')
# 卷积
self.c5 = Conv2D(
filters=256,
kernel_size=(3, 3),
strides=1,
padding="same"
)
# 激活
self.a5 = Activation('relu')
# 池化
self.p6 = MaxPool2D(
pool_size=(3,3),
strides=2
)
# 拉平
self.f1 = Flatten()
# 全连接
self.d1 = Dense(2048, activation='relu')
self.d1_ = Dropout(0.5)
# 全连接
self.d2 = Dense(2048, activation='relu')
self.d2_ = Dropout(0.5)
# 全连接
self.d3 = Dense(10, activation='softmax')
pass
# 前向传播函数
def call(self, x):
# 卷积1、批归一化1、激活1、池化1
x = self.c1(x)
x = self.b1(x)
x = self.a1(x)
x = self.p1(x)
# 卷积2、批归一化2、激活2、池化2
x = self.c2(x)
x = self.b2(x)
x = self.a2(x)
x = self.p2(x)
# 卷积3、激活3
x = self.c3(x)
x = self.a3(x)
# 卷积4、激活4
x = self.c4(x)
x = self.a4(x)
# 卷积5、激活5、池化5
x = self.c5(x)
x = self.a5(x)
x = self.p6(x)
# 拉平
x = self.f1(x)
# 全连接1、遗忘1
x = self.d1(x)
x = self.d1_(x)
# 全连接2、遗忘2
x = self.d2(x)
x = self.d2_(x)
# 全连接3
y = self.d3(x)
return y
pass
# 创建模型
model = AlexNet()
# 优化模型
model.compile(
optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['accuracy']
)
# 模型训练
model.fit(
x_train,
y_train,
batch_size=32,
epochs=2
)