当前位置: 首页 > news >正文

深度学习总结(10)

TensorFlow

训练神经网络主要围绕以下概念进行。
首先是低阶张量操作。这是所有现代机器学习的底层架构,可以转化为TensorFlow API。
张量,包括存储神经网络状态的特殊张量(变量)​。
张量运算,比如加法、relu、matmul。
反向传播,一种计算数学表达式梯度的方法(在TensorFlow中通过GradientTape对象来实现)​。

然后是高阶深度学习概念。这可以转化为Keras API。
层,多层可以构成模型。
损失函数,它定义了用于学习的反馈信号。
优化器,它决定学习过程如何进行。
评估模型性能的指标,比如精度。训练循环,执行小批量梯度随机下降。

常数张量和变量

要使用TensorFlow,需要用到张量。创建张量需要给定初始值。可以创建全1张量或全0张量​,也可以从随机分布中取值来创建张量​。

代码清单 全1张量或全0张量

import tensorflow as tf
#等同于np.ones(shape=(2, 1))
x = tf.ones(shape=(2, 1))
print(x)
#等同于np.zeros(shape=(2, 1))
x = tf.zeros(shape=(2, 1))
print(x)

tf.Tensor(
[[1.]
 [1.]], shape=(2, 1), dtype=float32)
tf.Tensor(
[[0.]
 [0.]], shape=(2, 1), dtype=float32)

代码清单 随机张量

#从均值为0、标准差为1的正态分布中抽取的随机张量,等同于np.random.normal(size=(3, 1), loc=0., scale=1.)
x = tf.random.normal(shape=(3, 1), mean=0., stddev=1.)  
print(x)

 # ←----从0和1之间的均匀分布中抽取的随机张量,等同于np.random.uniform(size=(3, 1), low=0., high=1.)
x = tf.random.uniform(shape=(3, 1), minval=0., maxval=1.) 
print(x)

tf.Tensor(
[[0.14704846]
 [1.0228435 ]
 [1.5658393 ]], shape=(3, 1), dtype=float32)
tf.Tensor(
[[0.73094225]
 [0.16863608]
 [0.27103436]], shape=(3, 1), dtype=float32)

TensorFlow张量是不可赋值的,它是常量。在NumPy中,你可以执行以下操作。

import numpy as np
x = np.ones(shape=(2, 2))
x[0, 0] = 0.

如果在TensorFlow中执行同样的操作)​,那么程序会报错​。

代码清单 TensorFlow张量是不可赋值的

#←----程序会报错,因为张量是不可赋值的
x = tf.ones(shape=(2, 2))  
x[0, 0] = 0.

要训练模型,我们需要更新其状态,而模型状态是一组张量。如果张量不可赋值,这时就需要用到变量(variable)​。tf.Variable是一个类,其作用是管理TensorFlow中的可变状态。要创建一个变量,你需要为其提供初始值。通过打印变量(variable),我们可以看到它和之前的tensorflow里面的张量是不同的。

代码清单 创建一个TensorFlow变量

v = tf.Variable(initial_value=tf.random.normal(shape=(3, 1)))
print(v)

<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[ 1.0559866 ],
       [ 0.28642738],
       [-1.1775647 ]], dtype=float32)>

变量的状态可以通过其assign方法进行修改。

代码清单 为TensorFlow变量赋值

v.assign(tf.ones((3, 1)))

这种方法也适用于变量的子集。

代码清单 为TensorFlow变量的子集赋值

v[0, 0].assign(3.)

assign_add()和assign_sub()分别等同于+=和-=的效果。

代码清单 使用assign_add()

v.assign_add(tf.ones((3, 1)))

张量运算:用TensorFlow进行数学运算

TensorFlow提供了许多张量运算来表达数学公式。

a = tf.ones((2, 2))
#求平方
b = tf.square(a)
# 求平方根
c = tf.sqrt(a)
# 两个张量(逐元素)相加
d = b + c 
#  ←----计算两个张量的点积
e = tf.matmul(a, b)
#  两个张量(逐元素)相乘
e *= d

GradientTape API

通过tensorflow,只需要创建一个GradientTape作用域,对一个或多个输入张量做一些计算,然后就可以检索计算结果相对于输入的梯度,

代码清单 使用GradientTape

input_var = tf.Variable(initial_value=3.)
with tf.GradientTape() as tape:
   result = tf.square(input_var)
gradient = tape.gradient(result, input_var)

要检索模型损失相对于权重的梯度,最常用的方法是gradients = tape.gradient(loss,weights)。。至此,你只遇到过tape.gradient()的输入张量是TensorFlow变量的情况。实际上,它的输入可以是任意张量。但在默认情况下只会监视可训练变量(trainable variable)​。如果要监视常数张量,那么必须对其调用tape.watch(),手动将其标记为被监视的张量。

代码清单 对常数张量输入使用GradientTape

input_const = tf.constant(3.)
with tf.GradientTape() as tape:
   tape.watch(input_const)
   result = tf.square(input_const)
gradient = tape.gradient(result, input_const)

之所以必须这么做,是因为如果预先存储计算梯度所需的全部信息,那么计算成本非常大。为避免浪费资源,梯度带需要知道监视什么。它默认监视可训练变量,因为计算损失相对于可训练变量列表的梯度,是梯度带最常见的用途。梯度带是一个非常强大的工具,它甚至能够计算二阶梯度(梯度的梯度)​。举例来说,物体位置相对于时间的梯度是这个物体的速度,二阶梯度则是它的加速度。如果测量一个垂直下落的苹果的位置随时间的变化,并且发现它满足position(time) =4.9 * time ** 2,那么它的加速度是多少?我们可以用两个嵌套的梯度带找出答案。

time = tf.Variable(0.)
with tf.GradientTape() as outer_tape:
    with tf.GradientTape() as inner_tape:
        position =  4.9 * time ** 2
    speed = inner_tape.gradient(position, time)
#内梯度带计算出一个梯度,我们用外梯度带计算这个梯度的梯度。答案自然是4.9 * 2 = 9.8
acceleration = outer_tape.gradient(speed, time)  

本文全部可执行代码贴出:

import tensorflow as tf
#等同于np.ones(shape=(2, 1))
x = tf.ones(shape=(2, 1))
print(x)
#等同于np.zeros(shape=(2, 1))
x = tf.zeros(shape=(2, 1))
print(x)

#从均值为0、标准差为1的正态分布中抽取的随机张量,等同于np.random.normal(size=(3, 1), loc=0., scale=1.)
x = tf.random.normal(shape=(3, 1), mean=0., stddev=1.)
print(x)

# ←----从0和1之间的均匀分布中抽取的随机张量,等同于np.random.uniform(size=(3, 1), low=0., high=1.)
x = tf.random.uniform(shape=(3, 1), minval=0., maxval=1.)
print(x)

print("--------------------------")

v = tf.Variable(initial_value=tf.random.normal(shape=(3, 1)))
print(v)

v.assign(tf.ones((3, 1)))
print(v)

v[0, 0].assign(3.)
print(v)

v.assign_add(tf.ones((3, 1)))
print(v)

a = tf.ones((2, 2))
#求平方
b = tf.square(a)
# 求平方根
c = tf.sqrt(a)
# 两个张量(逐元素)相加
d = b + c
#  ←----计算两个张量的点积
e = tf.matmul(a, b)
#  两个张量(逐元素)相乘
e *= d

input_var = tf.Variable(initial_value=3.)
with tf.GradientTape() as tape:
   result = tf.square(input_var)
gradient = tape.gradient(result, input_var)

input_const = tf.constant(3.)
with tf.GradientTape() as tape:
   tape.watch(input_const)
   result = tf.square(input_const)
gradient = tape.gradient(result, input_const)

time = tf.Variable(0.)
with tf.GradientTape() as outer_tape:
    with tf.GradientTape() as inner_tape:
        position =  4.9 * time ** 2
    speed = inner_tape.gradient(position, time)
#内梯度带计算出一个梯度,我们用外梯度带计算这个梯度的梯度。答案自然是4.9 * 2 = 9.8
acceleration = outer_tape.gradient(speed, time)

运行结果:

在这里插入图片描述

相关文章:

  • 开源实时语音交互大模型Ultravox-cn
  • zynq7020 u-boot 速通
  • 发送加密信息的简单实现【Java】
  • Linux下python虚拟环境搭建及使用
  • k8s 部署spring项目+动态启动pod
  • 【漫话机器学习系列】199.过拟合 vs 欠拟合(Overfit vs Underfit)
  • 常见的归一化(Normalization)方法
  • 【高并发内存池】从零到一的项目:项目介绍、内存池及定长内存池的设计
  • 关于MOS的二十个问题
  • 学习SqlSugar的跨库查询基本用法
  • 【JavaEE】SpringBoot 统一功能处理
  • 视觉SLAM十四讲2nd—学习笔记(一)
  • isce+mintpy水体掩膜
  • “堆积木”式话云原生微服务架构(第一回)
  • Autosar Nm开发问题-部分网络管理报文无法维持网络唤醒
  • 论文阅读笔记——Reactive Diffusion Policy
  • 基于51单片机的正负5V数字电压表( proteus仿真+程序+设计报告+讲解视频)
  • Maven java 项目引入2.0.16版本的slf4j-api后,提示jedis:5.1.0的子依赖slf4j-api:1.7.36与2.0.16冲突
  • (PC+WAP)大气滚屏网站模板 电气电力设备网站源码下载
  • llm开发框架新秀
  • 九号线香网站建设/网络推广是网络营销的基础
  • 乐清做网站建设公司/域名网站查询
  • 装饰网站banner/百度一下首页版
  • 网站建设优化怎么做/2345网址导航官网下载安装
  • 企业门户网站模板html/怎么开个人网站
  • 做外贸有哪些好的免费b2b网站/网络营销的成功案例有哪些