365天深度学习训练营-第T9周:猫狗识别2

 我的环境:

  • 语言环境:Python3.11.2
  • 编译器:PyCharm Community Edition 2022.3
  • 深度学习环境:TensorFlow2 

 一、跑通代码

1.1 导入数据构建网络

        导入并配置数据数据,构建VGG16神经网络

import matplotlib.pyplot as plt
import pathlib,PIL,warnings
import tensorflow as tf
from tensorflow.keras import layers,models,Input
from tensorflow.keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout
from tensorflow.keras.models import Model
import numpy as np
from tqdm import tqdm
import tensorflow.keras.backend as k
#用来设置中文字体,此处为黑体
plt.rcParams['font.sans-serif'] = ['SimHei']
#用来显示负号
plt.rcParams['axes.unicode_minus'] = False
#隐藏警告
warnings.filterwarnings('ignore')

#导入数据
path = 'F:/365-7-data'
data = pathlib.Path(path)

#显示数据
count = len(list(data.glob('*/*')))
print(count)
PIL.Image.open(str(list(data.glob('cat/*'))[0])).show()

#配置数据
batch_size=8
img_height = 224
img_width = 224

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data,
    validation_split=0.2,
    subset='training',
    seed=123,
    image_size=(img_height,img_width),
    batch_size=batch_size
)
vali_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data,
    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 img,labels in train_ds.take(1):
    print(img.shape)
    print(labels.shape)
    break

#配置数据集
AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
vali_ds = vali_ds.cache().prefetch(buffer_size=AUTOTUNE)

normalization_layer = layers.experimental.preprocessing.Rescaling(1./255)
train_ds = train_ds.map(lambda x,y:(normalization_layer(x),y))
vali_ds = vali_ds.map(lambda x,y:(normalization_layer(x),y))

image_batch ,labels_batch = next(iter(train_ds))
print(np.min(image_batch[0]),np.max(image_batch[0]))

#构建VGG16
def VGG16(nb_classes, input_shape):
    input_tensor = Input(shape=input_shape)
    x = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv1')(input_tensor)
    y = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv2')(x)
    z = MaxPooling2D((2,2),strides=(2,2),name='block1_pool')(y)
    q = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv1')(z)
    w = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv2')(q)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(w)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
    x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
    x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
    x = Flatten()(x)
    x = Dense(4096,activation='relu',name='fc1')(x)
    x = Dense(4096, activation='relu', name='fc2')(x)
    output_tensor = Dense(nb_classes,activation='softmax',name='predictions')(x)
    print(output_tensor)
    print(type(output_tensor))
    model = Model(input_tensor,output_tensor)
    return model
model = VGG16(1000,(224,224,3))
model.summary()
model.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy']
)

        与T8周一样构建VGG16神经网络并编译

1.2 模型训练

        本次使用train_on_batch进行模型训练,配合tqdm显示进度条

epochs = 10
lr = 1e-4

history_train_loss = []
history_train_accuracy = []
history_val_loss = []
history_val_accuracy = []

for epoch in range(epochs):
    train_total = len(train_ds)
    val_total = len(val_ds)

    with tqdm(total=train_total,desc=f'Epoch{epoch+1}/{epochs}',mininterval=1,ncols=100) as pdar:
        lr = lr*0.92
        k.set_value(model.optimizer.lr, lr)
        train_loss = []
        train_accuracy = []
        for image,label in train_ds:
            history = model.train_on_batch(image,label)
            train_loss.append(history[0])
            train_accuracy.append(history[1])
            pdar.set_postfix({'loss':'%.4f'%history[0],
                             'accuracy':'%.4f'%history[1],
                              'lr': k.get_value(model.optimizer.lr)})
            pdar.update(1)
        history_train_loss.append(np.mean(train_loss))
        history_train_accuracy.append(np.mean(train_accuracy))

    print('开始验证')
    with tqdm(total=val_total,desc=f'Epoch{epoch+1}/{epochs}',mininterval=1,ncols=100) as pdar:
        val_loss = []
        val_accuracy = []
        for image,label in val_ds:
            history = model.train_on_batch(image,label)
            val_loss.append(history[0])
            val_accuracy.append(history[1])
            pdar.set_postfix({'loss':'%.4f'%history[0],
                             'accuracy':'%.4f'%history[1]})
            pdar.update(1)
        history_val_loss.append(np.mean(val_loss))
        history_val_accuracy.append(np.mean(val_accuracy))
    print('结束验证')
    print('验证loss为:%.4f' % np.mean(val_loss))
    print('验证准确率为:%.4f' % np.mean(val_accuracy))

        np.mean是numpy库中的一个函数,用于计算数组中元素的平均值。它的用法是:np.mean(array, axis=None)。其中,array是要计算平均值的数组,axis是指定计算平均值的轴。如果不指定axis,则计算整个数组的平均值。

        每一次循环获取的皆为每一批次的损失率及准确率。

1.3 模型评估

        评估准确率及损失率 

epochs_range = range(len(trloss))

plt.figure(figsize=(14,4))
plt.subplot(1,2,1)
plt.plot(epochs_range,history_train_accuracy,label='Training Accuracy')
plt.plot(epochs_range,history_val_accuracy,label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

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

二、第T8周bug

        原以为是学习率的问题,但经过本周学习发现准确率是正确的,第T8周在训练模型时将每一个batch的损失率以及准确率从新赋值给了变量,导致变量最终为最后一批的损失率及准确率。

        使用np.mean进行平均值取值

        输出一下每一次运行所得的列表

        可以看到每次循环都会增加一个数据到列表中。这是因为每一次循环都是一个batch,所得损失率以及准确率都是该batch的。 

        更改将每一次的模型数据添加到列表,然后求平均。

lr = lr*0.92
k.set_value(model.optimizer.lr, lr)
train_loss = []
train_accuracy = []
for image,label in train_ds:
    history = model.train_on_batch(image,label)
    train_loss.append(history[0])
    train_accuracy.append(history[1])
    pdar.set_postfix({'loss':'%.4f'%history[0],
                      'accuracy':'%.4f'%history[1],
                      'lr': k.get_value(model.optimizer.lr)})
    pdar.update(1)
history_train_loss.append(np.mean(train_loss))
history_train_accuracy.append(np.mean(train_accuracy))

        这样每一轮训练最终取值为每一批次的平均值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值