2021年7月第三周
1.编写卷积神经网络程序,实现五种花朵分类

数据:
image.png

训练:
image.png

测试:
image.png
image.png

image.png
image.png
image.png

2.学习了【北京大学】Tensorflow2.0教程

循环神经网络具有记忆性、参数共享并且图灵完备(Turing completeness),因此在对序列的非线性特征进行学习时具有一定优势^ [4]^[ ]() 。循环神经网络在自然语言处理(Natural Language Processing, NLP),例如语音识别、语言建模、机器翻译等领域有应用,也被用于各类时间序列预报。引入了卷积神经网络(Convolutional Neural Network,CNN)构筑的循环神经网络可以处理包含序列输入的计算机视觉问题。


循环核:参数时间共享,循环层提取时间信息。
image.png

循环神经网络:借助循环核提取时间特征后,送入全连接网络。
image.png
image.png
image.png
image.png

例子:(1)循环网络计算过程-字母预测
image.png

独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。通常,在通信网络协议栈中,使用八位或者十六位状态的独热码,且系统占用其中一个状态码,余下的可以供用户使用。

例如,有6个状态的独热码状态编码为:000001,000010,000100,001000,010000,100000。
image.png
image.png

(2)用RNN实现输入一个字母,预测下一个字母 (One hot 编码)

输入abcd输出e

输入bcde输出a

输入cdea输出b

输入deab输出c

输入eabc输出d
image.png
image.png
image.png

(3)RNN实现股票预测
image.png
image.png

(4)用LSTM实现股票预测
image.png
image.png
image.png

(5)用GRU实现股票预测
image.png
image.png
image.png

遇到的问题和解决办法

Tensorflow与numpy版本不匹配。

解决:对应https://docs.floydhub.com/guides/environments/ 降低numpy版本

2021年7月第二周

1.安装CUDA和cuDNN使用gpu加速

https://blog.csdn.net/wbing96/article/details/108914071

https://blog.csdn.net/sinat_23619409/article/details/84202651
image.png
image.png
image.png

GPU性能太差提示显存不够,可通过减少batch_size解决。

2.学习了【北京大学】Tensorflow2.0教程

卷积:
image.png
image.png

image.png

感受野:(Receptive Field)卷积神经网络各输出特征图中的每个像素点,在原始输入图片上映射区域的大小。

全零填充:卷积计算保持输入特征图的尺寸不变,在输入特征图周围填充0
image.png
image.png

批标准化:(Batch Normalization, BN) 标准化:使数据符合0均值,1为标准差的分布。批标准化:对一小批数据(batch),做标准化处理。常用在卷积操作和激活操作之间。
image.png

池化:用于减少特征数据量,最大池化可提取图片纹理,均值池化可保留背景特征。
image.png

舍弃:(Dropout)在神经网络训练时,将一部分神经元按照一定比例从神经网络中暂时舍弃,神经网络使用时,被舍弃的神经元恢复链接。
image.png

卷积神经网络:借助卷积核提取特征后,送入全连接网络。
image.png

卷积-特征提取器-CBAPDConv2D(卷积层)BN层、Activation(激活层)、MaxPool2D(池化层)Dropout

Cifar10数据集:
image.png

卷积神经网络搭建:
image.png
image.png
image.png

五个经典卷积神经网络

LeNetAlexNetVGGNetInceptionNetResNet

1.LeNet
image.png
image.png

2.AlexNet
image.png
image.png

3.VGGNet
image.png
image.png
image.png

4.InceptionNet
image.png

5.ResNet
image.png

总结:
image.png

3.阅读论文《基于多尺度卷积神经网络的水果识别技术研究》

遇到的问题和解决办法

2021年7月第一周

  1. 学习了【北京大学】Tensorflow2.0教程 https://www.bilibili.com/video/BV1B7411L7Qt

神经网络优化器: 一言以蔽之,优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数让损失函数(目标函数)值不断逼近全局最小。
image.png

五种优化器:

  1. SGD(随机梯度下降)
    image.png
  2. SGDM
    image.png
  3. Adagrad
    image.png
  4. RMSProp
    image.png
  5. Adam
    image.png

五种优化器训练耗时对比
image.png

搭建网络八股sequential
image.png
image.png
image.png
image.png

2.完成代码:

# 利用鸢尾花数据集,实现前向传播、反向传播,可视化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组数据)

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



        # 实现梯度更新 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()

结果:
image.png

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

结果:
image.png

2021年6月第四周

  1. 学习了【北京大学】Tensorflow2.0教程 https://www.bilibili.com/video/BV1B7411L7Qt

损失函数:

均方误差(mean-square error, MSE)是反映估计量与被估计量之间差异程度的一种度量。

交叉熵(Cross Entropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。
image.png

欠拟合与过拟合:

欠拟合:模型不能有效拟合数据集,是对现有数据集学习的不够彻底。

过拟合:模型对当前数据拟合的太好,但对从未见过的新数据难以做出正确的判断。
image.png

欠拟合的解决方法:
增加输入特征项 增加网络参数 减少正则化参数

过拟合的解决方法:
数据清洗 增大训练集 采用正则化 增大正则化参数
image.png

2完成代码:

*"""*



*预测酸奶日销量* *y* *,* *x1* *、* *x2* *是影响日销量的因素。

建模前,应预先采集的数据有:每日* *x1* *、* *x2* *和销量* *y_* *(即已知答案,最佳情况:产量* *=* *销量)

拟造数据集* *X,Y_* *:** y_ = x1 + x2 * *噪声:* *-0.05 ~ +0.05 * *拟合可以预测销量的函数**

"""

* import tensorflow as tf

import numpy as np



SEED = 23455

rdm =
np.random.RandomState(seed=SEED)

x = rdm.rand(32, 2)

y_ = [[x1 + x2 + rdm.rand() / 10.0 - 0.05] for (x1, x2) in x]

x = tf.cast(x, dtype=tf.float32)



w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))



epoch = 15000

lr = 0.002



for epoch in range(epoch):

    with tf.GradientTape() as tape:

        y = tf.matmul(x, w1)

        loss_mse =
tf.reduce_mean(tf.square(y_ - y))

        grads = tape.gradient(loss_mse, w1)

        w1.assign_sub(lr * grads)



        if epoch % 500 == 0:

            print("After %d training steps, w1 is" % (epoch))

            print(w1.numpy(),"\n")



print("Final w1 is:", w1.numpy())

运行结果:

image.png

*"""*



*预测酸奶日销量* *y* *,* *x1* *、* *x2* *是影响日销量的因素。

建模前,应预先采集的数据有:每日* *x1* *、* *x2* *和销量* *y_* *(即已知答案,最佳情况:产量* *=* *销量)

拟造数据集* *X,Y_* *:** y_ = x1 + x2 * *噪声:* *-0.05 ~ +0.05 * *拟合可以预测销量的函数**

* *如预测商品销量,预测多了,损失成本;预测少了,损失利润。 若利润 loss tf reduce sum tf select tf greater y y loss mo = . _ . . , _,
_ _, _ _ ( ( ( ) re y y loss less y y ( * *−** * *−** ) ( )))
* *成本,则mse产生的loss无法利益最大化。 如:预测酸奶销量,酸奶成本(COST)1元,酸奶利润(PROFIT)99元。
预测少了损失利润99元,大于预测多了损失成本1元。 预测少了损失大,希望生成的预测函数往多了预测。*



*"""

* import tensorflow as tf

import numpy as np



SEED = 23455

COST = 1

PROFIT = 99



rdm =
np.random.RandomState(seed=SEED)

x = rdm.rand(32, 2)

y_ = [[x1 + x2 + rdm.rand() / 10.0 - 0.05] for (x1, x2) in x]

x = tf.cast(x, dtype=tf.float32)



w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))



epoch = 15000

lr = 0.002



for epoch in range(epoch):

    with tf.GradientTape() as tape:

        y = tf.matmul(x, w1)

        # loss_mse = tf.reduce_mean(tf.square(y_ - y))

        loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT))

        grads = tape.gradient(loss, w1)

        w1.assign_sub(lr * grads)



        if epoch % 500 == 0:

            print("After %d training steps, w1 is" % (epoch))

            print(w1.numpy(),"\n")



print("Final w1 is:", w1.numpy())

运行结果:
image.png

import numpy as np



import tensorflow as tf

import pandas as pd

from matplotlib import pyplot as plt



df = pd.read_csv('dot.csv')

x_data = np.array(df[['x1', 'x2']])

y_data = np.array(df['y_c'])



x_train = np.vstack(x_data).reshape(-1, 2)

y_train = np.vstack(y_data).reshape(-1, 1)



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



x_train = tf.cast(x_train, tf.float32)

y_train = tf.cast(y_train, tf.float32)



train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)



# 生成神经网络的参数,输入层为2个神经元,隐藏层为11个神经元,1层隐藏层,输出层为一个神经元

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.005

epoch = 800



# 训练部分

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

            # 均方误差损失函数

            loss = tf.reduce_mean(tf.square(y_train
- y))

        variables = [w1, b1, w2, b2]

        grads = tape.gradient(loss, variables)

        # 实现梯度更新

        w1.assign_sub(lr * grads[0])

        b1.assign_sub(lr * grads[1])

        w2.assign_sub(lr * grads[2])

        b2.assign_sub(lr * grads[3])

    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_test in grid:

    # 使用训练好的参数进行预测

    h1 = tf.matmul([x_test], 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)) # squeeze去掉纬度是1的纬度,相当于去掉[['red'],[''blue]],内层括号变为['red','blue']

# 把坐标xx yy和对应的值probs放入contour<[‘kɑntʊr]>函数,给probs值为0.5的所有点上色  plt点show后 显示的是红蓝点的分界线

plt.contour(xx, yy, probs, levels=[.5])

plt.show()

image.png
轮廓不够平滑存在过拟合现象

添加L2正则化后:
image.png

2021年6月第三周

  1. 学习了【北京大学】Tensorflow2.0教程 https://www.bilibili.com/video/BV1B7411L7Qt

神经网络的复杂度:
image.png

学习率:
image.png

指数衰减学习率: 可以先用较大的学习率,快速得到最优解,然后逐步减小学习率,使模型在训练后期稳定。
image.png

激活函数: 所谓激活函数(Activation Function),就是在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端。

什么是激活函数: 激活函数(Activation functions)对于人工神经网络 1() 模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。它们将非线性特性引入到我们的网络中。如图1,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘罢了。

为什么使用激活函数: 如果不用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,这种情况就是最原始的感知机。如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。

常用的激活函数: Sigmoid函数、Tanh函数、ReLU函数、
image.png
image.png

Sigmoid函数:
image.png

Tanh函数:
image.png

ReLU函数:
image.png

Leaky Relu函数:
image.png
image.png

2完成代码:

import tensorflow as tf



import numpy as np



# tf.where()

a =
tf.constant([1, 2, 3, 1, 1])

b = tf.constant([0, 1, 3, 4, 5])

c = tf.where(tf.greater(a, b), a, b)

print("c:", c)

#
np.random.RandomState.rand()

rdm =
np.random.RandomState(seed=1)

a = rdm.rand()

b = rdm.rand(2, 3)

print("a:", a)

print("b:", b)

# np.vstack()

a = np.array([1, 2, 3])

b = np.array([4, 5, 6])

c = np.vstack((a, b))

print("c:\n", c)

# np.mgrid()

x, y = np.mgrid[1:3:1, 2:4:0.5]

grid = np.c_[x.ravel(), y.ravel()]

print("x:", x)

print("y:", y)

print('grid:\n', grid)

# -------------------------------------------------------------------------------------------

# 指数衰减学习率

w =
tf.Variable(tf.constant(5, dtype=tf.float32))

epoch = 40

LR_BASE = 0.2

LR_DECAY = 0.99

LR_STEP = 1



for epoch in range(epoch):

    lr = LR_BASE * LR_DECAY ** (epoch /
LR_STEP)

    with tf.GradientTape() as tape:

        loss = tf.square(w+1)

    grads = tape.gradient(loss, w)

    w.assign_sub(lr * grads)

    print("After %s epoch, w is %f, loss is %f,
lr is %f" %
(epoch, w.numpy(), loss, lr))

image.png

2021年6月第二周

  1. 学习了【北京大学】Tensorflow2.0教程 https://www.bilibili.com/video/BV1B7411L7Qt
    image.png

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

2.编写代码

# 创建一个张量



import tensorflow as tf

import numpy as np

a = tf.constant([1, 5], dtype=tf.int64)

print(a)

print(a.dtype)

print(a.shape)



b = np.arange(0, 5)

c = tf.convert_to_tensor(b)

print(c)

d = tf.zeros([2, 3])

e = tf.ones(4)

f = tf.fill([2, 2], 9)

print(d)

print(e)

print(f)

g = tf.random.normal([2, 2], mean=0.5, stddev=1)

print(g)

h = tf.random.truncated_normal([2, 2], mean=0.5, stddev=1)

print(h)

i = tf.random.uniform([2, 2], minval=0, maxval=1)

print(i)

x1 = tf.constant([1, 2, 3], dtype=tf.float64)

print(x1)

x2 = tf.cast(x1, tf.int32)

print(x2)

print(tf.reduce_max(x2), tf.reduce_min(x2))

a = tf.ones([1, 3])

b = tf.fill([1, 3], 3.)

print(a)

print(b)

print(tf.add(a, b))

print(tf.subtract(a, b))

print(tf.multiply(a, b))

print(tf.divide(a, b))

3.实验:鸢尾花分类

(1)鸢尾花数据集读入
image.png

安装sklearn 和 pandas
image.png
image.png

读入数据:
image.png

准备数据

• 数据集读入

• 数据集乱序

• 生成训练集和测试集(即 x_train / y_train)

• 配成 (输入特征,标签) 对,每次读入一小撮(batch)

搭建网络

• 定义神经网路中所有可训练参数

参数优化

• 嵌套循环迭代,with结构更新参数,显示当前loss

测试效果

• 计算当前参数前向传播后的准确率,显示当前acc

 acc / loss可视化

实验代码:

# -*- coding: UTF-8
-*-



# 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线



# 导入所需模块

import tensorflow as tf

from sklearn import datasets

from matplotlib import pyplot as plt

import numpy as np



# 导入数据,分别为输入特征和标签

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组数据)

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的和



# 训练部分

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



        # 实现梯度更新 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("--------------------------")



# 绘制 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()

image.png

2021年6月第一周

二)本周科研内容、工作进展,遇到的问题等

安装了tensorflow等环境

Pycharm更换pip源为国内

清华大学源:https://pypi.tuna.tsinghua.edu.cn/simple
image.png

安装tensorflow2.1

pip install tensorflow -i
https://pypi.tuna.tsinghua.edu.cn/simple --default-timeout=1000
image.png

  1. 学习了【北京大学】Tensorflow2.0教程 https://www.bilibili.com/video/BV1B7411L7Qt

以鸢尾花分类为例:

鸢尾花可分为: 0狗尾草鸢尾 1杂色鸢尾 2佛吉尼亚鸢尾

通过测量花的花萼长、花萼宽、花瓣长、花瓣宽, 可以得出鸢尾花的类别。

神经网络:

  • 采集大量(花萼长、花萼宽、花瓣长、花瓣宽,对应的类别(标签,需要人工标定))数据对构成数据集
  • 把数据集喂入搭建好的神经网络结构中
  • 网络优化参数得到模型
  • 模型读入新输入特征,输出识别结果。

如图:
image.png
image.png

image.png

image.png

输入 [花萼长、花萼宽、花瓣长、花瓣宽] 1行4列的数据(X)乘 W(权值 4行三列)得到 1行3列的结果。
image.png
image.png

输入 [花萼长、花萼宽、花瓣长、花瓣宽] 所以有四个输入节点 输出的是三种鸢尾花各自的可能性大小,所以输出节点是3个。

y0,y1,y2 与 前面的x0,x1,x2,x3都有连接关系
称之为全连接网络。
image.png
image.png

image.png

image.png

image.png

image.png

3.编写代码

import tensorflow as tf





# 变量定义

w =
tf.Variable(tf.constant(5, dtype=tf.float32))

lr = 0.2

epoch = 40





for epoch in range(epoch):

    with tf.GradientTape() as tape: 
# with 结构到grads框起了梯度的计算过程

        loss = tf.square(w + 1)

    grads = tape.gradient(loss, w)  # .gradient函数告知谁对谁求导



    w.assign_sub(lr * grads)  # .assign_sub对变量做自减 即: w -=lr*grads 即 w = w - lr*grads

    print("After %s epoch, w is %f,loss is %f" % (epoch, w, loss))





# 最终目的:找到loss最小 即w = -1的最优参数w

image.png

随着loss的减小 w趋向-1最终找到了w=-1使loss最小

把学习率改为0.01:
image.png
学习率过小时,参数更新缓慢,40次迭代后未能找到最优值

把学习率改为0.999:
image.png

学习率过大时,参数在最优值两边跳动,同样没有找到最优值

最后修改:2021 年 08 月 21 日
如果觉得我的文章对你有用,请随意赞赏