参考视频: https://www.bilibili.com/video/BV16A41157LW?p=34
获取cifar10数据(使用本地数据)
from tensorflow.python.keras.datasets.cifar import load_batch
def get_load_cifar10():
# 获取数据 直接使用 tf.keras.datasets.cifar10.load_data() 会报错(160M数据,可能是因为网络不好)
# cifar10数据下载 参考 https://zhuanlan.zhihu.com/p/129078357
# path 为解压后的路径
path = 'D:\\Repository\\ai_data\\DeepLearing_TensorFlow2.0-book\\cifar10\\cifar-10-batches-py\\'
num_train_samples = 50000
x_train = np.empty((num_train_samples, 3, 32, 32), dtype='uint8')
y_train = np.empty((num_train_samples,), dtype='uint8')
for i in range(1, 6):
fpath = os.path.join(path, 'data_batch_' + str(i))
(x_train[(i - 1) * 10000:i * 10000, :, :, :],
y_train[(i - 1) * 10000:i * 10000]) = load_batch(fpath)
fpath = os.path.join(path, 'test_batch')
x_test, y_test = load_batch(fpath)
y_train = np.reshape(y_train, (len(y_train), 1))
y_test = np.reshape(y_test, (len(y_test), 1))
if tf.keras.backend.image_data_format() == 'channels_last':
x_train = x_train.transpose(0, 2, 3, 1)
x_test = x_test.transpose(0, 2, 3, 1)
x_test = x_test.astype(x_train.dtype)
y_test = y_test.astype(y_train.dtype)
x_train, x_test = x_train / 255.0, x_test / 255.0 # 数据归一化
return (x_train, y_train), (x_test, y_test)
模型搭建
class MyCifarModel(tf.keras.Model):
'''
卷积神经网络搭建示例
搭建一层卷积 两层全连接的网络
使用6个 5*5的卷积核 过2*2 的池化核 池化步长2(5*5 conv,filters=6 2*2 pool strides=2)
过128个神经元的全连接层
最后过一个10个神经元的全连接层(因为cifar是一个10分类)
搭建神经网络的口诀是 CBAPD
C -- 卷积: 核 6*5*5 步长: 1 填充:same(使用全零填充)
B -- 批标准化: yes 使用标准化
A -- 激活函数: relu
P -- 池化: max(最大池化) 核: 2*2 池化步长: 2 填充 same
D -- 舍弃: Dropout(0.2)
Flatten: 拉直层 把卷积送过来的数据拉直
Dense: Dense(神经元 128,激活:relu, Dropout: 0.2)
Dense(神经元:10,激活: softmax)
'''
def __init__(self):
super(MyCifarModel, self).__init__()
self.c1 = tf.keras.layers.Conv2D(filters=6, kernel_size=(5, 5), padding='same') # 卷积层
self.b1 = tf.keras.layers.BatchNormalization() # BN层
self.a1 = tf.keras.layers.Activation('relu') # 激活层
self.p1 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2, padding='same') # 池化层
self.d1 = tf.keras.layers.Dropout(0.2) # dropout层
self.flatten = tf.keras.layers.Flatten()
self.f1 = tf.keras.layers.Dense(128, activation='relu')
self.d2 = tf.keras.layers.Dropout(0.2)
self.f2 = tf.keras.layers.Dense(10, activation='softmax') # softmax 使输出符合概率分布
def call(self, x):
# 使输入到输出 过一遍前向传播 返回推理结果
x = self.c1(x)
x = self.b1(x)
x = self.a1(x)
x = self.p1(x)
x = self.d1(x)
x = self.flatten(x)
x = self.f1(x)
x = self.d2(x)
y = self.f2(x)
return y
读取模型(实现断点续练):
def local_load_model(model_path):
if os.path.exists(model_path + '/saved_model.pb'):
tf.print('-------------load the model-----------------')
local_model = tf.keras.models.load_model(model_path)
else:
local_model = MyCifarModel()
local_model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
return local_model
使用
if __name__ == '__main__':
(x_train, y_train), (x_test, y_test) = get_load_cifar10()
model_path = "./data/model/breakpoint"
my_cifar_model = local_load_model(model_path)
# 电脑配置低 只训练3次
history = my_cifar_model.fit(x_train, y_train, batch_size=32, epochs=3, validation_data=(x_test, y_test),
validation_freq=1)
my_cifar_model.summary()
# 保存模型
my_cifar_model.save(model_path, save_format="tf")
完整代码如下
# -*- coding: utf-8 -*-
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.python.keras.datasets.cifar import load_batch
def get_load_cifar10():
# 获取数据 直接使用 tf.keras.datasets.cifar10.load_data() 会报错
# cifar10数据下载 参考 https://zhuanlan.zhihu.com/p/129078357
# path 为解压后的路径
path = 'D:\\Repository\\ai_data\\DeepLearing_TensorFlow2.0-book\\cifar10\\cifar-10-batches-py\\'
num_train_samples = 50000
x_train = np.empty((num_train_samples, 3, 32, 32), dtype='uint8')
y_train = np.empty((num_train_samples,), dtype='uint8')
for i in range(1, 6):
fpath = os.path.join(path, 'data_batch_' + str(i))
(x_train[(i - 1) * 10000:i * 10000, :, :, :],
y_train[(i - 1) * 10000:i * 10000]) = load_batch(fpath)
fpath = os.path.join(path, 'test_batch')
x_test, y_test = load_batch(fpath)
y_train = np.reshape(y_train, (len(y_train), 1))
y_test = np.reshape(y_test, (len(y_test), 1))
if tf.keras.backend.image_data_format() == 'channels_last':
x_train = x_train.transpose(0, 2, 3, 1)
x_test = x_test.transpose(0, 2, 3, 1)
x_test = x_test.astype(x_train.dtype)
y_test = y_test.astype(y_train.dtype)
x_train, x_test = x_train / 255.0, x_test / 255.0 # 数据归一化
return (x_train, y_train), (x_test, y_test)
'''
参考视频: https://www.bilibili.com/video/BV16A41157LW?p=34
'''
class MyCifarModel(tf.keras.Model):
'''
卷积神经网络搭建示例
搭建一层卷积 两层全连接的网络
使用6个 5*5的卷积核 过2*2 的池化核 池化步长2(5*5 conv,filters=6 2*2 pool strides=2)
过128个神经元的全连接层
最后过一个10个神经元的全连接层(因为cifar是一个10分类)
搭建神经网络的口诀是 CBAPD
C -- 卷积: 核 6*5*5 步长: 1 填充:same(使用全零填充)
B -- 批标准化: yes 使用标准化
A -- 激活函数: relu
P -- 池化: max(最大池化) 核: 2*2 池化步长: 2 填充 same
D -- 舍弃: Dropout(0.2)
Flatten: 拉直层 把卷积送过来的数据拉直
Dense: Dense(神经元 128,激活:relu, Dropout: 0.2)
Dense(神经元:10,激活: softmax)
'''
def __init__(self):
super(MyCifarModel, self).__init__()
self.c1 = tf.keras.layers.Conv2D(filters=6, kernel_size=(5, 5), padding='same') # 卷积层
self.b1 = tf.keras.layers.BatchNormalization() # BN层
self.a1 = tf.keras.layers.Activation('relu') # 激活层
self.p1 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2, padding='same') # 池化层
self.d1 = tf.keras.layers.Dropout(0.2) # dropout层
self.flatten = tf.keras.layers.Flatten()
self.f1 = tf.keras.layers.Dense(128, activation='relu')
self.d2 = tf.keras.layers.Dropout(0.2)
self.f2 = tf.keras.layers.Dense(10, activation='softmax') # softmax 使输出符合概率分布
def call(self, x):
# 使输入到输出 过一遍前向传播 返回推理结果
x = self.c1(x)
x = self.b1(x)
x = self.a1(x)
x = self.p1(x)
x = self.d1(x)
x = self.flatten(x)
x = self.f1(x)
x = self.d2(x)
y = self.f2(x)
return y
def local_load_model(model_path):
if os.path.exists(model_path + '/saved_model.pb'):
tf.print('-------------load the model-----------------')
local_model = tf.keras.models.load_model(model_path)
else:
local_model = MyCifarModel()
local_model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
return local_model
def show_train_line(history):
# 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
if __name__ == '__main__':
(x_train, y_train), (x_test, y_test) = get_load_cifar10()
model_path = "./data/model/breakpoint"
my_cifar_model = local_load_model(model_path)
history = my_cifar_model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test),
validation_freq=1)
show_train_line(history)
my_cifar_model.summary()
# 保存模型
my_cifar_model.save(model_path, save_format="tf")