Python高级编程(深度学习)02-基础
标题例子:MINIST手写数字识别
任务:使用MNIST数据集训练一个神经网络,使其能够识别手写数字。
MNIST数据集包含:
60,000张图片,包含0~9的数字
每张图片为28*28的灰度图像(单通道)
import cv2
import numpy as np
import tensorflow as tf
#import keras
from PIL import Image
from PIL.Image import ANTIALIAS
from tensorflow import keras
#from keras import layers
from tensorflow.keras import layers
from tensorflow.python.keras.models import load_model
def load_mnist(): #读取离线的MNIST.npz文件。
path = r'mnist.npz' #放置mnist.py的目录,这里默认跟本代码在同一个文件夹之下。
f = np.load(path)
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
(train_image,train_label),(test_image,test_label) = load_mnist()
print(train_image.shape)
print(train_label.shape)
#将image映射为784维向量,并映射为[0,1]之间的浮点数
train_image = train_image.reshape([60000,784])
test_image = test_image.reshape([10000,784])
train_image = train_image.astype("float32") / 255
test_image = test_image.astype("float32") / 255
#将label映射为one-hot-key的形式
num_classes = 10
train_label = keras.utils.to_categorical(train_label, num_classes)
test_label = keras.utils.to_categorical(test_label, num_classes)
#构建模型
model = keras.Sequential(
[
keras.Input(shape=(784,)), #这里(784,)的意思是784维向量构成的batch,省略的是batch的大小
layers.Dense(10, activation="relu"),
#layers.Dense(10, activation="relu"),
#layers.Dense(10, activation="relu"),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
#模型训练和测试
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="logs")
model.fit(x=train_image, y=train_label, batch_size=32, epochs=10, validation_data=(test_image, test_label), verbose=2, callbacks=[tensorboard_callback])
score = model.evaluate(test_image, test_label, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
model.save('model.h5')
# 加载待预测数据
def load_data():
pre_x = []
image = Image.open(r'C:\Users\Administrator.WIN-BE456U10DAB\Desktop\大三上\Python高级编程\Python高级编程代码\3.png')
L = image.convert("L")
#对图片进行二值化处理
L = L.convert("1")
# print(L)
#将图片大小进行修改
resize_img = L.resize((784,784),Image.ANTIALIAS)
print(resize_img)
image_arr = np.array(resize_img)
pre_x.append(image_arr)
return pre_x
pre_x = load_data()
print(pre_x)
# 通过模型预测结果并输出
predict = model.predict(pre_x)
print(predict)
#获取最大值输出
predict = np.argmax(predict,1)
print("模型预测的结果为: "+str(predict))
print(np.bincount(predict))
print("模型预测图片概率最高的结果为:\n")
print(+np.argmax(np.bincount(predict)))
以上的代码在跑的过程中由于cpu和电脑性能的不同,结果可能也会有不同,所以为了提高代码的性能和后期的准确率,可以通过修改两个参数进行提高。batch_size可以增加, epochs迭代次数也可以适应增加
作业1:predict
- 写一个程序,利用刚才训练好的模型,对一张用户输入的手写数字图片进行预测。
实验思路:
- 使用tf.keras.models.load_model()方法载入预训练模型。
- 使用PIL库读取图片,并做一定的预处理。
- 使用model.predict()方法进行预测,得到一组概率。 选择概率最高的那一项,输出。
- 参考Keras官网:https://keras.io/api/
第一步 使用load_model()方法载入训练模型,对头文件要求较高,所以我直接在上面的代码块中进行运行,就少了这一步。
第二步 使用PIL库读取图片,进行两步的预处理。建立一个load_data(),读取和处理图片数据。
第三步 model.predict()方法进行预测。
第四步 输出
# 加载待预测数据
def load_data():
pre_x = []
image = Image.open(r'数据的绝对路径')
L = image.convert("L")
#对图片进行二值化处理
L = L.convert("1")
# print(L)
#将图片大小进行修改
resize_img = L.resize((28,28),Image.ANTIALIAS)
print(resize_img)
image_arr = np.array(resize_img)
pre_x.append(image_arr)
return pre_x
pre_x = load_data()
print(pre_x)
# 通过模型预测结果并输出
predict = model.predict(pre_x)
print(predict)
#获取最大值输出
predict = np.argmax(predict,1)
print("模型预测的结果为: "+str(predict))
print(np.bincount(predict))
print("模型预测图片概率最高的结果为:\n")
print(+np.argmax(np.bincount(predict)))