TensorFlow学习(一)

TensorFlow学习(一)

问题引入

某学校决定根据学生德智体成绩评定三好学生。就是说要通过德育分、智育分、体育分求一个综合成绩来评定三好学生。

  • 假设这个学校计算综合成绩的规则是:德育分占60%,智育分占30%,体育分10%。
  • 学生家长知道了孩子的语文、数学、英语的成绩,也知道了孩子的综合成绩,但是不知道求出综合成绩的方法是什么。现在就是想知道每一项成绩的权重值。

分析问题

已知: 学生三科成绩[70,80,90],学生综合成绩75
求: 三科成绩权重值[0.6,0.3,0.1]

用TensorFlow解决

首先导入需要的模块

# 导入所需模块
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

然后定义数据集合

# 定义数据集合
# 设置随机数种子,主要为了保持重复运行数据一致
np.random.seed(1)
# 200行3列的矩阵,200表示200条学生成绩,3表示每项成绩
x_data = np.random.randint(0,101,[200,3])   
# 定义实际权重值
w_ture = np.array([[0.6,0.3,0.1]])
# 根据x_data和w求学生综合成绩y_data,求出结果是[200,1]形状的矩阵
y_data = np.matmul(x_data,w_ture.T)

转换x_data数据类型

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

定义深度学习所需参数和变量

# 定义深度学习需要的变量和参数
# 生成神经网络的参数,3个输入特征(学生成绩),故输入层为3个输入节点;输出层是学生综合成绩,在这次学习中是为了方便计算loss值
w = tf.Variable(tf.random.normal([3,1],stddev=0.1),tf.float32)	# 赋初值为正态分布随机数

lr = 0.001          # 定义学习率
loss_result = []    # 记录每次loss值,方便后面画loss图像
epochs = 500        # 设置循环次数

定义训练部分

# 训练部分
for epoch in range(epochs):
    with tf.GradientTape() as tape: # with结构记录梯度信息
        y = tf.matmul(x_train,w)     # y = w1*x1 + w2*x2 + w3*x3 结果是[200,1]形状的矩阵
        loss = tf.abs(y-y_data)     # 定义loss函数为|y-y_data|
        loss_mean = tf.reduce_mean(loss)
        loss_result.append(loss_mean)    # 将各个epoch的loss平均值记录在loss_result中
    # 计算loss函数对w的梯度
    grad = tape.gradient(loss,w)

    # 实现梯度更新
    w.assign_sub(lr * grad)         # 参数w自更新

    # 每个epoch,打印loss和w信息
    print("epoch:",epoch)
    print("loss_mean:\n",loss_mean)
    print("w:\n",w)
    print('-'*50)

试运行

到这里就可以试运行一下代码了
运行结果如下:

--------------------------------------------------
epoch: 496
loss_mean:
 tf.Tensor(869.7556, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[5.3367324],
       [6.4165573],
       [1.3079062]], dtype=float32)>
--------------------------------------------------
epoch: 497
loss_mean:
 tf.Tensor(591.71313, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[-5.365268 ],
       [-2.7274427],
       [-8.395094 ]], dtype=float32)>
--------------------------------------------------
epoch: 498
loss_mean:
 tf.Tensor(869.7556, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[5.3367324],
       [6.4165573],
       [1.3079062]], dtype=float32)>
--------------------------------------------------
epoch: 499
loss_mean:
 tf.Tensor(591.71313, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[-5.365268 ],
       [-2.7274427],
       [-8.395094 ]], dtype=float32)>
--------------------------------------------------

我们发现其中的权重值w一直在两个值之间震荡,这说明我们的学习率需要调整。重新调整学习率为0.0001再运行

lr = 0.0001 
--------------------------------------------------
epoch: 496
loss_mean:
 tf.Tensor(57.050888, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[-0.11206388],
       [-0.18151736],
       [-0.4973095 ]], dtype=float32)>
--------------------------------------------------
epoch: 497
loss_mean:
 tf.Tensor(89.095985, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[0.9581361 ],
       [0.7328826 ],
       [0.47299045]], dtype=float32)>
--------------------------------------------------
epoch: 498
loss_mean:
 tf.Tensor(57.050888, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[-0.11206388],
       [-0.18151736],
       [-0.4973095 ]], dtype=float32)>
--------------------------------------------------
epoch: 499
loss_mean:
 tf.Tensor(89.095985, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[0.9581361 ],
       [0.7328826 ],
       [0.47299045]], dtype=float32)>
--------------------------------------------------

发现结果还是在震荡,我们需要更小的学习率。

lr = 0.000001
--------------------------------------------------
epoch: 499
loss_mean:
 tf.Tensor(0.6623709, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[0.6057445 ],
       [0.3035863 ],
       [0.10675556]], dtype=float32)>
--------------------------------------------------

这次运行我们发现结果与我们的真是权重值已经很接近了。

结论

学习率较大的话可能会出现数据震荡现象,这时候需要调小学习率;而学习率过小则会需要更多的训练次数,大家可以尝试。

写完剩下的matplotlib绘制loss图像部分的代码

# 绘制loss图像
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(loss_result)
plt.show()

在这里插入图片描述
可以看出loss值仍然在震荡,我们可以继续缩小学习率,但是没有这个必要了。我们可以优化模型。

优化模型

我们可以重新设计误差函数,例如mse均方误差
Alt

在模型中我们这么写

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

重新设置学习率为0.0001运行试试

lr = 0.0001 
epoch: 499
loss_mean:
 tf.Tensor(1.2128112e-11, shape=(), dtype=float32)
w:
 <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[0.59999996],
       [0.29999995],
       [0.10000006]], dtype=float32)>
--------------------------------------------------

数据很精确,误差甚至只有10e-11数量级


可以发现loss值在训练次数很少的时候就已经变得很小了,我们可以尝试减少训练次数看看结果。

epochs = 50 

在这里插入图片描述
可以看到在循环次数为10次时误差值loss就已经很小了。说明这个误差函数是很高效的。

完整代码

# 已知学生成绩[70,80,90],以及学生综合成绩75
# 求权重值: w = 0.6,0.3,0.1
# 导入所需模块
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 定义数据集合
# 设置随机数种子,主要为了保持重复运行数据一致
np.random.seed(1)
# 200行3列的矩阵,200表示200条学生成绩,3表示每项成绩
x_data = np.random.randint(0,101,[200,3])
# 定义实际权重值
w_ture = np.array([[0.6,0.3,0.1]])
# 根据x_data和w求学生综合成绩y_data,求出结果是[200,1]形状的矩阵
y_data = np.matmul(x_data,w_ture.T)

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

# 定义深度学习需要的变量和参数
# 生成神经网络的参数,3个输入特征(学生成绩),故输入层为3个输入节点;输出层是学生综合成绩,在这次学习中是为了方便计算loss值
w = tf.Variable(tf.random.normal([3,1],stddev=0.1),tf.float32)  # 赋初值为正态分布随机数

lr = 0.0001          # 定义学习率
loss_result = []    # 记录每次loss值,方便后面画loss图像
epochs = 500       # 设置循环次数

# 训练部分
for epoch in range(epochs):
    with tf.GradientTape() as tape: # with结构记录梯度信息
        y = tf.matmul(x_train,w)     # y = w1*x1 + w2*x2 + w3*x3 结果是[200,1]形状的矩阵
        loss = tf.reduce_mean(tf.square(y-y_data))     # 定义loss函数为均方误差mse
        loss_mean = tf.reduce_mean(loss)
        loss_result.append(loss_mean)    # 将各个epoch的loss平均值记录在loss_result中

    # 计算loss函数对w的梯度
    grad = tape.gradient(loss,w)

    # 实现梯度更新
    w.assign_sub(lr * grad)         # 参数w自更新

    # 每个epoch,打印loss和w信息
    print("epoch:",epoch)
    print("loss_mean:\n",loss_mean)
    print("w:\n",w)
    print('-'*50)

# 绘制loss图像
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(loss_result)
plt.show()



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值