商城网站的建设如何让百度收录
文章目录
- 一、前期准备
- 1.设置GPU
- 2.导入数据
- 3.查看数据
- 二、数据预处理
- 1.加载数据
- 2.可视化数据
- 3.再次检查数据
- 4.配置数据集
- 三、模型复现
- 1.DenseLayer
- 2.Transition
- 3.实现DenseNet网络
- 四、训练模型
- 五、结果可视化
- 总结
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
一、前期准备
1.设置GPU
import tensorflow as tf gpus = tf.config.list_physical_devices("GPU")if gpus:tf.config.experimental.set_memory_growth(gpus[0], True) # 设置GPUtf.config.set_visible_devices([gpus[0]], "GPU")
2.导入数据
import matplotlib.pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号import os,PIL,pathlib
import numpy as npfrom tensorflow import keras
from tensorflow.keras import layers, models
data_dir = "8/bird_photos"data_dir = pathlib.Path(data_dir)
3.查看数据
image_count = len(list(data_dir.glob('*/*')))print("图片总数为:", image_count)
图片总数为: 565
二、数据预处理
1.加载数据
batch_size = 8
img_height = 224
img_width = 224
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
"""
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)
Found 565 files belonging to 4 classes.
Using 452 files for training.
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
"""
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)
Found 565 files belonging to 4 classes.
Using 113 files for validation.
class_names = train_ds.class_names
print(class_names)
[‘Bananaquit’, ‘Black Skimmer’, ‘Black Throated Bushtiti’, ‘Cockatoo’]
2.可视化数据
plt.figure(figsize=(10, 5)) # 图形的宽为10高为5for images, labels in train_ds.take(1):for i in range(8):ax = plt.subplot(2, 4, i + 1) plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]])plt.axis("off")
2025-02-21 10:53:06.021196: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor 'Placeholder/_4' with dtype int32 and shape [452][[{{node Placeholder/_4}}]]
2025-02-21 10:53:06.021478: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor 'Placeholder/_0' with dtype string and shape [452][[{{node Placeholder/_0}}]]
2025-02-21 10:53:06.027975: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] 
plt.imshow(images[1].numpy().astype("uint8"))
<matplotlib.image.AxesImage at 0x175a9e920>
3.再次检查数据
for image_batch, labels_batch in train_ds:print(image_batch.shape)print(labels_batch.shape)break
(8, 224, 224, 3)
(8,)
2025-02-21 10:53:07.684073: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_4’ with dtype int32 and shape [452]
[[{{node Placeholder/_4}}]]
2025-02-21 10:53:07.684953: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_4’ with dtype int32 and shape [452]
[[{{node Placeholder/_4}}]]
4.配置数据集
AUTOTUNE = tf.data.AUTOTUNEtrain_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
三、模型复现
1.DenseLayer
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Modelclass DenseLayer(tf.keras.Model):"""Basic unit of DenseBlock (using bottleneck layer)"""def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):super(DenseLayer, self).__init__()# BatchNorm + ReLU + 1x1 Conv (Bottleneck layer)self.norm1 = layers.BatchNormalization()self.relu1 = layers.ReLU()self.conv1 = layers.Conv2D(filters=bn_size * growth_rate, kernel_size=1, strides=1, use_bias=False, padding="valid")# BatchNorm + ReLU + 3x3 Conv (Feature Extraction)self.norm2 = layers.BatchNormalization()self.relu2 = layers.ReLU()self.conv2 = layers.Conv2D(filters=growth_rate, kernel_size=3, strides=1, padding="same", use_bias=False)self.drop_rate = drop_ratedef call(self, x, training=False):"""Forward pass"""out = self.conv1(self.relu1(self.norm1(x, training=training)))out = self.conv2(self.relu2(self.norm2(out, training=training)))# Dropout if drop_rate > 0if self.drop_rate > 0:out = layers.Dropout(self.drop_rate)(out, training=training)# Concatenate input and new featuresreturn tf.concat([x, out], axis=-1) # TensorFlow uses `axis=-1` for channels
class DenseBlock(tf.keras.Model):"""Dense Block for DenseNet"""def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):super(DenseBlock, self).__init__()self.layers_list = []# 逐层添加 DenseLayerfor i in range(num_layers):layer = DenseLayer(num_input_features + i * growth_rate, growth_rate, bn_size, drop_rate)self.layers_list.append(layer)def call(self, x, training=False):"""Forward pass"""for layer in self.layers_list:x = layer(x, training=training) # 依次通过每个 DenseLayer,并进行拼接return x
2.Transition
class TransitionLayer(tf.keras.Model):"""Transition layer between two adjacent DenseBlock"""def __init__(self, num_input_features, num_output_features):super(TransitionLayer, self).__init__()# Batch Normalization + ReLUself.norm = layers.BatchNormalization()self.relu = layers.ReLU()# 1x1 Convolution to reduce feature mapsself.conv = layers.Conv2D(filters=num_output_features, kernel_size=1, strides=1, use_bias=False, padding="valid")# 2x2 Average Pooling (stride=2)self.pool = layers.AveragePooling2D(pool_size=2, strides=2)def call(self, x, training=False):"""Forward pass"""x = self.conv(self.relu(self.norm(x, training=training)))x = self.pool(x) # Reduce spatial dimensionsreturn x
3.实现DenseNet网络
class DenseNet(Model):"""DenseNet-BC Model"""def __init__(self, growth_rate=32, block_config=(6, 12, 24, 16), num_init_features=64,bn_size=4, compression_rate=0.5, drop_rate=0, num_classes=1000):""":param growth_rate: (int) number of filters used in DenseLayer, `k` in the paper:param block_config: (list of 4 ints) number of layers in each DenseBlock:param num_init_features: (int) number of filters in the first Conv2d:param bn_size: (int) the factor using in the bottleneck layer:param compression_rate: (float) the compression rate used in Transition Layer:param drop_rate: (float) the drop rate after each DenseLayer:param num_classes: (int) number of classes for classification"""super(DenseNet, self).__init__()# First Convolutional Layer (Conv2d + BN + ReLU + MaxPool)self.conv0 = layers.Conv2D(filters=num_init_features, kernel_size=7, strides=2,padding="same", use_bias=False)self.norm0 = layers.BatchNormalization()self.relu0 = layers.ReLU()self.pool0 = layers.MaxPooling2D(pool_size=3, strides=2, padding="same")# Dense Blocksself.blocks = []num_features = num_init_featuresfor i, num_layers in enumerate(block_config):block = DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate)self.blocks.append(block)num_features += num_layers * growth_rate# Transition Layerif i != len(block_config) - 1:num_output_features = int(num_features * compression_rate)transition = TransitionLayer(num_features, num_output_features)self.blocks.append(transition)num_features = num_output_features# Final BN + ReLUself.norm5 = layers.BatchNormalization()self.relu5 = layers.ReLU()# Global Average Pooling + Fully Connected Layer (Classifier)self.global_avg_pool = layers.GlobalAveragePooling2D()self.classifier = layers.Dense(num_classes)# Weight Initializationself._init_weights()def _init_weights(self):"""Initialize weights similar to PyTorch's kaiming_normal_"""for layer in self.layers:if isinstance(layer, layers.Conv2D):layer.kernel_initializer = tf.keras.initializers.HeNormal()elif isinstance(layer, layers.BatchNormalization):layer.beta_initializer = tf.keras.initializers.Zeros()layer.gamma_initializer = tf.keras.initializers.Ones()elif isinstance(layer, layers.Dense):layer.bias_initializer = tf.keras.initializers.Zeros()def call(self, x, training=False):"""Forward pass"""x = self.conv0(x)x = self.relu0(self.norm0(x, training=training))x = self.pool0(x)for block in self.blocks:x = block(x, training=training) # Pass through DenseBlocks and TransitionLayersx = self.relu5(self.norm5(x, training=training))x = self.global_avg_pool(x)x = self.classifier(x)return x
def densenet121(pretrained=False, weights_path=None, **kwargs):"""DenseNet121 in TensorFlow"""model = DenseNet(num_init_features=64, growth_rate=32, block_config=(6, 12, 24, 16),**kwargs)if pretrained and weights_path:model.load_weights(weights_path)print(f"Loaded pretrained weights from {weights_path}")return model
model = densenet121(pretrained=False, num_classes=4)
model.compile(optimizer="adam",loss='sparse_categorical_crossentropy',metrics=['accuracy'])
四、训练模型
epochs = 10history = model.fit(train_ds,validation_data=val_ds,epochs=epochs
)
Epoch 1/10
2025-02-21 10:54:10.969427: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_0’ with dtype string and shape [452]
[[{{node Placeholder/_0}}]]
2025-02-21 10:54:10.969780: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_4’ with dtype int32 and shape [452]
[[{{node Placeholder/_4}}]]
57/57 [==============================] - ETA: 0s - loss: 5.5120 - accuracy: 0.3230
2025-02-21 10:54:53.306479: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_4’ with dtype int32 and shape [113]
[[{{node Placeholder/_4}}]]
2025-02-21 10:54:53.306614: I tensorflow/core/common_runtime/executor.cc:1197] [/device:CPU:0] (DEBUG INFO) Executor start aborting (this does not indicate an error and you can ignore this message): INVALID_ARGUMENT: You must feed a value for placeholder tensor ‘Placeholder/_0’ with dtype string and shape [113]
[[{{node Placeholder/_0}}]]
57/57 [] - 45s 737ms/step - loss: 5.5120 - accuracy: 0.3230 - val_loss: 1.3863 - val_accuracy: 0.2655
Epoch 2/10
57/57 [] - 43s 750ms/step - loss: 3.0714 - accuracy: 0.4292 - val_loss: 1.3863 - val_accuracy: 0.3186
Epoch 3/10
57/57 [] - 41s 718ms/step - loss: 1.3863 - accuracy: 0.4646 - val_loss: 1.3863 - val_accuracy: 0.3186
Epoch 4/10
57/57 [] - 41s 717ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.4336
Epoch 5/10
57/57 [] - 41s 716ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.4425
Epoch 6/10
57/57 [] - 41s 716ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.5310
Epoch 7/10
57/57 [] - 41s 716ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.5398
Epoch 8/10
57/57 [] - 41s 717ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.5310
Epoch 9/10
57/57 [] - 41s 719ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.5221
Epoch 10/10
57/57 [] - 41s 716ms/step - loss: 1.3863 - accuracy: 0.4447 - val_loss: 1.3863 - val_accuracy: 0.5398
五、结果可视化
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()
总结
本周主要学习了DenseNet,特别了解了DenseNet的结构,其中最主要的是DenseNet的密集连接机制。使用了上周的数据集进行复现实验,更加深入地了解到了DenseNet的结构以及应用。