365天深度学习训练营-第T7周:咖啡豆识别

 我的环境:

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

 一、代码运行

 1.1 导入数据集

        使用pathlib库获取数据

import pathlib
path = 'F:/49-data/49-data'
data = pathlib.Path(path)

         查看数据

import PIL
print(len(list(data.glob(*/*.png))))
PIL.Image.open(str(list(data.glob(*/*.png))[1])).show()
'''
1200
'''

1.2 数据预处理

        将数据加载到tf.data.Dataset中

import tensorflow as tf
batch_size = 32
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
)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data,
    validation_split=0.2,
    subset='validation',
    seed=123,
    iamge_size=(img_height,img_width),
    batch_size=batch_size
)
class_names = train_ds.class_names
print(class_names)

         可视化数据

import matplotlib.pyplot as plt
plt.figure(figsize=(20,10))
for img,label in train_ds[0]:
    for i in range(20):
        plt.subplot(2,10,i+1)
        plt.xticks([])
        plt.yticks([])
        plt.imshow(img[1].numpy().astype('uint8'))
        plt.xlabel(label[i])
plt.show()

        配置数据集

from tensorflow.keras import layers,models
import numpy as np

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_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))
val_ds = val_ds.map(lambda x,y:normalization_layer(x),y)

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

1.3 构建VGG16模型

        这次使用VGG16模型,先构建VGG16网络

from tensorflow.keras import layers,models,Input
from tensorflow.keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout
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)
    x = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv2')(x)
    x = MaxPooling2D((2,2),strides=(2,2),name='block1_pool')(x)
    x = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv1')(x)
    x = Conv2D(128,(3,3),activation='relu',padding='same',name='block2_conv2')(x)
    x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)
    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)
    model = Model(input_tensor,output_tensor)
    return model
model = VGG16(1000,(224,224,3))
model.summary()

        VGG16包含13个卷积层,3个全连接层以及5个池化层 。与以往构建神经网络不同,这次试用函数式API,可以通过定义多个输入和多个输出来构建更加复杂的模型。与使用Sequential构建模型的区别是使用的API不同,通过直接将上一层的输出传递给下一层。与使用Sequential模型的主要区别在于它允许我们创建具有多个输入和输出的模型。在函数式API中,我们可以创建任意拓扑结构的模型,而不仅仅是简单的一维线性堆叠模型。因此,我们可以在模型中创建分支和合并,使我们能够实现更加复杂的神经网络结构。此外,函数式API还允许我们对神经网络模型的不同部分进行重复使用和共享,从而提高了代码的可重用性和可维护性。

        查看x所属类

x = Conv2D(64,(3,3),activation='relu',padding='same',name='block1_conv1')(Input(shape=(224,224,3)))
print(x)
print(type(x))
'''
KerasTensor(type_spec=TensorSpec(shape=(None, 224, 224, 64), dtype=tf.float32, name=None), name='block1_conv1/Relu:0', description="created by layer 'block1_conv1'")
<class 'keras.engine.keras_tensor.KerasTensor'>
'''

         x为张量对象,在看看output_tensor

output_tensor = Dense(nb_classes,activation='softmax',name='predictions')(x)
print(output_tensor)
print(type(output_tensor))
'''
KerasTensor(type_spec=TensorSpec(shape=(None, 1000), dtype=tf.float32, name=None), name='predictions/Softmax:0', description="created by layer 'predictions'")
<class 'keras.engine.keras_tensor.KerasTensor'>
'''

        将输入张量与输出张量传递给Model,模型构建完成。Model是一个通用的模型类,用于组合不同的层以构建深度学习的模型。 

1.4 编译

        依旧设置动态学习率,监控对象为准确率

initial_learning_rate = 1e-4
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate,
    decay_steps=60,
    decay_rate=0.96,
    staircase=True
)
optimizer = tf.keras.optimizers.Adam(lr_schedule)
model.compile(
    optimizer=optimizer,
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy']
)

1.5 训练模型

        设置保存参数及早停法开始模型训练 

epochs = 100
checkpointer = ModelCheckpoint('best_model.h5',monitor='val_accuracy',save_best_only=True,save_weights_only=True,verbose=1)
early = EarlyStopping(monitor='val_accuracy',min_delta=0.001,patience=20,verbose=1)

history = model.fit(train_ds,validation_data=val_ds,epochs=epochs,callbacks=[checkpointer,early])

1.6 模型评估

acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

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

epochs_range = range(len(loss))

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()

二、总结

        本次使用VGG16神经网络进行模型构建,其具有更深的结构,准确率也更高。使用函数式API进行模型搭建,该种搭建方式在搭建复杂模型以及非线性堆叠模型时更常使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值