- 🍨 本文为🔗365天深度学习训练营 内部限免文章(版权归 K同学啊 所有)
- ** 参考文章地址:[🔗TensorFlow入门实战|365天深度学习训练营-第7周:咖啡豆识别(训练营内部成员可读) ]**
- 🍖 作者:K同学啊
一、本周学习内容:
1、自己搭建VGG16网络
vgg16网络代码
def vgg_net(num_layer,filter):
blk = Sequential()
for _ in range(num_layer):
blk.add(Conv2D(filters=filter,kernel_size=3,padding='same',activation='relu'))
blk.add(MaxPool2D(pool_size=(2,2),strides=2))
return blk
conv_arch = [(2,64),(2,128),(3,256),(3,512),(3,512)]
model = Sequential()
for num_layer,filter in conv_arch:
model.add(vgg_net(num_layer,filter))
model.add(Sequential([
Flatten(),
Dense(4096,activation='relu'),
Dropout(0.5),
Dense(4096,activation='relu'),
Dropout(0.5),
Dense(len(class_num),activation='softmax') # 输出类别数自行更改
]))
x = tf.random.uniform((1,224,224,3))
y = model(x)
print(model.summary())
2、第一次训练
Epoch 1: val_acc improved from -inf to 0.47500, saving model to models_weights.h5
30/30 [==============================] - 28s 622ms/step - loss: 0.5809 - acc: 0.2823 - val_loss: 0.5517 - val_acc: 0.4750
……
我设置了早停 它经过来 193次迭代后结束
Epoch 195: val_acc did not improve from 0.99583
30/30 [==============================] - 8s 261ms/step - loss: 6.0461e-05 - acc: 1.0000 - val_loss: 0.0194 - val_acc: 0.9917
最优验证集达到了 0.99583
准备开始继续训练 即将第一次训练结束的最优模型加载入网络 其他不做修改 继续训练网络
将model = load_model("网络模型") #替代自己搭建的vgg16网络
3、继续训练
完蛋 忘记修改继续训练的模型的保存名称了
第一次迭代 验证集掉到 0.98333
终于在 第102次迭代时验证集到达了1.0000
Epoch 1: val_acc improved from -inf to 0.98333, saving model to models_weights.h5
30/30 [==============================] - 31s 828ms/step - loss: 0.0176 - acc: 0.9885 - val_loss: 0.0197 - val_acc: 0.9833
……
Epoch 102: val_acc improved from 0.99167 to 1.00000, saving model to models_weights1.h5
30/30 [==============================] - 16s 537ms/step - loss: 0.0166 - acc: 0.9906 - val_loss: 0.0107 - val_acc: 1.0000
Epoch 103/1000
30/30 [==============================] - ETA: 0s - loss: 0.0112 - acc: 0.9917
Epoch 103: val_acc did not improve from 1.00000
30/30 [==============================] - 8s 244ms/step - loss: 0.0112 - acc: 0.9917 - val_loss: 0.0080 - val_acc: 1.0000
二、前言
我们的数据图片共有1200 张,四个类别,类别即为文件夹名。
类别包括:[‘Dark’, ‘Green’, ‘Light’, ‘Medium’]
在我们使用tensorflow.keras.preprocessing.image_dataset_from_directory()函数读取后会弹出下列提示
Found 1200 files belonging to 4 classes.
Using 240 files for validation.
[‘Dark’, ‘Green’, ‘Light’, ‘Medium’]
三、电脑环境
电脑系统:Windows 10
语言环境:Python 3.8.8
编译器:Pycharm 2021.1.3
深度学习环境:TensorFlow 2.8.0,keras 2.8.0
显卡及显存:RTX 3070 8G
四、前期准备
1、导入相关依赖项
from keras.models import Sequential
from keras.layers import *
from tensorflow import keras
from keras.callbacks import ModelCheckpoint
import tensorflow as tf
import matplotlib.pyplot as plt
2、设置GPU(我下载的tensorflow-gpu 默认使用GPU)
只使用GPU
if gpus:
gpu0 = gpus[0] #如果有多个GPU,仅使用第0个GPU
tf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用
tf.config.set_visible_devices([gpu0],"GPU")
使用cpu和gpu
os.environ[“CUDA_VISIBLE_DEVICES”] = “-1”
3、加载数据集和展示
(1)、数据集加载
# 数据集加载
traindatadir = "./dataset"
train = keras.preprocessing.image_dataset_from_directory(directory=traindatadir,
validation_split=0.2,
subset='training',
seed=469,
label_mode='categorical',
image_size=(224,224),
batch_size=32)
val = keras.preprocessing.image_dataset_from_directory(directory=traindatadir,
validation_split=0.2,
subset='validation',
seed=469,
label_mode='categorical',
image_size=(224,224),
batch_size=32)
class_names = train.class_names
print(class_names)
(2)、数据展示
图片展示
# 图片展示
plt.figure(figsize=(20, 5)) # 创建一个画布,画布大小为宽20、高5(单位为英寸inch)
for images,labels in train.take(1):
for i in range(20):
# 将整个画布分成2行10列,绘制第i+1个子图。
plt.subplot(2, 10, i+1)
plt.imshow(images[i].numpy().astype("uint8"), cmap=plt.cm.binary)
plt.title(class_names[np.argmax(labels[i])]) # 由于我们使用了one_hot 这行与之前不同
plt.axis('off')
plt.show() #使用pycharm的需要加入这行代码才能将图像显示出来
# train.take(i) 取出第i组图片数据和标签,即将所有图片打包后一个batch为32,
五、数据预处理
注意此时我们使用了热编码加载数据 标签格式变为:
# 数据预处理
tf.keras.layers.experimental.preprocessing.Rescaling(1./255,input_shape=(224,224,3))
六、搭建CNN网络
# 网络模型
def vgg_net(num_layer,filter):
blk = Sequential()
for _ in range(num_layer):
blk.add(Conv2D(filters=filter,kernel_size=3,padding='same',activation='relu'))
blk.add(MaxPool2D(pool_size=(2,2),strides=2))
return blk
conv_arch = [(2,64),(2,128),(3,256),(3,512),(3,512)]
# model = Sequential([Conv2D(filters=64,kernel_size=3,padding='same',activation='relu',input_shape=(224,224,1))])
model = Sequential()
for num_layer,filter in conv_arch:
model.add(vgg_net(num_layer,filter))
# print(model.summary())
model.add(Sequential([
Flatten(),
Dense(4096,activation='relu'),
Dropout(0.5),
Dense(4096,activation='relu'),
Dropout(0.5),
Dense(17,activation='softmax')
]))
x = tf.random.uniform((1,224,224,3))
y = model(x)
print('y',y)
print(model.summary())
# 设置保存最优模型
checkpointer = ModelCheckpoint(
filepath='models_weights.h5', #模型保存位置
monitor='val_acc', # 监测参数
verbose=1, # 0为不输出日志信息,1为输出进度条记录,2为每个epoch输出一条记录
save_best_only=True, # 仅保存最优模型
save_weights_only= True # 仅保存权重文件 注意如果仅保存权重模型,还需要自己搭建原模型对应的网络
)
# 设置早停
earlystopper = EarlyStopping(
monitor="val_accuracy", # 被检测的数据
min_delta=0.001, # 被检测数据中被认为的最小变化值
patience=50, # 训练没有进步的轮次
verbose=1 # 日志
)
# 设置 动态学习率
initial_learing_rate = 0.001
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
initial_learing_rate,
decay_steps=8, # 训练多少个steps衰减一次(注意不是epochs) staircase = True 时有效
decay_rate = 0.92, # 衰减的比例 用原本学习率乘以该数值获得衰减后的学习率
staircase = True # 如果为True, 学习率呈现阶梯型下降趋势.
)
model.compile(optimizer=keras.optimizers.SGD(learning_rate=lr_schedule),loss=loss=keras.losses.binary_crossentropy,metrics=['acc'])
history = model.fit(train,validation_data=val,epochs=1000,verbose=1,
callbacks=[checkpointer,earlystopper])
evaluate = model.evaluate(val)
print(evaluate)
七、绘制损失函数图像和准确度图像
绘制代码与前几周相同
# 画准确度图
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(1000)
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()
以上就是我本周的学习内容