看代码吧,很详细了
1.GPS_Model.py
"""
生成训练模型
"""
import tensorflow as tf
# 定义模型
class GPSNet(object):
def __init__(self):
self.layer = tf.keras.layers # 此时定义一个空壳
self.models = tf.keras.models # 准备一个空的模型
self.input_shape = (32, 32, 3)
self.classes = 21
self.model = self.GPS_Net()
def GPS_Net(self):
# 定义输入节点 创建输入层
# 指定输入shape为 32 x 32的一个大小,而且 颜色rgb为3个通道
img_input = self.layer.Input(shape=self.input_shape)
# 填充入卷积层
x = self.layer.Conv2D(64, # 64个卷积来扫描图片
(5, 5), # 卷积尺寸为5 x 5
activation='relu', # 设置relu激活函数来加快训练速度和克服梯度消失
padding='valid', # 设置填充方式为有效填充
name='conv1')(img_input) # 传入图片模型
# 填充入BN层 类似池化层,可以进行泛化和提高拟合
x = self.layer.BatchNormalization()(x)
# 填充池化层 把输入的尺寸变小降低计算,调高效率,提高抗拟合
x = self.layer.AveragePooling2D()(x)
# 开始循环扩充神经网络。
x = self.layer.Conv2D(256, (3, 3), activation='relu', padding='valid', name='conv1')(img_input)
x = self.layer.AveragePooling2D()(x)
x = self.layer.Conv2D(128, (3, 3), activation='relu', padding='valid', name='conv1')(img_input)
x = self.layer.BatchNormalization()(x)
x = self.layer.AveragePooling2D()(x)
# 将层拉平 将二维数据转化为一维
x = self.layer.Flatten()(x)
# 指定两个全连接层
x = self.layer.Dense(512, activation='relu', name='fc1')(x)
x = self.layer.BatchNormalization()(x)
x = self.layer.Dense(128, activation='relu', name='fc2')(x)
x = self.layer.BatchNormalization()(x)
# 指定输出层 激活函数softmax将多个神经元的输出,映射到(0,1)区间内。 uc_merced分类数为21
x = self.layer.Dense(self.classes, activation='softmax', name='predictions')(x)
inputs, outputs = img_input, x
# 指定输入和输出生成训练模型
return self.models.Model(inputs, outputs, name='GPS_Net')
2.GPSAugment.py
"""
数据增强
"""
import tensorflow as tf
import numpy as np
# 数据增强
def tf_rotate(img):
"""
TensorFlow对图像进行随机旋转
:param img: 图像输入
:return: 旋转后的图像
"""
angle = np.random.choice(['up_down' 'up_down_left_right', 'left_right', 'none'])
print(angle)
if angle == 'up_down':
img = tf.image.flip_up_down(img)
elif angle == 'up_down_left_right':
# 水平垂直翻转
img = tf.image.flip_left_right(img)
img = tf.image.flip_up_down(img)
elif angle == 'left_right':
# 水平翻转
img = tf.image.flip_left_right(img)
elif angle == 'none':
pass
return img
# 进行数据标准化
def convert(image, label):
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, size=[32, 32]) # 强制图片大小到统一格式
return image, label
# 数据增强
def augment(image, label):
image, label = convert(image, label)
image = tf_rotate(image)
# 图片的明暗度
image = tf.image.random_brightness(image, max_delta=0.5) # Random brightness
# 随机设置图片的对比度
image = tf.image.random_contrast(image, lower=0.2, upper=1.8)
# 随机设置图片的色度
image = tf.image.random_hue(image, max_delta=0.3)
# 随机设置图片的饱和度
image = tf.image.random_saturation(image, lower=0.2, upper=1.8)
return image, label
3.GPSModelTrain.py
"""
模型训练
"""
import tensorflow_datasets as tfds
import time
import os
import tensorflow as tf
from GPSAugment import augment
from GPS_Model import GPSNet
GPS = GPSNet()
model = GPS.model
# 首先记录模型训练日志
base_dir = os.path.abspath(os.path.dirname(__file__)) + os.sep
log_dir = base_dir + 'logs'
# 训练结构命令 tensorboard --logdir=path
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
raw_train, metadata = tfds.load(
'uc_merced', # 指定tfds数据集名称
split=['train'], # 指定为训练数据
with_info=True, # 这个参数指定输出为tuple的形式返回(tf.data.Dataset, tfds.core.DatasetInfo)
as_supervised=True, # 此参数指定以tuple的形式返回(input,label)
shuffle_files=True, # 对数据进行随机打乱
data_dir=base_dir + 'tensorflow_datasets'
)
# 指定一次训练数据为16个
BATCH_SIZE = 16
# 设定缓存
SHUFFLE_BUFFER_SIZE = 2520
# 从训练集里读取随机数据
train_batches = raw_train[0].shuffle(SHUFFLE_BUFFER_SIZE, # 每次读取16个
# 是否按顺序执行随机排序,保证每一次随机都能将图片信息全部读取一遍
reshuffle_each_iteration=True
).map(augment).batch(BATCH_SIZE).prefetch(tf.data.experimental.AUTOTUNE)
# 对模型进行训练
model.compile(
# 指定学习策略<优化器> Adam学习策略。 根据惯性和参数变化寻找到最优点
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),
# 指定损失函数 交叉熵损失函数
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
# 训练的时候打印正确信息
metrics=['accuracy']
)
# 训练数据
model.fit(
train_batches,
# 指定需要训练几个阶段
epochs=50,
# 回调可视化
callbacks=[tensorboard_callback]
)
# 保存数据
keras_file = base_dir + time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime()) + '-test.h5'
tf.keras.models.save_model(model=model,
filepath=keras_file,
# If True, 和优化器的状态一起保存,这里设置False
include_optimizer=False)
4.GPSTest.py
"""
数据测试
"""
import numpy as np
import tensorflow_datasets as tfds # 这个是之前说过的Tensorflow Datasets
import os
import matplotlib.pyplot as plt
from GPSAugment import convert
from GPS_Model import GPSNet
GPS = GPSNet()
model = GPS.model
raw_train, metadata = tfds.load(
'uc_merced',
split=['train'],
with_info=True,
as_supervised=True,
shuffle_files=True,
data_dir=os.path.abspath(os.path.dirname(__file__)) + os.sep + 'tensorflow_datasets')
# 加载保存的模型
model.load_weights(os.path.abspath(os.path.dirname(__file__)) + os.sep + "2020-11-04-13_01_15-test.h5")
# 训练后的模型预测展示
get_label_name = metadata.features['label'].int2str
# 测试阶段
for image, label in raw_train[0].take(20):
image, labels = convert(image, label) # 将图片标准化
predict = np.argmax(model.predict(np.expand_dims(image, axis=0))) # 预测
# 画图
plt.figure()
plt.imshow(image)
plt.title(get_label_name(predict))
plt.show()