人工智能实践:Tensorflow笔记

Tensorflow2.0入门学习笔记

  • 人工智能实践:Tensorflow笔记
  • tensorflow2-GPU安装
  • 神经网络的计算过程,搭建出第一个神经网络
    • 第一个例子:用神经网络进行鸢尾花分类
    • 一些常用的TF2函数(后面可能用到)
  • 神经网络的优化方法,学习率,激活函数,损失函数以及正则化的使用
    • 学习率的设置
    • 激活函数
    • 损失函数
    • 缓解过拟合
    • 参数优化器
  • 神经网络搭建八股,六步法
  • 神经网络八股扩展
    • 自制数据集
    • 数据增强,扩充补给
    • 模型的存取
    • 参数提取
    • 参数可视化
  • 卷积神经网络
  • 循环神经网络

人工智能实践:Tensorflow笔记

人工智能实践:Tensorflow笔记

课程源码下载链接:https://pan.baidu.com/s/19XC28Hz_TwnSQeuVifg1UQ 提取码:mocm

tensorflow2-GPU安装

网上搜索
我之前安装了pytorch所以已经安装了cuda11.1以及cudnn8.8.1,
但是安装完tensorflow-gpu2.4.0
(我的cudnn 版本位置 D:\CUDNN\cuda\include\cudnn_version.h
(我的cuda版本位置 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1
(tensorflow-gpu版本 激活anaconda环境输入

神经网络的计算过程,搭建出第一个神经网络

准备数据:采集大量的“特征/标签”数据
搭建网络:搭建神经网络结构(前向传播)
优化参数:训练数据网络获取最佳参数(反向传播)
应用网络:将网络封装为模型,输入未曾见过的数据(测试集),输出预测结果(前向传播)

第一个例子:用神经网络进行鸢尾花分类

准备数据,采集(花瓣长宽,花萼长宽,对应的类别)数据对构成数据集
搭建网络,输入层 1 ∗ 4 1*4 14的矩阵,输出为 1 ∗ 3 1*3 13的矩阵,由图可见,参数为 4 ∗ 3 4*3 43的矩阵以及一个偏置项,就是一个全连接网络
人工智能实践:Tensorflow笔记_第1张图片优化参数:
  通过将 1 ∗ 4 1*4 14的数据喂入网络,通过计算会得到一个结果 y y y,这就是前向传播, y y y应该是一个 1 ∗ 3 1*3 13的矩阵,这里的三个数就代表这三种分类的概率了,当然现在的结果都是蒙的,因为参数都是随机出来的嘛。
  因此引出损失函数(loss function)用来表示预测值 y y y与标准答案 y y y_之间的差距。可以定量地判断参数的好坏,当损失函数最小时参数 达到最优值。
  现在,就需要找到一组参数使得损失函数最小啦。梯度以及梯度下降法介绍。简单来说,梯度就是函数对各个参数求偏导后的向量,其下降方向是函数减少方向。而梯度下降法就是沿着损失函数梯度下降的方向寻找其最小值,从而得到最优参数的方法。那么每次沿着梯度下降的方向走多远呢,可以通过学习率来控制( l e a r n i n g r a t e , l r learning rate, lr learningrate,lr):当学习率过小,收敛满,当学习率过大可能会在最小值附近震荡。
  反向传播就是从后向前,逐层求出偏导,并更新参数的过程。
   w t + 1 = w t − l r ∗ ∂ l o s s / ∂ w t w_{t+1}=w_t-lr*\partial loss/\partial w_t wt+1=wtlrloss/wt
例如: l o s s = ( w + 1 ) 2 loss = (w+1)^2 loss=(w+1)2 那么导数就是 2 w + 2 2w+2 2w+2
  参数 w w w初始化为5,学习率为0.2,则
  1次 参数 w w w:5   5-0.2*(2+5+2)=2.6
  2次 参数 w w w:2.6   2.6-0.2*(2*2.6+2)=1.16
  …
人工智能实践:Tensorflow笔记_第2张图片好,理论存在,开始实践,打开源码中的/class1/p13试试看。
应用网络,…

一些常用的TF2函数(后面可能用到)

tf.constant(张量内容,dtype = 数据类型(可选)或者tf.zeros(维度) #创建张量: 
tf.convert_to_tensor() # numpy与tensor转换得到
tf.cast(张量名,dtype=数据类型) #强制tensor转化为该数据类型
tf.reduce_min(张量名) #计算张量维度上元素的最小值
tf.reduce_max(张量名) #计算张量维度上元素的最大值
tf.reduce_mean(张量名,axis=操作轴) #计算张量沿着指定维度的平均值
tf.variable(初始值)#将变量标记为“可训练”,变量会在反向传播中会被记录梯度信息
w = tf.variable(tf.random.normal([2,2],mean = 0, stddev = 1))
tf.subtract(张量1,张量2) #实现两个张量的对应元素相减
tf.multiply(张量1,张量2) #实现两个张量的对应元素相乘
tf.add(张量1,张量2) #实现两个张量的对应元素相加
tf.divide(张量1,张量2) #实现两个张量的对应元素相除
tf.square(张量名) #计算某个张量的平方
tf.pow(张量名,n次方数) #计算某个张量的n次方
tf.sqrt(张量名) #计算某个张量的开方
tf.matmul(矩阵1,矩阵2) #矩阵乘

# with 结构记录计算过程,gradient求出张量的梯度
with tf.GradientTape() as tape:
  若干个计算过程
grad = tape.gradient(函数,对谁求导)

# 将待转换数据,转换为one-hot形式的数据输出(独热码:就是有多少状态有多少比特,且只有一个比特为1,其余都为0)
tf.one_hot(待转换数据,depth=几分类)
tf.nn.softmax(x) #n分类的结果符合概率分布,也就是全部大于等于0并且和为1
tf.where(条件语句,真返回A,假返回B)
np.random.RandomState.rand(维度) #返回一个[0,1]之间的随机数,若维度为空,则返回标量
np.vstack(数组1,数组2) #将两个数组按垂直方向叠加

#下面三个一起用生成网格坐标线
np.mgrid[起始值:结束值:步长 , 起始值:结束值:步长 , ...] #返回若干组维度相同的等差数组,
x.ravel()  #把多维数组变成一维数组,相当于把点前的数组拉直
np.c_[数组1 , 数组2 , ...] #使返回的间隔数值点配对

神经网络的优化方法,学习率,激活函数,损失函数以及正则化的使用

学习率的设置

	实际应用中,可以先用较大的学习率,快速找到较优值,然后逐步减小学习率,使模型找到最优解
	例如指数衰减学习率:指数衰减学习率=初始学习率*学习率衰减率(当前轮次/几轮衰减一次)

激活函数

	[激活函数的作用](https://www.zhihu.com/question/22334626)
	激活函数就是用来给模型引入非线性因素,解决线性模型所不能解决的问题
	[常见的激活函数](https://zhuanlan.zhihu.com/p/73214810)
	Sigmoid函数,tanh ,ReLU,LeakyReLU,PReLU
	Sigmoid这种一看就是非线性,但是RELU为什么是非线性呢?我是这么理解的,ReLU本身是分段线性函数,但是可以通过ReLu的线性组合去逼近一个非线性函数。

激活函数总结

	视频中的老师对于初学者的建议:
	首选relu激活函数;
	学习率设置较小值
	对输入特征进行标准化,即让输入特征满足以0为均值,1为标准差的正态分布
	对网络的初始参数进行中心化,即让随机生成的参数满足以0为均值,√(2/当前层输入特征个数)为标准差的正态分布

损失函数

定量表示预测值与已知答案的差距

loss_m = tf.reduce_mean(tf.square(y_-y)) #均方误差
loss_c = tf.losses.categorical_crossentropy(y_,y) #交叉熵损失函数
tf.nn.softmax_cross_entropy_with_logits(y_,y) #结合softmax的交叉熵,就是先做softmax再求交叉熵损失(和softmax后面接categorical_crossentropy结果一样)
loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_)*COST, (y_ - y)*PROFIT))或者loss =1 #自定义损失函数,自己写一个,当成损失函数值做反向传播

缓解过拟合

	欠拟合:模型不能有效拟合数据集,对现有数据集学习的不够彻底
	过拟合:模型对当前数据拟合的太好,但对从未见过的新数据,难以做出正确的判断,模型缺乏泛化力。

解决方法
欠拟合解决方法

增加输入特征项
增加网络参数
减少正则化参数

过拟合解决方法

数据清洗
增大训练集
采用正则化
增大正则化参数

正则化缓解过拟合

	就是在损失函数中引入模型复杂度指标,利用给参数加权值,弱化了训练数据的噪声。
	新的损失函数loss_n= 原损失函数loss_o+(超参数R*需要正则化的参数loss(w))
	loss(w)的计算方法有两种,一种L1,一种L2
# 导入所需模块
import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd

# 读入数据/标签 生成x_train y_train
df = pd.read_csv('dot.csv')
x_data = np.array(df[['x1', 'x2']])
y_data = np.array(df['y_c'])

x_train = x_data
y_train = y_data.reshape(-1, 1)

Y_c = [['red' if y else 'blue'] for y in y_train]

# 转换x的数据类型,否则后面矩阵相乘时会因数据类型问题报错
x_train = tf.cast(x_train, tf.float32)
y_train = tf.cast(y_train, tf.float32)

# from_tensor_slices函数切分传入的张量的第一个维度,生成相应的数据集,使输入特征和标签值一一对应
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)

# 生成神经网络的参数,输入层为4个神经元,隐藏层为32个神经元,2层隐藏层,输出层为3个神经元
# 用tf.Variable()保证参数可训练
w1 = tf.Variable(tf.random.normal([2, 11]), dtype=tf.float32)
b1 = tf.Variable(tf.constant(0.01, shape=[11]))

w2 = tf.Variable(tf.random.normal([11, 1]), dtype=tf.float32)
b2 = tf.Variable(tf.constant(0.01, shape=[1]))

lr = 0.01  # 学习率为
epoch = 400  # 循环轮数

# 训练部分
for epoch in range(epoch):
    for step, (x_train, y_train) in enumerate(train_db):
        with tf.GradientTape() as tape:  # 记录梯度信息

            h1 = tf.matmul(x_train, w1) + b1  # 记录神经网络乘加运算
            h1 = tf.nn.relu(h1)
            y = tf.matmul(h1, w2) + b2

            # 采用均方误差损失函数mse = mean(sum(y-out)^2)
            loss_mse = tf.reduce_mean(tf.square(y_train - y))
            # 添加l2正则化####################################################################################
            loss_regularization = []
            # tf.nn.l2_loss(w)=sum(w ** 2) / 2
            loss_regularization.append(tf.nn.l2_loss(w1))
            loss_regularization.append(tf.nn.l2_loss(w2))
            # 求和
            # 例:x=tf.constant(([1,1,1],[1,1,1]))
            #   tf.reduce_sum(x)
            # >>>6
            # loss_regularization = tf.reduce_sum(tf.stack(loss_regularization))
            loss_regularization = tf.reduce_sum(loss_regularization)
            loss = loss_mse + 0.03 * loss_regularization #REGULARIZER = 0.03

        # 计算loss对各个参数的梯度
        variables = [w1, b1, w2, b2]
        grads = tape.gradient(loss, variables)

        # 实现梯度更新
        # w1 = w1 - lr * w1_grad
        w1.assign_sub(lr * grads[0])
        b1.assign_sub(lr * grads[1])
        w2.assign_sub(lr * grads[2])
        b2.assign_sub(lr * grads[3])

    # 每200个epoch,打印loss信息
    if epoch % 20 == 0:
        print('epoch:', epoch, 'loss:', float(loss))

# 预测部分
print("*******predict*******")
# xx在-3到3之间以步长为0.01,yy在-3到3之间以步长0.01,生成间隔数值点
xx, yy = np.mgrid[-3:3:.1, -3:3:.1]
# 将xx, yy拉直,并合并配对为二维张量,生成二维坐标点
grid = np.c_[xx.ravel(), yy.ravel()]
grid = tf.cast(grid, tf.float32)
# 将网格坐标点喂入神经网络,进行预测,probs为输出
probs = []
for x_predict in grid:
    # 使用训练好的参数进行预测
    h1 = tf.matmul([x_predict], w1) + b1
    h1 = tf.nn.relu(h1)
    y = tf.matmul(h1, w2) + b2  # y为预测结果
    probs.append(y)

# 取第0列给x1,取第1列给x2
x1 = x_data[:, 0]
x2 = x_data[:, 1]
# probs的shape调整成xx的样子
probs = np.array(probs).reshape(xx.shape)
plt.scatter(x1, x2, color=np.squeeze(Y_c))
# 把坐标xx yy和对应的值probs放入contour<[‘kɑntʊr]>函数,给probs值为0.5的所有点上色  plt点show后 显示的是红蓝点的分界线
plt.contour(xx, yy, probs, levels=[.5])
plt.show()

# 读入红蓝点,画出分割线,包含正则化
# 不清楚的数据,建议print出来查看 

参数优化器

首先明确几个参数

待优化参数w
损失函数loss
学习率lr
每次迭代一个batch
t表示当前batch迭代的总次数

参数更新流程
人工智能实践:Tensorflow笔记_第3张图片常见的5种参数优化器:
SGD

#sgd
w1.assign_sub(lr * grads[0])  #参数w自更新
b1.assign_sub(lr * grads[1])  #参数b自更新

SGDM:在SGD基础上增加了一阶动量

m_w,m_b = 0,0
beta = 0.9
# sgd-momentun
m_w = beta * m_w + (1 - beta) * grads[0]
m_b = beta * m_b + (1 - beta) * grads[1]
w1.assign_sub(lr * m_w)
b1.assign_sub(lr * m_b)

Adagrad:在SGD基础上增加了二阶动量

v_w,v_b = 0,0
# adagrad
v_w += tf.square(grads[0])
v_b += tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

RMSProp:在SGD基础上增加了二阶动量

v_w,v_b = 0,0
beta = 0.9
# rmsprop
v_w = beta * v_w + (1 - beta) * tf.square(grads[0])
v_b = beta * v_b + (1 - beta) * tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))

Adam:同时结合SGDM一阶动量和RMSProp二阶动量,还有修正公式

m_w,m_b = 0,0
v_w,v_b = 0,0
beta1,beta2 = 0.9,0.999
delta_w,delta_b = 0,0
global_step = 0
# adam
m_w = beta1 * m_w + (1 - beta1) * grads[0]
m_b = beta1 * m_b + (1 - beta1) * grads[1]
v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])

m_w_correction = m_w / (1 - tf.pow(beta1,int(global_step)))
m_b_correction = m_b / (1 - tf.pow(beta1,int(global_step)))
v_w_correction = v_w / (1 - tf.pow(beta2,int(global_step)))
v_b_correction = v_b / (1 - tf.pow(beta2,int(global_step)))

w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))

神经网络搭建八股,六步法

import #导入包
train , test #自制数据集,数据增强
model = tf.leras.models.Sequential/class MyModel(Model)
model.compile #配置训练方法
model.fit #执行训练过程,断点续训
model.summary #参数提取
#共六步

网络结构搭建

model = tf.keras.models.Sequential([网络结构]) #添加网络结构
tf.keras.layers.Flatten() #拉直层
tf.keras.layers.Dense(神经元个数,activation="激活函数",kernel_regularizer=哪种正则化) #全连接层
# activation(字符串给出)可选:relu、softmax、sigmoid、tanh
# kernel_regularizer可选:tf.keras.regularizers.l1()、tf.keras.regularizers.l2()
tf.keras.layers.Conv2D(filters=卷积核个数,kernel_size=卷积核尺寸,strides=卷积步长,padding="valid"or"same") #卷积层
tf.keras.layers.LSTM() #LSTM层

优化器参数选择

model.compile(optimizer=优化器,loss=损失函数,metrics=["准确率"])
#optimizer可选项
'sgd' or tf.keras.optimizers.SGD(lr=学习率,momentum=动量参数)
'adagrad' or tf.keras.optimizers.Adagrad(lr=学习率) 
'adadelta' or tf.keras.optimizers.Adadelta(lr=学习率)
'adam' or tf.keras.optimizers.Adam(lr=学习率,beta_1=O.9,beta_2=0.999) 
# loss可选项
'mse' or tf.keras.losses.MeanSquaredError()
'sparse_categorical_crossentropy' or tf.keras,losses.SparseCategoricalCrossentropy(from_logits=False)
# 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]

model.fit

model.fit(训练集的输入特征,训练集的标签,batch_size= ,epoch= ,validation_data=(测试集的输入特征,测试集的标签),validation_split=从训练集划分多少比例给测试集,validation_freq=多少次epoch测试一次)

model.summary

#写上这个就可以打印网络了

用Sequential搭建鸢尾花分类网络

import tensorflow as tf
from sklearn import datasets
import numpy as np

x_train = datasets.load_iris().data
y_train = datasets.load_iris().target

np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)

model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())
])

model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)

model.summary()

这样的搭建方式是上层输出就是下层输入,但是无法写出一些带有跳连的非顺序网络结构,这是可以用类class搭建

class MyModel(Model):
   def__init__(self):
     super(MyModel,self).__init__()
     #定义网络结构块
     #准备积木
   def call(self,x):
     #调用网络结构块,实现前向传播
     #调用搭建积木
    return y
model = MyModel()

用class代替Sequrntial搭建网络结构

import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from sklearn import datasets
import numpy as np

x_train = datasets.load_iris().data
y_train = datasets.load_iris().target

np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)

class IrisModel(Model):
    def __init__(self):
        super(IrisModel, self).__init__()
        self.d1 = Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())

    def call(self, x):
        y = self.d1(x)
        return y

model = IrisModel()

model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)
model.summary()

神经网络八股扩展

自制数据集

使用本地数据集:
def generateds(path):
#处理一下,读取数据。
		return 特征x,标签y
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'

# generateds()函数,用于制作数据集
def generateds(path, txt):
    f = open(txt, 'r')  # 以只读形式打开txt文件
    contents = f.readlines()  # 读取文件中所有行
    f.close()  # 关闭txt文件
    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'))  # 图片变为8位宽灰度值的np.array格式
        img = img / 255.  # 数据归一化 (实现预处理)
        x.append(img)  # 归一化后的数据,贴到列表x
        y_.append(value[1])  # 标签贴到列表y_
        print('loading : ' + content)  # 打印状态提示

    x = np.array(x)  # 变为np.array格式
    y_ = np.array(y_)  # 变为np.array格式
    y_ = y_.astype(np.int64)  # 变为64位整型
    return x, y_  # 返回输入特征x,返回标签y_

# 判断训练集特征x_train,训练集标签y_train,测试集输入特征x_test,测试集标签y_test是不是已经存在
# 如果存在,直接读取
# 如果不存在,调用generateds()函数制作数据集
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)
    # reshape()是数组array中的方法,作用是将数据重新组织,这里可以理解为将数据组织成len(x_train_save), 28, 28的三维数组
    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:
    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)

# 下面的和之前六步法的完全一样
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 = 随机宽度偏移量
    height_shift_range = 随机高度偏移量
    水平翻转:horizontal_flip = 是否随机水平翻转
    随机缩放:zoom_range = 随机缩放的范围[1-n,1+n])
image_gen_train.fit(x_train)

测试代码:

import tensorflow as tf
# 增加了ImageDataGenerator模块
from tensorflow.keras.preprocessing.image import ImageDataGenerator

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
# 给数据增加一个维度,从(60000, 28, 28)reshape为(60000, 28, 28, 1)
# 因为后面image_gen_train.fit需要输入四维数据,因此需要reshape,将数据变为60000张28行28列单通道数据,这个单通道是灰度值
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)

# 把x_train送入数据增强操作
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%
)
# fit执行增强操作
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'])

# 执行训练过程
# fit这里以flow形式按照batch打包后执行训练过程
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()

模型的存取

#读取模型
checkpoint_save_path = "./checkpoint/mnist.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    # 如果有索引表,就说明保存过模型,则可以调用load_weights读取模型参数
    model.load_weights(checkpoint_save_path)
#保存模型
tf.keras.callbacks.ModelCheckpoint(
filepath=路径文件名,                                     save_weights_only=True/False,                                save_best_only=True/False)

# 执行训练过程时,加入callbacks选项,记录到history中
history = model.fit(callbacks=[cp_callback])
# 使用举例
import tensorflow as tf
# 为了判断保存的模型参数是否存在,引入os模块
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.0, x_test / 255.0

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'])

# 先定义出存放模型的路径和文件名,命名为ckpt文件
# 生成ckpt文件时,会同步生成索引表,所以通过判断是否已经有索引表,就知道是不是已经保存过模型参数
checkpoint_save_path = "./checkpoint/mnist.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    # 如果有索引表,就说明保存过模型,则可以调用load_weights读取模型参数
    model.load_weights(checkpoint_save_path)

# 加入回调函数,返回给cp_callback
# 三个参数分别为:文件存储路径/是否只保留模型参数/是否只保留最优结果
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True)

# 执行训练过程时,加入callbacks选项,记录到history中
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.summary()

# 打印所有可训练参数,并存入weights文件
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()

参数可视化

import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt

np.set_printoptions(threshold=np.inf)

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

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()

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()

###############################################    show   ###############################################

# 显示训练集和验证集的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']

# subplot将图像分为1行2列,这段代码画第1列
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()

卷积神经网络

循环神经网络

你可能感兴趣的:(tensorflow笔记,深度学习,神经网络,人工智能)