预测本地图片
import tensorflow as tf
import numpy as np
import os
from PIL import Image as im
train_path = 'D:\python 文件\项目\数据集\class4\class4\MNIST_FC\mnist_image_label\mnist_train_jpg_60000\\'
train_txt = 'D:\python 文件\项目\数据集\class4\class4\MNIST_FC\mnist_image_label\mnist_train_jpg_60000.txt'
x_train_savepath = './mnist_x_train.npy'
y_train_savepath = './mnist_y_train.npy'
test_path = 'D:\python 文件\项目\数据集\class4\class4\MNIST_FC\mnist_image_label\mnist_test_jpg_10000\\'
test_txt = 'D:\python 文件\项目\数据集\class4\class4\MNIST_FC\mnist_image_label\mnist_test_jpg_10000.txt'
x_test_savepath = './mnist_x_test.npy'
y_test_savepath = './mnist_t_test.npy'
# 定义自制数据集函数
def generateds(path,txt):
with open(txt, "r") as f:
contents = f.readlines()
# 定义两个空列表,记录特征和标签
train_features = []
train_labels = []
# 逐行取出
for content in contents:
value = content.split() # 按空格进行切分
img_path = path + value[0] # 拼出图片完整路径
img = im.open(img_path)
img = np.array(img.convert("L")) # 将图片变为8位宽灰度值的array格式
img = img/255 # 归一化
train_features.append(img) # 将图片保存到列表中
train_labels.append(value[1]) # 将标签保存到列表中
train_features = np.array(train_features) # 将特征列表转换位array型
train_labels = np.array(train_labels) # 将标签列表转化为array型
train_labels = train_labels.astype(np.int64) # 转换数据类型
return train_features, train_labels
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):
print("--------------Load Datasets------------------")
x_train = np.load(x_train_savepath)
y_train = np.load(y_train_savepath)
x_test = np.load(x_test_savepath)
y_test = np.load(y_test_savepath)
print(x_train.dtype)
else:
print("--------------Generateds Datasets----------------")
x_train, y_train = generateds(train_path, train_txt)
x_test, y_test = generateds(test_path, test_txt)
print("---------------Save Datasets----------------")
np.save(x_train_savepath, x_train)
np.save(y_train_savepath, y_train)
np.save(x_test_savepath, x_test)
np.save(y_test_savepath, y_test)
generateds(train_path,train_txt)
# 搭建网络结构
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
# 配置网络
model.compile(
optimizer=tf.optimizers.Adam(),
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["sparse_categorical_accuracy"]
)
# 训练数据
model.fit(x_train, y_train, batch_size=32, epochs=10, validation_data=(x_test, y_test), validation_freq=2)
# 统计信息
model.summary()
数据增强可以扩展数据集,对图片的增强就是对图像的简单形变,用来解决因拍照或其它因素造成的图片形变。
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]
)
image_gen_train.fit(x_train),这里的fit需要输入一个四维数据,所以需要对x_train进行reshape,
x_train = x_train.reshape(x_train.shape[0],28,28,1)
其中,1代表单通道,是灰度值
# 将训练集标签,特征,batch打包送入fit进行训练
model.fit(image_gen_train.flow(x_train,y_train,batch_size=32),...)
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
fashion = tf.keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion.load_data()
x_train = x_train/255
y_test = y_test/255
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) # 给数据增加一个维度,使数据和网络结构匹配
# 数据增强
image_gen_train = ImageDataGenerator(
rescale=1, # 将每个数除以1
rotation_range=45, # 随机45度旋转
width_shift_range=15, # 宽度偏移
height_shift_range=15, # 高度偏移
horizontal_flip=True, # 水平翻转
zoom_range=0.5, # 将图像随机缩放阈值50%
)
image_gen_train.fit(x_train)
# 搭建网络
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
# 配置网络
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["sparse_categorical_accuracy"]
)
# 训练
model.fit(image_gen_train.flow(x_train, y_train, batch_size=32), epochs=10, validation_data=(x_test, y_test), validation_freq=2)
# 查看信息
model.summary()
fashion数据集是经过处理的,所以无法明显的看到效果,但在实际生活中,数据增强往往能起到很大的作用。
三:断点续训,存取模型
读取模型
load_weights(路劲文件名)
保存模型
cp_callback = tf.keras.callback.ModelCheckpoint(
filepath=路径文件名,
save_weights_only = True/False, # 是否只保留模型参数
save_best_only = True/False, # 是否只保留最优结果
)
在已有模型上训练
在fit()中加入callbacks参数,记录到history中
history = model.fit(…,callbacks=[cp_callback])
代码实现
import tensorflow as tf
import os
from tensorflow.keras.datasets import fashion_mnist
# 读取数据
(x_train,y_train), (x_test,y_test) = fashion_mnist.load_data()
# 数据归一化
x_train, x_test = x_train/255, x_test/255
# 定义网络结构
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
# 配置训练方法
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["sparse_categorical_accuracy"]
)
# 定义模型保存地址
checkpoint_save_path = './checkpoint/mnist.ckpt'
# 判断档期那是否存在模型
if os.path.exists(checkpoint_save_path + '.index'):
print("----------------- load the model -----------------")
model.load_weights(checkpoint_save_path)
# 创建模型
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True
)
# 在已有模型基础上训练
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1, callbacks=[cp_callback])
# 查看网络结构及数据统计
model.summary()
四:参数提取
model.trainable_variables,返回模型中可训练的参数
np.set_printoptions(threshold=超过多少省略显示)
例:np.set_printoptions(threshold=np.inf),其中np.inf表示无限大
import tensorflow as tf
import numpy as np
import os
from tensorflow.keras.datasets import fashion_mnist
np.set_printoptions(threshold=np.inf)
# 读取数据
(x_train,y_train), (x_test,y_test) = fashion_mnist.load_data()
# 数据归一化
x_train, x_test = x_train/255, x_test/255
# 定义网络结构
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
# 配置训练方法
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["sparse_categorical_accuracy"]
)
# 定义模型保存地址
checkpoint_save_path = './checkpoint/mnist.ckpt'
# 判断档期那是否存在模型
if os.path.exists(checkpoint_save_path + '.index'):
print("----------------- load the model -----------------")
model.load_weights(checkpoint_save_path)
# 创建模型
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True
)
# 在已有模型基础上训练
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1, callbacks=[cp_callback])
# 查看网络结构及数据统计
model.summary()
# 参数提取
print(model.trainable_variables)
with open(r"./weight.txt","w") as f:
for v in model.trainable_variables:
f.write(str(v.name) + "\n")
f.write(str(v.shape) + "\n")
f.write(str(v.numpy()) + "\n")
五:loss/acc可视化
fit()后的结果包含以下几部分:
可以用fit().history(参数)提取出来
import tensorflow as tf
import numpy as np
import os
from matplotlib import pyplot as plt
from tensorflow.keras.datasets import fashion_mnist
np.set_printoptions(threshold=np.inf)
# 读取数据
(x_train,y_train), (x_test,y_test) = fashion_mnist.load_data()
# 数据归一化
x_train, x_test = x_train/255, x_test/255
# 定义网络结构
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(120, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
# 配置训练方法
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=["sparse_categorical_accuracy"]
)
# 定义模型保存地址
checkpoint_save_path = './checkpoint/mnist.ckpt'
# 判断档期那是否存在模型
if os.path.exists(checkpoint_save_path + '.index'):
print("----------------- load the model -----------------")
model.load_weights(checkpoint_save_path)
# 创建模型
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True
)
# 在已有模型基础上训练
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1, callbacks=[cp_callback])
# 查看网络结构及数据统计
model.summary()
# 参数提取
print(model.trainable_variables)
with open(r"./weight.txt","w") as f:
for v in model.trainable_variables:
f.write(str(v.name) + "\n")
f.write(str(v.shape) + "\n")
f.write(str(v.numpy()) + "\n")
# 提取数据
acc = history.history["sparse_categorical_accuracy"]
val_acc = history.history["val_sparse_categorical_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
# loss/acc绘图
plt.subplot(1, 2, 1)
plt.plot(acc, label="Training Auccary")
plt.plot(val_acc, label="Validation Accuracy")
plt.title("Training And Validation Accuracy")
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(loss, label="Loss")
plt.plot(val_acc, label="Validation Loss")
plt.title("Training And Validation Loss")
plt.legend()
plt.show()
图示如下:
六:绘图识物
运用模型识别手写数字
predict(输入特征,batch_size=整数)
import tensorflow as tf
import numpy as np
from PIL import Image as im
model_path = "./checkpoint/mnist.ckpt"
img_pre_path = "D:\python 文件\项目\数据集\class4\class4\MNIST_FC\\"
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax")
])
model.load_weights(model_path)
preNum = int(input("请输入预测图片的数量:"))
for i in range(preNum):
img_name = input("请输入要预测图片的名字:")
img_path = img_pre_path + img_name
img = im.open(img_path)
img = img.resize((28, 28), im.ANTIALIAS)
img_arr = np.array(img.convert("L"))
img_arr = 255 - img_arr
img_arr = img_arr / 255
x_predict = img_arr[tf.newaxis, ...] # 使输入的维度和神经网络的维度相匹配
result = model.predict(x_predict)
pred = tf.argmax(result, axis=1)
tf.print(pred)