北大Tensorflow2.0(二、三、四)

总目录
【tensorlfow2】安装及简介全连接神经网络
北大Tensorflow2.0(一)

一级目录

二级目录

三级目录

2

激活函数

类似于归一化数据,常用relu
解决了梯度消失问题 (在正区间) (2) 只需判断输入是否大于0,计算速度快
(3) 收敛速度远快于sigmoid和tanh
缺点:
(1) 输出非0均值,使收敛慢
(2) Dead RelU问题:某些神经元可能永远不会被激活(输入为负数时结果为0),导致相应的参数永远不能被更新。
解决方法

  • 设置小些的学习率,减少参数变化
  • 输入特征标准化,即让输入特征满足以0为均值,1为标准差的正态分布;
  • 初始参数中心化,即让随机生成的参数满足以0为均值,sqrt( 2/当前层输入特征个数) 为标准差的正态分布。
    前向传播可看成线性变化,激活函数拟合非线性部分

正则化:解决过拟合 p29_regularizationfree.py

过拟合预测边界会不平滑
w1 = tf.Variable(tf.random.normal([2, 11]), dtype=tf.float32)

#生成正态分布的随机数,默认均值为0,标准差为1
tf.random.normal(维度,mean = 均值,stddev = 标准差)
#生成截断式正态分布的随机数
tf.random.truncated_normal(维度,mean = 均值。stddev = 标准差)

生成网格坐标点
#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)

batch为单位批量喂入神经网络,提高训练速度

优化器

深度学习优化算法经历了SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam

p32_sgd.py

记录不同优化器模型速度
#训练部分
now_time = time.time() ##2##
.
.
.
total_time = time.time() - now_time ##3##
print(“total_time”, total_time) ##4##

# 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线
# 导入所需模块
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np
import time  ##1##
# 导入数据,分别为输入特征和标签
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target
# 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
# seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)
# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]
# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)

# from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)batch=32
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
# 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元
# 用tf.Variable()标记参数可训练
# 使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
lr = 0.1  # 学习率为0.1
train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500  # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和
# 训练部分
now_time = time.time()  ##2##
for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集
    for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batch
        with tf.GradientTape() as tape:  # with结构记录梯度信息
            y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算
            y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)
            y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracy
            loss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)
            loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确
        # 计算loss对各个参数的梯度
        grads = tape.gradient(loss, [w1, b1])
        
        # SGD优化器 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
        w1.assign_sub(lr * grads[0])  # 参数w1自更新
        b1.assign_sub(lr * grads[1])  # 参数b自更新
        
    # 每个epoch,打印loss信息
    print("Epoch {}, loss: {}".format(epoch, loss_all / 4))
    train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中
    loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备
    
    # 测试部分
    # total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 使用更新后的参数进行预测
        y = tf.matmul(x_test, w1) + b1
        y = tf.nn.softmax(y)
        pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类
        # 将pred转换为y_test的数据类型
        pred = tf.cast(pred, dtype=y_test.dtype)
        # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
        correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
        # 将每个batch的correct数加起来
        correct = tf.reduce_sum(correct)
        # 将所有batch中的correct数加起来
        total_correct += int(correct)
        # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
        total_number += x_test.shape[0]
    # 总的准确率等于total_correct/total_number
    acc = total_correct / total_number
    test_acc.append(acc)
    print("Test_acc:", acc)
    print("--------------------------")
total_time = time.time() - now_time  ##3##
print("total_time", total_time)  ##4##

# 绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像
# 绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()
# 本文件较 class1\p45_iris.py 仅添加四处时间记录  用 ##n## 标识
# 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx  对比各优化器收敛情况



SGD最大的缺点是下降速度慢,而且可能会在沟壑的两边持续震荡,停留在一个局部最优
点。
SGDM(含momentum的SGD) 𝒎t = 𝜷 𝒎𝒎𝒕𝒕−𝟏𝟏 + (𝟏 − 𝜷) 𝒈t, 𝜷为超参数,经验值为0.9

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

AdaGrad

TensorFlow API: tf.keras.optimizers.Adagrad
上述SGD算法一直存在一个超参数(Hyper-parameter),即学习率。超参数是训练前需要手动
选择的参数,前缀“hyper”就是用于区别训练过程中可自动更新的参数。学习率可以理解为参数 沿
着梯度 反方向变化的步长。
SGD对所有的参数使用统一的、固定的学习率,一个自然的想法是对每个参数设置不同的学习率,
然而在大型网络中这是不切实际的。因此,为解决此问题,AdaGrad算法被提出,其做法是给学习率
一个缩放比例,从而达到了自适应学习率的效果(Ada = Adaptive)。其思想是:对于频繁更新的参
数,不希望被单个样本影响太大,我们给它们很小的学习率;对于偶尔出现的参数,希望能多得到一些
信息,我们给它较大的学习率。

AdaGrad 在稀疏数据场景下表现最好。因为对于频繁出现的参数,学习率衰减得快;对于稀疏的

参数,学习率衰减得更慢。然而在实际很多情况下,二阶动量呈单调递增,累计从训练开始的梯度,学
习率会很快减至 0 ,导致参数不再更新,训练过程提前结束。

Adam

TensorFlow API: tf.keras.optimizers.Adam
是前述方法的集大成者。我们看到,SGDM在 SGD基础上增加了一阶动量,AdaGrad、RMSProp和AdaDelta在SGD基础上增加了二阶动量。把一
阶动量和二阶动量结合起来,再修正偏差,就是Adam了。

在这里插入图片描述

# 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,b1
w1.assign_sub(learning_rate * m_w_correction / tf.sqrt(v_w_correction))
 b1.assign_sub(learning_rate * m_b_correction / tf.sqrt(v_b_correction))

3 神经网络搭建八股、用六步法写出手写数字识别训练模型

tf.keras 搭建网络八股
tf.keras 中的 Model 类,可以看到右方目录列出了 Model 类所包含的函数。
搭建神经网络六部法
tf.keras 搭建神经网络六部法
第一步:import 相关模块,如 import tensorflow as tf。
第二步:指定输入网络的训练集和测试集,如指定训练集的输入 x_train 和标签
y_train,测试集的输入 x_test 和标签 y_test。
第三步:逐层搭建网络结构,model = tf.keras.models.Sequential()。
第四步:在 model.compile()中配置训练方法,选择训练时使用的优化器、损失
函数和最终评价指标。
第五步:在 model.fit()中执行训练过程,告知训练集和测试集的输入值和标签、
每个 batch 的大小(batchsize)和数据集的迭代次数(epoch)。
第六步:使用 model.summary()打印网络结构,统计参数数目。

模板:记住

imort
train,test
# 搭建网络结构
```python
model = tf.keras.models.Sequential
# 配置训练方法,优化器、参数、评测指标
model.compile
#执行训练过程,告知训练集和测试集的输入特征和标签
model.fit
#打印网络的结构和参数统计
model.summary

Model.compile

( optimizer = 优化器, loss = 损失函数, metrics = [“准确率”])
Compile 用于配置神经网络的训练方法,告知训练时使用的优化器、损失函
数和准确率评测标准。

optimizer

可以是字符串形式给出的优化器名字,也可以是函数形式,使用函数形式可以设置学习率、动量和超参数。 可选项包括:
‘sgd’or tf.optimizers.SGD( lr=学习率,
decay=学习率衰减率,
momentum=动量参数) ‘adagrad’or tf.keras.optimizers.Adagrad(lr=学习率,
decay=学习率衰减率) ‘adadelta’or tf.keras.optimizers.Adadelta(lr=学习率,
decay=学习率衰减率) ‘adam’or tf.keras.optimizers.Adam (lr=学习率,
decay=学习率衰减率)
###Loss
可以是字符串形式给出的损失函数的名字,也可以是函数形式。
可选项包括:
‘mse’or tf.keras.losses.MeanSquaredError()
‘sparse_categorical_crossentropy
or tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
损失函数常需要经过 softmax 等函数将输出转化为概率分布的形式。
from_logits 则用来标注该损失函数是否需要转换为概率的形式,取 False 时表示转化为概率分布,取 True 时表示没有转化为概率分布,直接输出。
例如:
model.compile(optimizer=‘adam’,
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=[‘sparse_categorical_accuracy’])

model.fit

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

model.summary()

打印网络结构参数的统计

Sequential demo

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

全连接层:tf.keras.layers.Dense( 神经元个数,
activation=”激活函数”,
kernel_regularizer=”正则化方式”)
其中:
activation(字符串给出)可选 relu、softmax、sigmoid、tanh 等
kernel_regularizer 可选 tf.keras.regularizers.l1()、
tf.keras.regularizers.l2()

#选择训练参数
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),# False是因为神经网络最后一层用了softmax
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 声明网络

使用 Sequential 可以快速搭建网络结构,但是如果网络包含跳连等其他复
杂网络结构,Sequential 就无法表示了。这就需要使用 class 来声明网络结构。

class MyModel(Model):
def __ init__ (self):
super(MyModel, self).init()
//初始化网络结构
def call(self, x):
y = self.d1(x)
return y
使用 class 类封装网络结构,如上所示是一个 class 模板,
MyModel 表示声明的神经网络的名字,括号中的 Model 表示创建的类需要继承 tensorflow 库中的 Model 类。
类中需要定义两个函数,init()函数为类的构造函数用于初始化类的参数,spuer(MyModel,self).init()这行表示初始化父类的参数。之后便可初始化网络结构,搭建出神经网络所需的各种网络结构块。
call()函数中调用__init__()函数中完成初始化的网络块,实现前向传播并返回推理
值。使用 class 方式搭建鸢尾花网络结构的代码如下所示。

class IrisModel(Model):
def __init__(self):
super(IrisModel, self).__init__()
self.d1 = Dense(3, activation='sigmoid', 
kernel_regularizer=tf.keras.regularizers.l2())
def call(self, x):
y = self.d1(x)
return y

搭建好网络结构后只需要使用 Model=MyModel()构建类的对象,就可以使用
该模型了。
对比使用 Sequential()方法和 class 方法,有两点区别: ①import 中添加了 Model 模块和 Dense 层、Flatten 层。
②使用 class 声明网络结构,model = IrisModel()初始化模型对象。

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='sigmoid', 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()

p13_mnist_datasets.py
报错
Exception: URL fetch failure on https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz: None – unknown url type: https
Process finished with exit code 1
解决办法
下载mnist.npz,下完后我放到了C:\Users\81211.keras\datasets中,再次运行就可以啦,记得不要放到anaconda安装路径中的datasets中,这是一个坑嗷!


tf.keras.layers.Dense(10, activation=‘softmax’)
#使输出服从概率分布


p16_fashion_sequential.py 报错
在使用以下语句时,执行报错——无法访问/访问超时/访问被拒绝。

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
1
2
但是,这里我们需要官方的数据集进行练习,就必须要进行下载数据的——既然通过load_data()默认下载不可以,那么我们不如通过本地下载,再放入指定文件中来解决问题呢。

解决方法(建议至少运行过一次load_data()函数,创建需要的文件路径)
补充提示:可以在按照我的方法解决问题前,运行一次相应的load_data()函数,这样虽然不成功,但是会创建一个路径——这样下边的步骤就可以直接进行了。

前往数据集下载网址直接下载需要的四个数据集。
下载1: train-images-idx3-ubyte.gz
下载2: train-labels-idx1-ubyte.gz
下载3: t10k-images-idx3-ubyte.gz
下载4: t10k-labels-idx1-ubyte.gz
然后将数据集放入到C盘用户文件夹的.keras文件下的datasets目录里(不要解压哦)
具体如下:
1.点击C盘下的用户文件夹进入

2.点击30208文件夹(这是我的root文件夹)进入

3.进入.keras文件夹

4.再进入datasets

5.进入fashion-mnist文件夹——这里我们用fashion-mnist练习,所以将下载的数据集放进去这里
(如果是mnist数据集就需要放进mnist文件夹——这样的文件都是提前通过先使用keras的load_data()下载,虽然会失败,但是会留下一个空目录,就是我们下载到本地的数据集存放的地方。)

4 神经网络八股扩展、增加自制数据集、数据增强、断点续参数提取和acc、loss可视化,实现给图识物的应用程序

完整代码:代码 mnist_train_ex5.py(必背)

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

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

绘图
acc/loss可视化,查看训练效果
(1)使用方法
history = model.fit(训练集数据,训练集标签,batch_size = ,epochs = ,validation_split =用作测试数据的比例,validation_data = 测试集,validation_freq = 测试频率)
(2)可选参数
history:
训练集loss: loss
测试集loss: val_los
训练集准确率:sparse_categorical_accuracy
测试集准确率: val_sparse_categorical_accuracy

显示训练集和验证集的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)
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()
————————————————

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值