实验代码:提取码-6666
初始化神经网络模型:model = tf.models.Sequential([网络结构])
拉直层:tf.keras.layers.Flatten()
全连接层:tf.keras.layers.Dense(神经元个数,activation='激活函数',kernel_regularizer=正则化方式)
acitivation(以字符串给出):‘relu’,‘softmax’,‘sigmoid’
kernel_regularize:tf.keras.regulizers.l1()
,tf.keras.regulizers.l2()
卷积层:tf.keras.layers.Conv2D(filters=卷积核个数,kernel_size=卷积核尺寸,strides=卷积核步长,padding="valid"/"same")
LSTM:tf.keras.layers.LSTM()
在初始化神经网络模型之后需要添加优化模型参数的基本配置如分类器,损失函数等:model.compile(optimizer=${优化器},losses=${损失函数},metrics=[‘准确率’])
SGD优化器:‘sgd’ 或者
tf.keras.optimizers.SGD(lr=${学习率},momentum=${动量参数})
Adagrad优化器:‘adagrad’ 或者tf.keras.optimizers.Adagrad(lr=${学习率})
Adadelta优化器:‘adadelta’ 或者tf.keras.optimizers.Adadelta(lr=${学习率})
SGD优化器:‘adam’ 或者tf.keras.optimizers.Adam(beta_1=0.9,beta_2=0.999)
均方差损失函数(MSE):‘mse’ 或者
tf.keras.MeanSquareError()
交叉熵损失函数(CrossEntropy):‘sparse_categorical_crossentropy’ 或者tf.keras.SparseCategoricalCrossentropy(from_logits=False)
‘accuracy’: y _ y\_ y_与 y y y都是数值,如: y _ = [ 1 ] , y = [ 1 ] y\_=[1],y=[1] y_=[1],y=[1]
‘categorical_accuracy’: y _ y\_ y_与 y y y都是独热编码,如: y _ = [ 0 , 1 , 0 ] , y = [ 0.256 , 0.695 , 0.048 ] y\_=[0,1,0],y=[0.256,0.695,0.048] y_=[0,1,0],y=[0.256,0.695,0.048]
‘sparse_categorical_accuracy’: y _ y\_ y_是数值, y y y都是独热码,如: y _ = [ 1 ] , y = [ 0.256 , 0.695 , 0.048 ] y\_=[1],y=[0.256,0.695,0.048] y_=[1],y=[0.256,0.695,0.048]
model.summary()
model.fit(${训练集输入特征},${训练集标签},batch_size,epochs,validation_data=(${测试集输入特征},${测试集的标签}),validation_split=${从训练集划分多少比例给测试集},validation_freq=${多少次epoch测试一次})
由于Sequential型只适用于上层输出就是上层的顺序,无法写出一些带跳连的非顺序网络结构,因此用一个类进行封装一方面可以使模型更加简介明了,也增加了模型可执行性
采用类封装神经网络如下模板:
class MyModel(Model):
## 定义所需网络结构模块
def __init__(self):
super(MyModel,self).__init__()
# 定义网络模块
def call(self,x):
# 调用网络结构快,实现前向传播
out=""
return out;
【例1】:我们以 MNIST 手写数据集为例子来尝试搭建入门级神经网络
导入基本的第三方库
import tensorflow as tf
from tensorflow.keras import Model
import matplotlib.pyplot as plt
import numpy as np
将神经网络封装成一个类,并将模型初始化
## 将神经网络模型封装成为一个类
class MnistModel(Model):
def __init__(self):
super(MnistModel,self).__init__()
self.dl = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
def call(self,x):
out = self.dl(x)
return out
# 初始化模型
model = MnistModel()
加载MNIST数据集,并将训练集和测试集的特征进行归一化
# 加载MNIST手写数据集
mnist = tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
# 将训练集数据进行随机打乱
np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)
# 训练集和测试集特征归一化
x_train,x_test = x_train/255.,x_test/255.
加载模型训练时的基本配置(如:优化器,损失函数等)
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
训练模型
model.fit(x_train,y_train,
batch_size=32,epochs=5,
validation_data=[x_test,y_test],
validation_freq=1)
model.summary()
观察数据集数据结构,给x_train
,y_train
,x_test
,y_test
赋值,随后定义函数def generateDatasets(${图片路径},${标签文件})
def generateDatasets(path,txt):
f = open(txt,'r')
contents = f.readlines()
f.close()
## 存放数据集特X与标签Y
x,y_=[],[]
for content in contents:
# 以空格为分割依据分割为value[0]:数据集文件名 + value[1]:标签
value = content.split()
# 获取图片保存所在路径,并将图片读取出来
img_path = path + value[0]
img = Image.open(img_path)
# 将图片转换成灰度图像,并将数据归一化
img = np.array(img.convert('L'))
img = img/255.
x.append(img)
y_.append(value[1])
print('loading:'+content)
# 数据集制作成功
x = np.array(x)
y_ = np.array(y_)
y = y.astype(np.int64)
return x,y_
【例2】:将图片数据转换成需要的满足tensorflow训练的数据集
导入第三方库(不需要多说)
import tensorflow as tf
from PIL import Image
import numpy as np
import os
设置数据集存放的位置
## 数据的路径名
# 训练集(原始数据)存放的文件夹
train_path = './mnist_image_label/mnist_train_jpg_60000/'
# 训练集(原始数据文件名 + 标签)构成的txt文档
train_txt = './mnist_image_label/mnist_train_jpg_60000.txt'
# 训练集特征X和标签y分别转成.npy数据格式,所存放的位置
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_train_jpg_60000/'
# 训练集(原始数据文件名 + 标签)构成的txt文档
test_txt = './mnist_image_label/mnist_test_jpg_10000.txt'
# 训练集特征X和标签y分别转成.npy数据格式,所存放的位置
x_test_savepath = './mnist_image_label/mnist_x_test.npy'
y_test_savepath = './mnist_image_label/mnist_y_test.npy'
加载数据
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):
## 判断.npy文件是否存在,如果存在直接加载
print('--------------------- Load Datasets ---------------------')
# 加载.npy文件
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:
## 反之调用generateDatasets函数,先把图片数据转成指定的格式,并将数据转换成.npy文件,以便下次使用
print('--------------------- Generate Datasets ---------------------')
x_train,y_train = generateDatasets(train_path,train_txt)
x_test,y_test = generateDatasets(test_path,test_txt)
# 转成.npy文件
print('--------------------- Load 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)
模型搭建 + 常规训练
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
model.fit(x_train,y_train,batch_size=32,epochs=5,validation_data=(x_test,y_test),validation_freq=1)
model.summary()
数据增强的目的是帮助扩展数据集,即对图像的简单形变,用来应对因拍照角度不同引起的图片变形,如下代码就是一个模板:
image_gen_train = tf.keras.preprocessing.image.ImageDataGenerator(
rescale='${所有数据将乘以该数值}',
rotation_range='${随机宽度偏移量}',
width_shift_range='${随机高度偏移量}',
horizontal_filp='${是否水平旋转}'
zoom_range=随机缩放的范围'${[1-n,1+n]}')
image_gen_train.fit(x_train)
【例3】:将图片增强后训练模型
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_test = x_train/255.,x_test/255.
x_train=x_train.reshape(x_train.shape[0],28,28,1)
## 数据增强
image_gen_train = ImageDataGenerator(
rescale=1./1., #如为图像,分母为255时,可归一化
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(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='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=5,validation_data=(x_test,y_test),validation_freq=1)
model.summary()
读取模型:load_weights('${文件路径名}')
,代码样例
checkpoint_save_path = "./checkpoint/MnistModel.ckpt"
if os.path.exists(checkpoint_save_path + 'index'):
print("-------- load the model -----------")
model.load_weights(checkpoint_save_path)
保存模型:
tf.keras.callbacks.ModelCheckpoint(filepath='${路径文件名}',save_weights_only=True/False,save_best_only=True/False)
history=model.fit(...,...,callbacks=[cp_callback])
【例4】:跟踪训练模型参数,并保存模型参数
import tensorflow as tf
import os
mnist = tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
x_train,x_test = x_train/255.,x_test/255.
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='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
(返回模型中可训练的参数)
设置print输出格式:np.set_printoptions(threshold='${超过多少省略提示}')
【例5】:基于【例4】保存的模型我们将模型参数打印下来
import numpy as np
np.set_printoptions(threshold=np.inf) # 打印全部内容
print(model.trainable_variables)
file = open('./weight.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()
【例6】:将模型训练的过程(模型在训练集/测试集中的精度/损失函数)
import matplotlib.pyplot as plt
# 训练集的准确率
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.legend()
plt.subplot(1,2,2)
plt.plot(loss,label='Training Loss')
plt.plot(val_loss,label='Validation Loss')
plt.legend()
plt.show()
案例说明:给出了一组手写数据集,我们用基于MNIST手写数据集训练好的模型来预测这一组数据;
基于以下程序,实现了预测手写数字的案例:
from PIL import Image
import numpy as np
import tensorflow as tf
model_save_path = './checkpoint/mnist.ckpt'
# 初始化模型
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
# 初始化模型,并加载已经训练好的模型参数
model.load_weights(model_save_path)
preNum = int(input("Input the number of test pictures:"))
for i in range(preNum):
image_path = input("the path of picture:")
img = Image.open(image_path)
img = img.resize((28,28),Image.ANTIALIAS)
img_arr = np.array(img.convert('L'))
# 将输入的图片进行灰度处理,下面的操作目的是减少图片噪声污染,提高模型预测的准确度
for i in range(28):
for j in range(28):
if img_arr[i][j]<200:
img_arr[i][j] = 255
else:
img_arr[i][j] = 0
img_arr = img_arr / 255.0
# 加载图片,并调用模型预测
x_predict = img_arr[tf.newaxis, ...]
result = model.predict(x_predict)
pred = tf.argmax(result,axis=1)
tf.print(pred)