《python深度学习》笔记---5.3-2、猫狗分类(使用预训练网络-实战)
《python深度学习》笔记---5.3-2、猫狗分类(使用预训练网络-实战)
一、总结
一句话总结:
【卷积就是特征提取】:从预训练网络训练猫狗分类,可以更加方便的理解卷积层就是特征提取
【使用预训练网络效果非常好】:我们的验证精度达到了约90%,比上一节从头开始训练的小型模型效果要好得多。但从图 中也可以看出,虽然 dropout 比率相当大,但模型几乎从一开始就过拟合。这是因为本方法没有 使用数据增强,而数据增强对防止小型图像数据集的过拟合非常重要。
1、引入vgg16已经训练好的模型?
from tensorflow.keras.applications import VGG16
conv_base = VGG16(weights='imagenet',include_top=False,input_shape=(150, 150, 3))
# 把vgg模型弄过来 conv_base = VGG16(weights='imagenet', # include_top=False表示不包含dense层 include_top=False, input_shape=(150, 150, 3)) 这里向构造函数中传入了三个参数。 weights 指定模型初始化的权重检查点。 include_top 指定模型最后是否包含密集连接分类器。默认情况下,这个密集连接分类器对应于ImageNet 的 1000 个类别。因为我们打算使用自己的密集连接分类器(只有 两个类别:cat 和 dog),所以不需要包含它。 input_shape 是输入到网络中的图像张量的形状。这个参数完全是可选的,如果不传 入这个参数,那么网络能够处理任意形状的输入。
2、利用预训练好的VGG16抽取训练集、验证集和测试集的特征?
【主要就是VGG16的predict方法】:features_batch = conv_base.predict(inputs_batch)
''' directory:目录 sample_count:样本数 ''' def extract_features(directory, sample_count): # 初始化 features features = np.zeros(shape=(sample_count, 4, 4, 512)) # 初始化 labels labels = np.zeros(shape=(sample_count)) # 图像增强() generator = datagen.flow_from_directory( directory, target_size=(150, 150), batch_size=batch_size, class_mode='binary') i = 0 for inputs_batch, labels_batch in generator: # 调用 conv_base 模型的 predict 方法来从这些图像中提取特征。 features_batch = conv_base.predict(inputs_batch) # 切片依次找到features和labels features[i * batch_size : (i + 1) * batch_size] = features_batch labels[i * batch_size : (i + 1) * batch_size] = labels_batch i += 1 # 如果所有的样本弄完了,就终止循环 if i * batch_size >= sample_count: # 注意,这些生成器在循环中不断 生成数据,所以你必须在读取完 所有图像后终止循环 break return features, labels train_features, train_labels = extract_features(train_dir, 2000) validation_features, validation_labels = extract_features(validation_dir, 1000) test_features, test_labels = extract_features(test_dir, 1000)
3、预训练好的VGG16后面接dense层实例?
其实就是把vgg16提取好的特征放到作为输入数据放到dense网络里面就好
model = models.Sequential() model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512)) model.add(layers.Dropout(0.5)) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer=optimizers.RMSprop(lr=2e-5), loss='binary_crossentropy', metrics=['acc']) history = model.fit(train_features, train_labels, epochs=30, batch_size=20, validation_data=(validation_features, validation_labels))
二、5.3-2、猫狗分类(使用预训练网络-实战)
博客对应课程的视频位置:
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
In [3]:
from tensorflow.keras.applications import VGG16
# 把vgg模型弄过来
conv_base = VGG16(weights='imagenet',
# include_top=False表示不包含dense层
include_top=False,
input_shape=(150, 150, 3))
# C:\Users\Fan Renyi\.keras\models\vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
这里向构造函数中传入了三个参数。
weights 指定模型初始化的权重检查点。
include_top 指定模型最后是否包含密集连接分类器。默认情况下,这个密集连接分类器对应于ImageNet 的 1000 个类别。因为我们打算使用自己的密集连接分类器(只有 两个类别:cat 和 dog),所以不需要包含它。
input_shape 是输入到网络中的图像张量的形状。这个参数完全是可选的,如果不传 入这个参数,那么网络能够处理任意形状的输入。
1、 不使用数据增强的快速特征提取
首先,运行 ImageDataGenerator 实例,将图像及其标签提取为Numpy 数组。我们需要 调用 conv_base 模型的 predict 方法来从这些图像中提取特征。
In [1]:
import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator
In [4]:
base_dir = 'E:\\78_recorded_lesson\\001_course_github\\AI_dataSet\\dogs-vs-cats\\cats_and_dogs_small'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
test_dir = os.path.join(base_dir, 'test')
In [5]:
datagen = ImageDataGenerator(rescale=1./255)
batch_size = 20
In [12]:
'''
directory:目录
sample_count:样本数
'''
def extract_features(directory, sample_count):
# 初始化 features
features = np.zeros(shape=(sample_count, 4, 4, 512))
# 初始化 labels
labels = np.zeros(shape=(sample_count))
# 图像增强()
generator = datagen.flow_from_directory(
directory,
target_size=(150, 150),
batch_size=batch_size,
class_mode='binary')
i = 0
for inputs_batch, labels_batch in generator:
# 调用 conv_base 模型的 predict 方法来从这些图像中提取特征。
features_batch = conv_base.predict(inputs_batch)
# 切片依次找到features和labels
features[i * batch_size : (i + 1) * batch_size] = features_batch
labels[i * batch_size : (i + 1) * batch_size] = labels_batch
i += 1
# 如果所有的样本弄完了,就终止循环
if i * batch_size >= sample_count:
# 注意,这些生成器在循环中不断 生成数据,所以你必须在读取完 所有图像后终止循环
break
return features, labels
In [15]:
train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir, 1000)
test_features, test_labels = extract_features(test_dir, 1000)
In [17]:
print(train_features.shape)
print(train_labels.shape)
目前,提取的特征形状为 (samples, 4, 4, 512)。我们要将其输入到密集连接分类器中, 所以首先必须将其形状展平为 (samples, 8192)。
In [18]:
train_features = np.reshape(train_features, (2000, 4 * 4 * 512))
validation_features = np.reshape(validation_features, (1000, 4 * 4 * 512))
test_features = np.reshape(test_features, (1000, 4 * 4 * 512))
In [19]:
print(train_features.shape)
现在你可以定义你的密集连接分类器(注意要使用dropout 正则化),并在刚刚保存的数据 和标签上训练这个分类器。
In [20]:
from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras import optimizers
In [21]:
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
In [22]:
model.compile(optimizer=optimizers.RMSprop(lr=2e-5),
loss='binary_crossentropy',
metrics=['acc'])
In [23]:
history = model.fit(train_features, train_labels,
epochs=30,
batch_size=20,
validation_data=(validation_features, validation_labels))
训练速度非常快,因为你只需处理两个 Dense 层。即使在CPU 上运行,每轮的时间也不 到一秒钟。
训练期间的损失曲线和精度曲线
In [26]:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'b--', label='Training acc')
plt.plot(epochs, val_acc, 'r-', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'b--', label='Training loss')
plt.plot(epochs, val_loss, 'r-', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
我们的验证精度达到了约90%,比上一节从头开始训练的小型模型效果要好得多。但从图 中也可以看出,虽然 dropout 比率相当大,但模型几乎从一开始就过拟合。这是因为本方法没有 使用数据增强,而数据增强对防止小型图像数据集的过拟合非常重要。
根本原因的话其实就是 因为预训练的vgg16中训练了很多数据,而这些数据使准确率提供很正常
In [ ]:
版权申明:欢迎转载,但请注明出处
一些博文中有一些参考内容因时间久远找不到来源了没有注明,如果侵权请联系我删除。
在校每年国奖、每年专业第一,加拿大留学,先后工作于华东师范大学和香港教育大学。
2024-10-30:27岁,宅加太忙,特此在网上找女朋友,坐标上海,非诚勿扰,vx:fan404006308
AI交流资料群:753014672