tensorflow1.x 基础案例2

前言

在TensorFlow 1.x中实现线性回归通常指的是使用静态图的方式,而在TensorFlow 1.x中使用Eager API实现线性回归是在TensorFlow 1.x的晚期版本中引入的,以提供类似于TensorFlow 2.x的编程体验。以下是两种方式的区别、各自的优点以及对比的作用:

TensorFlow 1.x 静态图方式

实现方式:

  • 首先构建一个计算图,包括数据的输入、模型的定义、损失函数和优化器。
  • 使用tf.placeholder来定义输入数据占位符。
  • 通过tf.Session()来启动会话,并在会话中执行图的操作。

优点:

  • 图优化: 静态图允许在执行前对整个计算图进行优化,可能提高执行效率。
  • 多GPU支持: 更好地支持多GPU环境,适合大规模训练。

TensorFlow 1.x Eager API

实现方式:

  • TensorFlow 1.x在其后期版本中通过tf.contrib.eager模块引入了Eager API。
  • 允许立即执行操作,无需构建静态图,操作的返回值可以直接用于进一步的计算。

优点:

  • 即时反馈: 操作执行后立即返回结果,便于调试和实验。
  • 简化的API: 减少了编写和理解代码的复杂性。

对比作用

  • 编程模型: 静态图需要事先定义所有的操作,而Eager API允许逐步执行操作。
  • 易用性: Eager API通常更易于学习和使用,特别是对于习惯了Python即时执行特性的程序员。
  • 灵活性: Eager API提供了更高的灵活性,可以动态地修改和执行操作。
  • 性能: 静态图可能在性能上更有优势,尤其是在需要执行大量预定义计算的情况下。

实际应用

  • 研究和开发: Eager API适合快速迭代和实验,因为它可以即时看到操作结果。
  • 生产环境: 静态图可能更适合生产环境,特别是当模型训练和推断需要高性能和稳定性时。

总结

尽管TensorFlow 1.x的Eager API为1.x版本带来了更现代的编程体验,但它实际上是TensorFlow 2.x中Eager执行的预演。TensorFlow 2.x默认启用Eager执行,提供了更简洁和Pythonic的API,同时保持了向后兼容性。因此,对于新项目,推荐使用TensorFlow 2.x,它结合了1.x的静态图性能和Eager API的易用性。

2.1线性回归

所需的库:

tensorflow    1.12.0
numpy         1.19.5
matplotlib    3.3.4

代码:

# 线性回归
import tensorflow as tf
import numpy
import matplotlib.pyplot as plt
rng = numpy.random

# 参数
learning_rate = 0.01
training_epochs = 1000
display_step = 200

# 训练数据
train_X = numpy.asarray([3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 2.167,
                         7.042, 10.791, 5.313, 7.997, 5.654, 9.27, 3.1])
train_Y = numpy.asarray([1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 1.221,
                         2.827, 3.465, 1.65, 2.904, 2.42, 2.94, 1.3])
n_samples = train_X.shape[0]

# tf 图输入
X = tf.placeholder('float')
Y = tf.placeholder('float')
W = tf.Variable(rng.randn(), name='weight')
b = tf.Variable(rng.randn(), name='bias')

# 创建一个线性模型
pre = tf.add(tf.multiply(X, W), b)

# 均方误差损失
cost = tf.reduce_sum(tf.pow(pre - Y, 2))/(2 * n_samples)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

# 初始化变量(分配默认值)
init = tf.global_variables_initializer()

# 开始训练
with tf.Session() as sess:  # 创建并进入一个TensorFlow会话的上下文管理器
    sess.run(init)  # 运行初始化器init
    for epoch in range(training_epochs):
        for (x, y) in zip(train_X, train_Y):  # 遍历训练数据集,每次迭代提供一对特征x和标签y
            sess.run(optimizer, feed_dict={X: x, Y: y})  # 运行优化器操作,如梯度下降步骤,来更新模型的参数。

        # 记录损失
        if (epoch + 1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
            print(f"epoch{epoch + 1} cost= {c}, W = {sess.run(W)}, b = {sess.run(b)}")

    print("optimization finished!")
    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
    print(f"training cost={training_cost}, W = {sess.run(W)}, b = {sess.run(b)}")

    # 画图
    plt.plot(train_X, train_Y, 'ro', label='Original data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')
    plt.legend()
    plt.show()

输出:

epoch200 cost= 0.08749574422836304, W = 0.30706509947776794, b = 0.3880200982093811
epoch400 cost= 0.08340831100940704, W = 0.29456469416618347, b = 0.47794750332832336
epoch600 cost= 0.08090882748365402, W = 0.28478333353996277, b = 0.5483137965202332
epoch800 cost= 0.07938076555728912, W = 0.27712881565093994, b = 0.6033796668052673
epoch1000 cost= 0.07844720780849457, W = 0.27114012837409973, b = 0.6464620232582092
optimization finished!
training cost=0.07844720780849457, W = 0.27114012837409973, b = 0.6464620232582092

在这里插入图片描述

2.2 使用 TensorFlow 的 Eager API 实现线性回归

代码:

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 设置Eager API
tf.enable_eager_execution()
tfe = tf.contrib.eager

# 训练数据
train_X = [3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 2.167,
           7.042, 10.791, 5.313, 7.997, 5.654, 9.27, 3.1]
train_Y = [1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 1.221,
           2.827, 3.465, 1.65, 2.904, 2.42, 2.94, 1.3]
n_samples = len(train_X)

# 参数设置
learning_rate = 0.01
display_step = 200
num_steps = 1000

# 权重与偏置
W = tfe.Variable(np.random.randn())
b = tfe.Variable(np.random.randn())

# 线性回归
def linear_regression(inputs):
    return inputs * W + b

# 均方误差
def mean_square_fn(model_fn, inputs, labels):
    return tf.reduce_sum(tf.pow(model_fn(inputs) - labels, 2)) / (2 * n_samples)

# 梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)

# 计算梯度
grad = tfe.implicit_gradients(mean_square_fn)

# 初始损失
print(f"初始损失:{mean_square_fn(linear_regression, train_X, train_Y)}, W = {W.numpy()}, b = {b.numpy()}.")

# 开始训练
for step in range(num_steps):
    optimizer.apply_gradients(grad(linear_regression, train_X, train_Y))
    if (step + 1) % display_step == 0 or step == 0:
        print(f"Epoch:{step + 1}, 损失:{mean_square_fn(linear_regression, train_X, train_Y)}, W = {W.numpy()}, b = {b.numpy()}.")

plt.plot(train_X, train_Y, 'ro', label='初始数据')
plt.plot(train_X, np.array(W * train_X + b), label='拟合曲线')
plt.legend()
plt.show()

输出结果:

初始损失:25.554563522338867, W = 1.414129614830017, b = 0.1566573679447174.
Epoch:1, 损失:7.765857696533203, W = 0.9393506050109863, b = 0.09066701680421829.
Epoch:200, 损失:0.10071783512830734, W = 0.33907845616340637, b = 0.17886608839035034.
Epoch:400, 损失:0.09156356751918793, W = 0.32022035121917725, b = 0.3125614523887634.
Epoch:600, 损失:0.08593194931745529, W = 0.3054291903972626, b = 0.41742414236068726.
Epoch:800, 损失:0.0824674665927887, W = 0.2938278913497925, b = 0.4996721148490906.
Epoch:1000, 损失:0.08033612370491028, W = 0.2847285568714142, b = 0.5641824007034302.

在这里插入图片描述

小tips

权重(W)和偏置(b)的初始化已经在创建这两个变量时完成了。这是通过使用tf.Variable来实现的,并且使用numpy.random.randn()生成了随机数作为它们的初始值。:

W = tf.Variable(rng.randn(), name='weight')
b = tf.Variable(rng.randn(), name='bias')

如果想给权重和偏置赋予初始值,可以这样:

W = tf.Variable(0.4, name='weight')
b = tf.Variable(0.7, name='bias')

结果对比:

随机数赋初值:

training cost=0.07943815737962723, W = 0.22219787538051605, b = 0.998549222946167

手动赋初值:

training cost=0.07706085592508316, W = 0.25450703501701355, b = 0.7661195993423462

赋初值的优点:

  • 能够精确控制模型参数的起始点,有助于调试和验证模型的行为;
  • 从特定的值开始训练可以提高模型的稳定性和收敛速度;
  • 使用固定的初始值时,实验结果是可重复的,这对于科学研究和调试至关重要。
  • 适当的初始化可以减少过拟合的风险
  • 在超参数调优过程中,固定的初始化策略可以确保不同设置之间的比较是公平的。
  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值