欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[tensorflow2笔记七] 网络八股扩展

程序员文章站 2024-03-11 16:36:13
...

1.自制数据集,解决本领域应用

(1)数据集结构

两个包含图片的文件夹:
mnist_train_jpg_60000:60000张图片
mnist_test_jpg_10000:10000张图片

0_5.jpg,1_7.jpg等图片都是黑底白字灰度图,28x28个像素点,每个像素点都是0-255之间的整数,纯黑色0,纯白色255。

两个标签文本:
mnist_train_jpg_60000.txt
mnist_test_jpg_10000.txt

文本中有两列:图片名 标签
0_5.jpg 5
2_9.jpg 9

(2)构造函数,替换load_data(),给x_train,y_train,x_test,y_test赋值

def generateds(图片路径,标签文件)
将图片灰度值数据拼接到图片列表,把标签数据拼接到标签列表,顺序一致就可以。

(3)制作并使用数据集的demo

# 1.导入一些模块
import tensorflow as tf
from PIL import Image   # 用于打开一张图片
import numpy as np      # 用于数据格式转换
import os				# 路径

# 2.路径和存储文件
train_path = './mnist_image_label/mnist_train_jpg_60000/'       # 训练集图片路径
train_txt = './mnist_image_label/mnist_train_jpg_60000.txt'     # 训练集标签文件
x_train_savepath = './mnist_image_label/mnist_x_train.npy'      # 训练集输入特征存储文件
y_train_savepath = './mnist_image_label/mnist_y_train.npy'      # 训练集标签存储文件

test_path = './mnist_image_label/mnist_test_jpg_10000/'         # 测试集图片路径
test_txt = './mnist_image_label/mnist_test_jpg_10000.txt'       # 测试集标签文件
x_test_savepath = './mnist_image_label/mnist_x_test.npy'        # 测试集输入特征存储文件
y_test_savepath = './mnist_image_label/mnist_y_test.npy'        # 测试集标签存储文件

# 3.制作数据集的函数
def generateds(path, txt):          # 图片路径,标签文件
    f = open(txt, 'r')              # 以只读的形式打开txt
    contents = f.readlines()        # 读取文件中所有的行,每行为一个单位
    f.close()
    x, y_ = [], []
    for content in contents:                # 逐行读出
        value = content.split()             # 以空格分开
        img_path = path + value[0]
        img = Image.open(img_path)
        img = np.array(img.convert('L'))    # 图片变为8位宽度的灰度值
        img = img / 255.                    # 数据归一化
        x.append(img)
        y_.append(value[1])
        print('load:' + content)

    x = np.array(x)
    y_ = np.array(y_)
    y_ = y_.astype(np.int64)
    return x, y_

# 4.加载数据
if os.path.exists(x_train_savepath) and os.path.exists(y_train_savepath) and os.path.exists(
    x_test_savepath) and os.path.exists(y_test_savepath):   # 判断x_train,y_train,x_test,y_test是否存在
    print("----------------Load Datasets-------------")
    x_train_save = np.load(x_train_savepath)
    y_train = np.load(y_train_savepath)
    x_test_save = np.load(x_test_savepath)
    y_test = np.load(y_test_savepath)
    x_train = np.reshape(x_train_save, (len(x_train_save), 28, 28))
    x_test = np.reshape(x_test_save, (len(x_test_save), 28, 28))

else:   # 不存在,则调用generateds()函数制作数据集
    print('----------------Generate Datasets--------------')
    x_train, y_train = generateds(train_path, train_txt)
    x_test, y_test = generateds(test_path, test_txt)
	
	# 保存制作好的数据集,下次训练可以直接使用
    print('----------------Save Datasets------------------')
    x_train_save = np.reshape(x_train, (len(x_train), -1))
    x_test_save = np.reshape(x_test, (len(x_test), -1))
    np.save(x_train_savepath, x_train_save)
    np.save(y_train_savepath, y_train)
    np.save(x_test_savepath, x_test_save)
    np.save(y_test_savepath, y_test)

# 5.搭建网络
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

# 6.配置参数
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

# 7.训练
model.fit(x_train, y_train,batch_size=32,epochs=5,validation_data=(x_test, y_test),validation_freq=1)

# 8.打印网络参数
model.summary()

2.数据增强,扩充数据集

(1)理解

对图像的增强,就是对图像的简单形变,用来应对因拍照角度不同引起的图片变形。

数据增强在小数据量上可以增加模型泛化性。

(2)函数

# 1.设置数据增强参数
image_gen_train = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=所有数据乘以该数值
    rotation_range=随机旋转角度数范围
    width_shift_range=随机宽度偏移量
    height_shift_range=随机高度偏移量
    horizontal_flip=是否随机水平翻转
    zoom_range=随机缩放的范围[1-n, 1+n]
)
# 2.对输入特征进行数据增强
x_train = x_train.reshape(x_train.shape[0], 28, 28 ,1) # 增加一个维度,使数据与网络结构匹配
image_gen_train.fit(x_train)		# 此处的x_train要输入一个四维数据

# 3.变动model.fit
# 将x_train,y_train,batch打包,其余相同
model.fit(image_gen_train.flow(x_train,y_train,batch=32),...)

例子:

image_gen_train = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1. / 1.,          # 如果是图像,分母为255,可以归一化到0-1
    rotation_range=45,        # 随机45度旋转
    width_shift_range=.15,    # 宽度偏移
    height_shift_range=.15,   # 高度偏移
    horizontal_flip=False,    # 水平翻转
    zoom_range=0.5            # 将图像随机缩放阈量50%
)

3.断点续训,存取模型

(1)读取模型:model.load_weights(路径文件名)

checkpoint_save_path = "./mnist.ckpt"				# 定义存放模型的路径和文件名
if os.path.exists(checkpoint_save_path + '.index'):	# 判断是否有索引表 因为生成ckpt文件时,会同步生成索引表
	print('--------load the model---------')
	model.load_weights(checkpoint_save_path)

(2)保存模型:使用回调函数

# 1.设置保存方法
cp_callback = tf.keras.callbacks.ModelCheckpoint(
	filepath=路径文件名,
	save_weights_only=True/False 		# 是否只保留模型参数
	save_best_only=True/False# 是否只保留最有结果
	
# 2.训练时加入callbacks选项,记录到history中
history = model.fit(...,callbacks=[cp_callback])

4.参数提取,把参数存入文本

(1)理解:将模型的参数保存在文本中。

(2)函数:model.trainable_variables可以返回模型中可训练的参数,使用print函数打印出来。

但是,直接print中间很多数据会被省略号代替,所以要设置print输出格式。

np.set_printoptions(threshold=超出多少省略显示)

例子:

# 1.设置print格式
import numpy as np
np.set_printoptions(threshold=np.inf) 		# np.inf表示无限大,打印所有内容

# 2.打印参数
print(model.trainable_variables)

# 3.将参数写入文本
file = open('./weights.txt', 'w')
for v in model.trainable_variables:
	file.write(str(v.name) + '\n')
	file.write(str(v.shape) + '\n')
	file.write(str(v.numpy()) + '\n')
file.close()

5.acc/loss可视化,查看训练效果

(1)说明:

history = model.fit()。其实,在执行训练过程中,同步记录了
训练集loss(loss)、
测试集loss(val_loss)、
训练集准确率(sparse_categorical_accuracy)、
测试集准确率(val_sparse_categorical_accuracy)。

可以使用history.history[]提取出来。

(2)方法:

# 提取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']

# 绘制acc和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()

6.应用程序,给图识物

(1)说明:编写一个前向传播算法,使用训练好的模型,将输入图片识别出来。

(2)函数:predict(输入特征,batch_size=整数),可以返回前向传播的计算结果。

(3)程序

# 1.复现模型(前向传播)
model = tf.keras.models.Sequential([
	tf.keras.layers.Flatten(),
	tf.keras.layers.Dense(128,activation='relu'),
	tf.keras.layers.Dense(10,activation='softmax')
])

# 2.加载参数
model.load_weights(model_save_path)

# 3.预测结果
result = model.predict(x_predict)