AlexNet

一、AlexNet的网络架构

AlexNet与LeNet的设计理念非常相似,但也有显著的区别,其网络架构如下图所示:

在这里插入图片描述

该网络的特点是:

AlexNet包含8层变换,有5层卷积和2层全连接隐藏层,以及1个全连接输出层

AlexNet第一层中的卷积核形状是 11 × 11 11\times11 11×11。第二层中的卷积核形状减小到 5 × 5 5\times5 5×5,之后全采用 3 × 3 3\times3 3×3。所有的池化层窗口大小为 3 × 3 3\times3 3×3、步幅为2的最大池化。

AlexNet将sigmoid激活函数改成了ReLU激活函数,使计算更简单,网络更容易训练

AlexNet通过dropOut来控制全连接层的模型复杂度。

AlexNet引入了大量的图像增强,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。

在tf.keras中实现AlexNet模型:

# 构建AlexNet模型
net = tf.keras.models.Sequential([
    # 卷积层:96个卷积核,卷积核为11*11,步幅为4,激活函数relu
    tf.keras.layers.Conv2D(filters=96,kernel_size=11,strides=4,activation='relu'),
    # 池化:窗口大小为3*3、步幅为2
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    # 卷积层:256个卷积核,卷积核为5*5,步幅为1,padding为same,激活函数relu
    tf.keras.layers.Conv2D(filters=256,kernel_size=5,padding='same',activation='relu'),
    # 池化:窗口大小为3*3、步幅为2
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    # 卷积层:384个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
    tf.keras.layers.Conv2D(filters=384,kernel_size=3,padding='same',activation='relu'),
    # 卷积层:384个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
    tf.keras.layers.Conv2D(filters=384,kernel_size=3,padding='same',activation='relu'),
    # 卷积层:256个卷积核,卷积核为3*3,步幅为1,padding为same,激活函数relu
    tf.keras.layers.Conv2D(filters=256,kernel_size=3,padding='same',activation='relu'),
    # 池化:窗口大小为3*3、步幅为2
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    # 伸展为1维向量
    tf.keras.layers.Flatten(),
    # 全连接层:4096个神经元,激活函数relu
    tf.keras.layers.Dense(4096,activation='relu'),
    # 随机失活
    tf.keras.layers.Dropout(0.5),
    # 全链接层:4096个神经元,激活函数relu
    tf.keras.layers.Dense(4096,activation='relu'),
    # 随机失活
    tf.keras.layers.Dropout(0.5),
    # 输出层:10个神经元,激活函数softmax
    tf.keras.layers.Dense(10,activation='softmax')
])

我们构造一个高和宽均为227的单通道数据样本来看一下模型的架构:

# 构造输入X,并将其送入到net网络中
X = tf.random.uniform((1,227,227,1)
y = net(X)
# 通过net.summay()查看网络的形状
net.summay()

网络架构如下:
Model: “sequential”


Layer (type) Output Shape Param #

conv2d (Conv2D) (1, 55, 55, 96) 11712


max_pooling2d (MaxPooling2D) (1, 27, 27, 96) 0


conv2d_1 (Conv2D) (1, 27, 27, 256) 614656


max_pooling2d_1 (MaxPooling2 (1, 13, 13, 256) 0


conv2d_2 (Conv2D) (1, 13, 13, 384) 885120


conv2d_3 (Conv2D) (1, 13, 13, 384) 1327488


conv2d_4 (Conv2D) (1, 13, 13, 256) 884992


max_pooling2d_2 (MaxPooling2 (1, 6, 6, 256) 0


flatten (Flatten) (1, 9216) 0


dense (Dense) (1, 4096) 37752832


dropout (Dropout) (1, 4096) 0


dense_1 (Dense) (1, 4096) 16781312


dropout_1 (Dropout) (1, 4096) 0


dense_2 (Dense) (1, 10) 40970

Total params: 58,299,082
Trainable params: 58,299,082
Non-trainable params: 0


2、手写数字势识别

AlexNet使用ImageNet数据集进行训练,但因为ImageNet数据集较大训练时间较长,我们仍用前面的MNIST数据集来演示AlexNet。读取数据的时将图像高和宽扩大到AlexNet使用的图像高和宽227。这个通过tf.image.resize_with_pad来实现。

2.1 数据读取
首先获取数据,并进行维度调整:

import numpy as np
# 获取手写数字数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# 训练集数据维度的调整:N H W C
train_images = np.reshape(train_images,(train_images.shape[0],train_images.shape[1],train_images.shape[2],1))
# 测试集数据维度的调整:N H W C
test_images = np.reshape(test_images,(test_images.shape[0],test_images.shape[1],test_images.shape[2],1))

由于使用全部数据训练时间较长,我们定义两个方法获取部分数据,并将图像调整为227*227大小,进行模型训练:

# 定义两个方法随机抽取部分样本演示
# 获取训练集数据
def get_train(size):
    # 随机生成要抽样的样本的索引
    index = np.random.randint(0, np.shape(train_images)[0], size)
    # 将这些数据resize成227*227大小
    resized_images = tf.image.resize_with_pad(train_images[index],227,227,)
    # 返回抽取的
    return resized_images.numpy(), train_labels[index]
# 获取测试集数据 
def get_test(size):
    # 随机生成要抽样的样本的索引
    index = np.random.randint(0, np.shape(test_images)[0], size)
    # 将这些数据resize成227*227大小
    resized_images = tf.image.resize_with_pad(test_images[index],227,227,)
    # 返回抽样的测试样本
    return resized_images.numpy(), test_labels[index]

调用上述两个方法,获取参与模型训练和测试的数据集:

# 获取训练样本和测试样本
train_images,train_labels = get_train(256)
test_images,test_labels = get_test(128)

为了让大家更好的理解,我们将数据展示出来:

# 数据展示:将数据集的前九个数据集进行展示
for i in range(9):
    plt.subplot(3,3,i+1)
    # 以灰度图显示,不进行插值
    plt.imshow(train_images[i].astype(np.int8).squeeze(), cmap='gray', interpolation='none')
    # 设置图片的标题:对应的类别
    plt.title("数字{}".format(train_labels[i]))

在这里插入图片描述
2.2 模型编译

# 指定优化器,损失函数和评价指标
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.0, nesterov=False)

net.compile(optimizer=optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

2.3 模型训练

# 模型训练:指定训练数据,batchsize,epoch,验证集
net.fit(train_images,train_labels,batch_size=128,epochs=3,verbose=1,validation_split=0.1)

2.4 模型评估

# 指定测试数据
net.evaluate(test_images,test_labels,verbose=1)

a’lalex

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AlexNet是由Alex Krizhevsky等人在2012年提出的一个深度卷积神经网络(Convolutional Neural Network,CNN),它在ImageNet图像识别挑战赛中取得了显著突破,首次击败了传统的计算机视觉方法。这标志着深度学习在计算机视觉领域的重大进展。 在TensorFlow框架中,AlexNet可以被用来作为预训练模型,用于迁移学习任务,即在一个大型数据集(如ImageNet)上训练好的模型,在新的、具有相似任务的小规模数据集上进行微调。TensorFlow库提供了方便的接口,如`tf.keras.applications.AlexNet()`,可以直接加载预训练的AlexNet模型,并允许用户进行前向传播或对某些层进行修改和训练。 以下是使用AlexNet的基本步骤: 1. **导入模型**: ```python from tensorflow.keras.applications import AlexNet model = AlexNet(weights='imagenet') # 加载预训练权重 ``` 2. **冻结层**(如果不需要训练整个网络): ```python for layer in model.layers[:-10]: # 冻结除最后几层之外的层 layer.trainable = False ``` 3. **添加新层**(如果需要自定义输出): ```python new_output_layer = tf.keras.layers.Dense(units=...)(model.output) model = tf.keras.Model(inputs=model.input, outputs=new_output_layer) ``` 4. **编译和训练**(替换为新数据集): ```python model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(x_train, y_train, epochs=..., validation_data=(x_val, y_val)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值