探究几种神经网络不同写法的效果(Tensorflow2 以AlexNet网络为例)

猫狗分类的数据集,各一千张。

一.第一版

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pathlib
from keras.layers import Input, Activation, BatchNormalization, Flatten
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout
from keras.models import Model

gpus = tf.config.list_physical_devices("GPU")

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)  # 设置GPU显存用量按需使用
    tf.config.set_visible_devices([gpus[0]], "GPU")

# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 设置随机种子尽可能使结果可以重现
np.random.seed(1)
# 设置随机种子尽可能使结果可以重现
tf.random.set_seed(1)

# 数据集路径
data_dir = r"F:\Projects"
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*')))
print("图片总数为:", image_count)

batch_size = 8
img_height = 224
img_width = 224

# 训练集
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 测试集
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 检查数据
class_names = train_ds.class_names
print(class_names)

for image_batch, labels_batch in train_ds:
    print(image_batch.shape)  # (8, 224, 224, 3)
    print(labels_batch.shape)  # (8,)
    break

# 配置数据集
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)


# 搭建网络模型
def AlexNet(num_classes, input_shape):
    # 输入层
    input_tensor = Input(shape=input_shape)
    # 第一层
    x = Conv2D(96, (11, 11), strides=4, padding='valid', activation='relu', name='conv-1')(input_tensor)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='MaxPool-1')(x)

    # 第二层
    x = Conv2D(256, (5, 5), strides=1, padding='same', activation='relu', name='conv-2')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-2')(x)

    # 第三层
    x = Conv2D(384, (3, 3), strides=1, padding='same', activation='relu', name='conv-3')(x)

    # 第四层
    x = Conv2D(384, (3, 3), strides=1, padding='same', activation='relu', name='conv-4')(x)

    # 第五层
    x = Conv2D(256, (3, 3), strides=1, padding='same', activation='relu', name='conv-5')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-3')(x)

    # 第六七八层:全连接层
    x = Flatten()(x)
    x = Dense(4096, activation='relu', name='fc1')(x)
    x = Dense(4096, activation='relu', name='fc2')(x)
    output_tensor = Dense(num_classes, activation='softmax', name='predictions')(x)
    
    model = Model(input_tensor, output_tensor)
    return model


model = AlexNet(1000, (img_width, img_height, 3))
model.summary()

# 编译
opt = tf.keras.optimizers.Adam(learning_rate=1e-7)

model.compile(optimizer="adam",
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

epochs = 10  # 训练轮数
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs
)

# 模型评估可视化
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

# 保存模型
model.save('model/alexnet_model2.h5')
print('模型保存成功!')

可以训练,但是没什么用:
在这里插入图片描述
在这里插入图片描述
可以看到几乎没什么收敛。

第二版

在这里插入图片描述
这次主要添加了上面两行,其他没修改。
在这里插入图片描述
在这里插入图片描述
但是效果跟之前差不多,所以应该是网络结构的书写出了问题。

第三版

这次在第二版的基础上把激活函数的写法给修改了:
在这里插入图片描述
即在每个卷积层后面添加Activation。但是发现效果跟之前差不多,不收敛。
在这里插入图片描述
在这里插入图片描述
第三版的网络部分代码,其他没有修改:

# 搭建网络模型
def AlexNet(num_classes, input_shape):
    # 输入层
    input_tensor = Input(shape=input_shape)
    # 第一层
    x = Conv2D(96, (11, 11), strides=4, padding='valid', name='conv-1')(input_tensor)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='MaxPool-1')(x)

    # 第二层
    x = Conv2D(256, (5, 5), strides=1, padding='same', activation='relu', name='conv-2')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-2')(x)

    # 第三层
    x = Conv2D(384, (3, 3), strides=1, padding='same', activation='relu', name='conv-3')(x)
    x = Activation('relu')(x)
    # 第四层
    x = Conv2D(384, (3, 3), strides=1, padding='same', activation='relu', name='conv-4')(x)
    x = Activation('relu')(x)
    # 第五层
    x = Conv2D(256, (3, 3), strides=1, padding='same', activation='relu', name='conv-5')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-3')(x)

    # 第六七八层:全连接层
    x = Flatten()(x)
    x = Dense(4096, activation='relu', name='fc1')(x)
    x = Dropout(0.5)(x)  # 加入0.5的Dropout
    x = Dense(4096, activation='relu', name='fc2')(x)
    x = Dropout(0.5)(x)
    output_tensor = Dense(num_classes, activation='softmax', name='predictions')(x)

    model = Model(input_tensor, output_tensor)
    return model

第四版

这次在前面两个卷积层后面添加了BN操作,可是还是一样的效果。
在这里插入图片描述

最后

最后换了一个数据集,换成鸟类分类的数据集,写法如下,准确率提高了,说明基本能用。

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pathlib
from keras.layers import Input, Activation, BatchNormalization, Flatten
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout
from keras.models import Model

gpus = tf.config.list_physical_devices("GPU")

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)  # 设置GPU显存用量按需使用
    tf.config.set_visible_devices([gpus[0]], "GPU")

# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 设置随机种子尽可能使结果可以重现
np.random.seed(1)
# 设置随机种子尽可能使结果可以重现
tf.random.set_seed(1)

# 数据集路径
data_dir = r"F:\Dataset_DL\bird_photos"
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*')))
print("图片总数为:", image_count)

batch_size = 8
img_height = 227
img_width = 227

# 训练集
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 测试集
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 检查数据
class_names = train_ds.class_names
print(class_names)

for image_batch, labels_batch in train_ds:
    print(image_batch.shape)  # (8, 224, 224, 3)
    print(labels_batch.shape)  # (8,)
    break

# 配置数据集
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

seed = 7
np.random.seed(seed)


# 搭建网络模型
# 搭建网络模型
def AlexNet(num_classes, input_shape):
    # 输入层
    input_tensor = Input(shape=input_shape)
    # 第一层
    x = Conv2D(96, (11, 11), strides=4, padding='valid',name='conv-1')(input_tensor)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='MaxPool-1')(x)

    # 第二层
    x = Conv2D(256, (5, 5), strides=1, padding='same', name='conv-2')(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-2')(x)

    # 第三层
    x = Conv2D(384, (3, 3), strides=1, padding='same', name='conv-3')(x)
    x = Activation('relu')(x)
    # 第四层
    x = Conv2D(384, (3, 3), strides=1, padding='same', name='conv-4')(x)
    x = Activation('relu')(x)
    # 第五层
    x = Conv2D(256, (3, 3), strides=1, padding='same', name='conv-5')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=2, padding='valid', name='Maxpool-3')(x)

    # 第六七八层:全连接层
    x = Flatten()(x)
    x = Dense(4096, activation='relu', name='fc1')(x)
    x = Dropout(0.5)(x)  # 加入0.5的Dropout
    x = Dense(4096, activation='relu', name='fc2')(x)
    x = Dropout(0.5)(x)
    output_tensor = Dense(num_classes, activation='softmax', name='predictions')(x)

    model = Model(input_tensor, output_tensor)
    return model


model = AlexNet(1000, (img_width, img_height, 3))
model.summary()

# 编译
opt = tf.keras.optimizers.Adam(learning_rate=1e-7)

model.compile(optimizer="adam",
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

epochs = 10  # 训练轮数
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs
)

# 模型评估可视化
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

# 保存模型
model.save('model/alexnet_model2.h5')
print('模型保存成功!')

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值