(1)tf.Variable()
标记训练网络中的参数,如W,将变量标记为”可训练“,神经网络训练中,常用该函数标记待训练参数
w=tf.Variable(tf.random.normal([2,2],mean=0,stddev=1))
#标记w为待训练参数,初始化生成两行两列的正态分布的随机数,均值为0,标准差为1
(2)tf.matmul ,矩阵乘
(3)tf.data.Dataset.from_tensor_slices,切分传入张量的第一维度,生成输入特征与标签对,构建数据集
data=tf.data.Dataset.from_tensor_slices((输入特征,标签)) #numpy和Tensor格式均可用
(4)tf.GradientTape(),求梯度
with tf.GradientTape() as tape: #with结构记录计算过程,gradient求张量梯度
若干个计算过程
grad=tape.gradient(函数,求导对象)
eg:with tf.GradientTape( ) as tape:
w = tf.Variable(tf.constant(3.0))
loss = tf.pow(w,2)
grad = tape.gradient(loss,w) #对w求偏导
(5)enumerate(列表),枚举函数,常在for循环中使用
for i, element in enumerate(seq)
(6)tf.one_hot,独热码,在分类问题中,常用独热码做标签,标记类别:1表示是,0表示非
(7)tf.nn.softmax,分类函数,使输出符合概率分布
(8)assign_sub,赋值操作,更新参数的值并返回,如更新w
w = tf.Variable(4)
w.assign_sub(1) #w自减1
(9)tf.argmax(张量名,axis=操作轴),返回张量沿指定维度最大值的索引
(10)tf.where(条件语句,真返回A,假返回B)
(11)np.random.RandomState.rand(维度),返回一个[0,1)之间的随机数
(12)np.vstack(数组1,数组2),将两个数组按垂直方向叠加
(1)指数衰减学习率
(2)正则化:在损失函数中引入模型复杂度指标,利用给W加权值,弱化训练数据的噪声
正则化可以缓解过拟合
用Tensorflow API:tf.keras搭建网络八股
(1)import相关模块
(2)train,test:喂入训练集,测试集特征及标签
(3)model=tf.keras.models.Sequential:搭建网络结构(顺序网络结构)
model=tf.keras.models.Sequential([网络结构])#描述各层网络
网络结构:
tf.keras.layers.Flatten() #展平层
tf.keras.layers.Dense(神经元个数, activation= “激活函数“ ,kernel_regularizer=哪种正则化) #全连接层
tf.keras.layers.Conv2D(filters = 卷积核个数, kernel_size = 卷积核尺寸,strides = 卷积步长, padding = " valid” or “same”) #卷积层
tf.keras.layers.LSTM()#循环神经网络
(4)model.compile:配置训练方法,如优化器,损失函数,优化指标
model.compile(optimizer = 优化器,loss = 损失函数,metrics = [“准确率”] )
metrics:网络评测指标
‘accuracy’ :y_和y都是数值,如y_=[1] y=[1]
‘categorical_accuracy’ :y_和y都是独热码(概率分布),如y_=[0,1,0] y=[0.256,0.695,0.048]
‘sparse_categorical_accuracy’ :y_是数值,y是独热码(概率分布),如y_=[1] y=[0.256,0.695,0.048]
(5)model.fit:执行训练过程,训练集特征及标签,batch,epoch
model.fit (训练集的输入特征, 训练集的标签, batch_size= , epochs= , validation_data=(测试集的输入特征,测试集的标签),validation_split=从训练集划分多少比例给测试集,validation_freq = 多少次epoch测试一次)#_data和_split二选一
(6)model.summary:打印网络参数结构和参数统计
搭建跳层网络结构 class替换Sequential
class MyModel(Model): #Model,继承Tensorflow里的Model类
def init(self):
super(MyModel, self).init()
定义网络结构块
def call(self, x):
调用网络结构块,实现前向传播
return y
model = MyModel()
(1)自制数据集
import tensorflow as tf
from PIL import Image
import numpy as np
import os
#制作数据集
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'
def generateds(图片路径/path,标签文件/txt):
f = open(txt,'r') #打开标签文件,只读
contents = f.readlines() #读取整个文件所有行,保存在contents列表中,每行作为一个元素
f.close()
x,y_ = [],[]
for content in contents:#逐行取出
value = content.split() #以空格分割,图片路径为value[0],标签路径为value[1],存入列表
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_
#判断数据集路径是否存在
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_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)) #—1表示行数自动计算
x_test_save = np.reshape(x_test, (len(x_test), -1))
np.save(x_train_savepath, x_train_save) #保存路径为x_train_savepath,保存为npy文件
np.save(y_train_savepath, y_train)
np.save(x_test_savepath, x_test_save)
np.save(y_test_savepath, y_test)
(2)数据增强,扩充数据集
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) # 给数据增加一个维度,从(60000, 28, 28)reshape为(60000, 28, 28, 1)
image_gen_train = 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%
)
image_gen_train.fit(x_train) #对x_train做数据增强
model.fit(image_gen_train.flow(x_train, y_train, batch_size=32), epochs=5, validation_data=(x_test, y_test),
validation_freq=1) #以flow的形式送入模型训练
(3)保存模型
import tensorflow as tf
import os
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.fit运行后的结果返回给history
(4)参数提取,把模型中的参数存入文本
model.trainable_variables #返回模型中可训练的参数
设置print输出格式
np.set_printoptions(threshold = 超过多少省略显示) #np.inf表示无限大
print(model.trainable_variables)
np.set_printoptions(threshold=np.inf)
print(model.trainable_variables)
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可视化,查看训练效果
保存在history中
from matplotlib import pyplot as plt
# 显示训练集和验证集的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']
plt.subplot(1, 2, 1) #将图像分为1行2列,画出第一列
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)实际应用
前向传播执行应用
predict(输入特征,batch_size = 整数)
返回前向传播计算结果
from PIL import Image
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
model_save_path = './checkpoint/mnist.ckpt' #已经训练好的模型
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_save_path) #载入模型
preNum = int(input("input the number of test pictures:")) #输入图片
for i in range(preNum):
image_path = input("the path of test picture:") #存放图像路径
img = Image.open(image_path)
image = plt.imread(image_path)
plt.set_cmap('gray')
plt.imshow(image)
img = img.resize((28, 28), Image.ANTIALIAS)
img_arr = np.array(img.convert('L')) #转化为灰度图
for i in range(28): #数据预处理
for j in range(28): #转为灰度值只有0和255的黑白图像
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) #predict函数进行预测,
pred = tf.argmax(result, axis=1) #返回最大值
print('\n')
tf.print(pred)
plt.pause(1)
plt.close()