深度学习开源框架

文章目录

  • 1. 深度学习框架
    • 1.1 概述
    • 1.2 深度学习框架—关于组件
      • 1.2.1 组件—张量
      • 1.2.2 基于张量的各种操作
      • 1.2.3 计算图
      • 1.2.4 自动微分工具
      • 1.2.5 拓展包
  • 2. 主流深度学习框架
    • 2.1 市面上主流框架
    • 2.2 本土深度学习框架
    • 2.3 深度学习框架的标准化--ONNX
  • 3. Tensorflow
    • 3.1 Tensorflow—基本用法
    • 3.2 Tensorflow—构建图
    • 3.3 Tensorflow—Tensor(张量)
    • 3.4 Tensorflow—变量(Variables)
    • 3.5 Tensorflow—fetch/feed
    • 3.6 完整的tensorflow代码示例
    • 3.7 拓展-Tensorflow--可视化工具TensorBoard
  • 4. Pytorch
    • 4.1 概述
    • 4.2 Pytorch的优势
    • 4.3 Pytorch-常用工具包
    • 4.4 Pytorch-Tensor
    • 4.5 Pytorch-自动求导
    • 4.6 Pytorch-神经网络
    • 4.7 Pytorch实现MNIST分类
  • 5. 优化算法
    • 5.1 SGD(随机梯度下降)
    • 5.2 Momentum
    • 5.3 拓展--RMSprop(Root Mean Square Prop)
    • 5.4 拓展--RMSprop(Root Mean Square Prop)
    • 5.5 拓展--Adam

1. 深度学习框架

1.1 概述

深度学习框架是用于构建和训练深度学习模型的软件库或工具,它可以提供清晰的、高级的编程接口以及预训练的模型,使得开发者更加容易地设计和实现深度学习模型。以下是一些常见的深度学习框架:

  1. TensorFlow: 由Google Brain团队开发的开源库,适合多种应用,并在硬件加速、分布式计算、生产部署等方面具有优势。
  2. PyTorch: 由Facebook的AI研究团队开发的开源库,对于研究者来说,它的动态计算图特性可以提供更高的灵活性。
  3. Keras: 可以视为TensorFlow的高级封装,更注重用户体验和易用性。
  4. Caffe/Caffe2: Caffe最初由Berkeley Vision and Learning Center (BVLC)开发,主要针对卷积神经网络和图像处理。Caffe2则是Facebook对其进行了改进和扩展。
  5. MXNet: 由Apache Software Foundation维护,支持多种编程语言,并且可以进行分布式计算。
  6. Microsoft Cognitive Toolkit (CNTK): 由微软开发,优势在于其对大型、分布式深度学习的支持。

应用优势:

  • 深度学习框架的出现降低了入门的门槛,你不需要从复杂的神经网络开始编代码,你可以依据需要,使用已有的模型,模型的参数你自己训练得到,你也可以在已有模型的基础上增加自己的layer,或者是在顶端选择自己需要的分类器和优化算法(比如常用的梯度下降法)。
  • 当然也正因如此,没有什么框架是完美的,就像一套积木里可能没有你需要的那一种积木,所以不同的框架适用的领域不完全一致。
  • 总的来说深度学习框架提供了一系列的深度学习的组件(对于通用的算法,里面会有实现),当需要使用新的算法的时候就需要用户自己去定义,然后调用深度学习框架的函数接口使用用户自定义的新算法。

1.2 深度学习框架—关于组件

大部分深度学习框架都包含以下五个核心组件:

  1. 张量(Tensor) 。这是深度学习框架的核心组件,因为它负责所有的数学运算。例如,TensorFlow中的张量(Tensor)和PyTorch中的张量(Tensor)。
  2. 基于张量的各种操作(Operation)
  3. 计算图(Computation Graph)
  4. 自动微分(Automatic Differentiation)工具
  5. BLAS、cuBLAS、cuDNN等拓展包

1.2.1 组件—张量

在深度学习中,我们通常将张量理解为一个多维数组。在这种情况下,张量提供了一种在任意维度上组织数据的方式。
下面是一些不同维度的张量的例子:

  • 标量(0维张量):一个单独的数值,比如 7 或 3.14。
  • 向量(1维张量):一个数值的一维数组,比如 [1, 2, 3, 4]。
  • 矩阵(2维张量):一个数值的二维数组,可以理解为行和列,比如 [[1, 2, 3], [4, 5, 6], [7, 8, 9]]。
  • 3维张量:一个数值的三维数组,比如 [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]。

在深度学习中,我们经常需要处理更高维度的张量。例如,一个彩色图像可以被表示为一个3维张量。其高和宽对应于图像的像素,而深度(通道数)对应于颜色通道(红,绿,蓝)。如果我们有一个图像批次(例如,用于训练卷积神经网络的一组图像),那么我们可以使用一个4维张量来表示这个批次,其中第一个维度表示图像的索引

1.2.2 基于张量的各种操作

这里的一系列操作包含的范围很宽,可以是简单的矩阵乘法,也可以是卷积、池化和LSTM等稍复杂的运算。而且各框架支持的张量操作通常也不尽相同。

1.2.3 计算图

即流程图
在这里插入图片描述

在tensorflow框架中,可以帮助我们将代码的计算图画出来

1.2.4 自动微分工具

用于训练深度学习模型的算法,通常需要进行大量的微分操作。自动微分库可以自动计算这些微分

1.2.5 拓展包

  • 此前的大部分实现都是基于高级语言的(如Java、Python、Lua等),而即使是执行最简单的操作,高级语言也会比低级语言消耗更多的CPU周期,更何况是结构复杂的深度神经网络,因此运算缓慢就成了高级语言的一个天然的缺陷。
  • 由于低级语言的最优化编程难度很高,而且大部分的基础操作其实也都有公开的最优解决方案,因此一个显著的加速手段就是利用现成的扩展包。

2. 主流深度学习框架

2.1 市面上主流框架

  1. TensorFlow
  2. Keras
  3. PyTorch
  4. MXNet
  5. Caffe
  6. Caffe2
  7. Theano
  8. FastAI
  9. CNTK
  10. Gluon
  11. Torch
  12. Deeplearning4j
  13. Chainer

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

顶级深度学习框架四大阵营:

  1. TensorFlow,前端框架Keras,背后巨头Google;
  2. PyTorch,前端框架FastAI,背后巨头Facebook;
  3. MXNet,前端框架Gluon,背后巨头Amazon;
  4. Cognitive Toolkit (CNTK),前端框架Keras或Gluon,背后巨头Microsoft。

2.2 本土深度学习框架

  1. 华为MindSpore:支持端、边、云独立的和协同的统一训练和推理框架。2020年3月28日,正式开源
  2. 百度PaddlePaddle:PaddlePaddle 100% 都在Github上公开,没有内部版本。PaddlePaddle能够应用于自然语言处理、图像识别、推荐引擎等多个领域,其优势在于开放的多个领先的预训练中文模型。
  3. 阿里巴巴XDL (X-Deep Learning):阿里巴巴将把其应用于自身广告业务的算法框架XDL (X-Deep Learning)进行开源。XDL主要是针对特定应用场景如广告的深度学习问题的解决方案,是上层高级API 框架而不是底层框架。XDL需要采用桥接的方式配合使用 TensorFlow 和 MXNet 作为单节点的计算后端,XDL依赖于阿里提供特定的部署环境。
  4. 小米MACE:它针对移动芯片特性进行了大量优化,目前在小米手机上已广泛应用,如人像模式、 场景识别等。该框架采用与 Caffe2 类似的描述文件定义模型,因此它能非常便捷地部署移动端应用。 目前该框架为 TensorFlow 和 Caffe 模型提供转换工具,并且其它框架定义的模型很快也能得到支持。

2.3 深度学习框架的标准化–ONNX

  • 开放神经网络交换(ONNX,“Open Neural Network Exchange”):
    ONNX最初由微软和Facebook联合发布,后来亚马逊也加入进来,并发布了V1版本,宣布支持ONNX 的公司还有AMD、ARM、华为、 IBM、英特尔、Qualcomm等。
  • ONNX是一个表示深度学习模型的开放格式。它使用户可以更轻松地在不同框架之间转移模型。例如,它允许用户构建一个PyTorch模型,然后使用MXNet运行该模型来进行推理。

3. Tensorflow

TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量 (tensor)。它灵活的架构可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或 GPU),服务器,移动设备等等。
在这里插入图片描述

3.1 Tensorflow—基本用法

  1. 使用图 (graph) 来表示计算任务.
  2. 在被称之为 会话 (Session) 的上下文 (context) 中执行图.
  3. 使用 tensor 表示数据.
  4. 通过 变量 (Variable) 维护状态.
  5. 使用 feed 和 fetch 可以为任意的操作(arbitrary operation)赋值或者从其中获取数据。

3.2 Tensorflow—构建图

  1. 创建源op:源op不需要任何输入。例如常量(constant)。源op的输出被传递给其他op做运算。
  2. 在会话(session)中启动图
  3. 关闭session以释放资源

3.3 Tensorflow—Tensor(张量)

构建图的运算过程输出的结果是一个Tensor,主要由三个属性构成:Name、Shape和Type。

  • Name代表的是张量的名字,也是张量的唯一标识符,我们可以在每个op上添加name属性来对节点进行命名,Name的值表示的是该张量来自于第几个输出结果(编号从0开始)
  • Shape代表的是张量的维度。
  • Type表示的是张量的类型,每个张量都会有唯一的类型。我们需要注意的是要保证参与运算的张量类型相一致,否则会出现类型不匹配的错误。

下面是一个简单的tensorflow运行的实例:

import tensorflow as tf

# TensorFlow Python 库有一个默认图 (default graph), op 构造器可以为其增加节点. 
# 这个默认图对许多程序来说已经足够用了. 
# 创建一个常量 op, 产生一个 1x2 矩阵. 这个 op 被作为一个节点加到默认图中.
#
# 构造器的返回值代表该常量 op 的返回值.
matrix1 = tf.constant([[3., 3.]])
# 创建另外一个常量 op, 产生一个 2x1 矩阵.
matrix2 = tf.constant([[2.],[2.]])

# 创建一个矩阵乘法 matmul op , 把 'matrix1' 和 'matrix2' 作为输入.
# 返回值 'product' 代表矩阵乘法的结果.
product = tf.matmul(matrix1, matrix2)

'''
默认图现在有三个节点, 两个 constant() op, 和一个matmul() op. 
为了真正进行矩阵相乘运算, 并得到矩阵乘法的结果, 必须在会话里启动这个图.
启动图的第一步是创建一个 Session 对象, 如果无任何创建参数, 会话构造器将启动默认图.
'''
# 启动默认图.
sess = tf.Session()

# 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数. 
# 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回矩阵乘法 op 的输出.
#
# 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的.
# 
# 函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行.
#
# 返回值 'result' 是一个 numpy `ndarray` 对象.
result = sess.run(product)
print(result)
# ==> [[ 12.]]

# 任务完成, 关闭会话.
sess.close()
'''
session对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 “with” 代码块来自动完成关闭动作.

with tf.Session() as sess:
  result = sess.run([product])
  print (result)
'''

也可以指定硬件运行代码:

'''
在实现上, TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU或 GPU). 
一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测. 
如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作.
如果你的系统里有多个 GPU, 那么 ID 最小的 GPU 会默认使用。
'''
#如果你想要手动指派设备, 你可以用 with tf.device 创建一个设备环境, 这个环境下的 operation 都统一运行在环境指定的设备上.

import tensorflow as tf

# 新建一个graph.
with tf.device('/cpu:0'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b, name = "mul")
print("tesnor: ", c)
'''
如果你指定的设备不存在, 你会收到 InvalidArgumentError 错误提示。
可以在创建的 session 里把参数 allow_soft_placement 设置为 True, 这样 tensorFlow 会自动选择一个存在并且支持的设备来运行 operation.
'''
# 新建session with log_device_placement并设置为True.
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True))
# 运行这个op.
print (sess.run(c))
sess.close()

3.4 Tensorflow—变量(Variables)

变量Variables维护图执行过程中的状态信息.

通常会将一个统计模型中的参数表示为一组变量.
例如, 你可以将一个神经网络的权重作为某个变量存储在一个 tensor 中. 在训练过程中, 通过重复运行训练图, 更新这个 tensor.

import tensorflow as tf

# 创建一个变量, 初始化为标量 0.
state = tf.Variable(0, name="counter")

# 创建一个 op, 其作用是使 state 增加 1
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)

# 启动图后, 变量必须先经过`初始化` (init) op 初始化,
# 首先必须增加一个`初始化` op 到图中.
init_op = tf.global_variables_initializer()

# 启动图, 运行 op
with tf.Session() as sess:
  # 运行 'init' op
  sess.run(init_op)
  # 打印 'state' 的初始值
  print("state",sess.run(state))
  # 运行 op, 更新 'state', 并打印 'state'
  for _ in range(5):
    sess.run(update)
    print("update:",sess.run(state))

3.5 Tensorflow—fetch/feed

Fetch:为了取回操作的输出内容,可以使用session对象的run()调用执行图时,传入一些tensor,这些tensor会帮助你取回结果。

import tensorflow as tf

input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.multiply(input1, intermed)

with tf.Session() as sess:
  result = sess.run([mul, intermed])   #需要获取的多个 tensor 值,在 op 的一次运行中一起获得(而不是逐个去获取 tensor)。
  print(result)

Feed:使用一个tensor值临时替换一个操作的输出结果。可以提供feed数据作为run()调用的参数.

feed 只在调用它的方法内有效, 方法结束, feed 就会消失. 最常见的用例是将某些特殊的操作指定为 “feed” 操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符。

import tensorflow as tf

input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1, input2)

with tf.Session() as sess:
  print(sess.run([output], feed_dict={input1:[7], input2:[2.]}))

# 输出:
# [array([ 14.], dtype=float32)]

placeholder是一个数据初始化的容器,它与变量最大的不同在于placeholder定义的是一个模板,这样我们就可以在session运行阶段,利用feed_dict的字典结构给placeholder填充具体的内容,而无需每次都提前定义好变量的值,大大提高了代码的利用率。

3.6 完整的tensorflow代码示例

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
 
#使用numpy生成200个随机点
x_data=np.linspace(-0.5,0.5,200)[:,np.newaxis]
noise=np.random.normal(0,0.02,x_data.shape)
y_data=np.square(x_data)+noise
 
#定义两个placeholder存放输入数据
x=tf.placeholder(tf.float32,[None,1])
y=tf.placeholder(tf.float32,[None,1])
 
#定义神经网络中间层
Weights_L1=tf.Variable(tf.random_normal([1,10]))
biases_L1=tf.Variable(tf.zeros([1,10]))    #加入偏置项
Wx_plus_b_L1=tf.matmul(x,Weights_L1)+biases_L1
L1=tf.nn.tanh(Wx_plus_b_L1)   #加入激活函数

#定义神经网络输出层
Weights_L2=tf.Variable(tf.random_normal([10,1]))
biases_L2=tf.Variable(tf.zeros([1,1]))  #加入偏置项
Wx_plus_b_L2=tf.matmul(L1,Weights_L2)+biases_L2
prediction=tf.nn.tanh(Wx_plus_b_L2)   #加入激活函数

#定义损失函数(均方差函数)
loss=tf.reduce_mean(tf.square(y-prediction))
#定义反向传播算法(使用梯度下降算法训练)
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
 
with tf.Session() as sess:
    #变量初始化
    sess.run(tf.global_variables_initializer())
    #训练2000次
    for i in range(2000):
        sess.run(train_step,feed_dict={x:x_data,y:y_data})
 
    #获得预测值
    prediction_value=sess.run(prediction,feed_dict={x:x_data})
 
    #画图
    plt.figure()
    plt.scatter(x_data,y_data)   #散点是真实值
    plt.plot(x_data,prediction_value,'r-',lw=5)   #曲线是预测值
    plt.show()

3.7 拓展-Tensorflow–可视化工具TensorBoard

对大部分人而言,深度神经网络就像一个黑盒子,其内部的组织、结构、以及其训练过程很难理清 楚,这给深度神经网络原理的理解和工程化带来了很大的挑战。

为了解决这个问题,tensorboard应运而生。

Tensorboard是tensorflow内置的一个可视化工具,它通过将tensorflow程序输出的日志文件的信息可 视化使得tensorflow程序的理解、调试和优化更加简单高效。

Tensorboard的可视化依赖于tensorflow程序运行输出的日志文件,因而tensorboard和tensorflow程序 在不同的进程中运行。

import tensorflow as tf  

# 定义一个计算图,实现两个向量的减法操作  
# 定义两个输入,a为常量,b为变量  
a=tf.constant([10.0, 20.0, 40.0], name='a')  
b=tf.Variable(tf.random_uniform([3]), name='b')  
output=tf.add_n([a,b], name='add')  

# 生成一个具有写权限的日志文件操作对象,将当前命名空间的计算图写进日志中  
writer=tf.summary.FileWriter('logs', tf.get_default_graph()) 
writer.close()

#启动tensorboard服务(在命令行启动)
#tensorboard --logdir logs

#启动tensorboard服务后,复制地址并在本地浏览器中打开,

生成一个具有写权限的日志文件操作对象,将当前命名空间的计算图写进日志中
writer=tf.summary.FileWriter(‘logs’, tf.get_default_graph())
writer.close()

启动tensorboard服务(在命令行启动)
tensorboard --logdir logs

启动tensorboard服务后,复制地址并在本地浏览器中打开,
在这里插入图片描述

4. Pytorch

4.1 概述

  • Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(tensor )库,在机器学习和其他数学密集型应用有广泛应用。
  • Pytorch的计算图是动态的,可以根据计算需要实时改变计算图
  • 由于Torch语言采用 Lua,导致在国内一直很小众,并逐渐被支持 Python 的 Tensorflow 抢走用户。作为经典机器学习库 Torch 的端口,PyTorch 为 Python 语言使用者提供了舒适的写代码选择。

这是一个基于Python的科学计算包,其旨在服务两类场合:

  • 替代numpy发挥GPU潜能
  • 一个提供了高度灵活性和效率的深度学习实验性平台

4.2 Pytorch的优势

  1. 简洁:
    PyTorch的设计追求最少的封装,尽量避免重复造轮子。不像 TensorFlow 中充斥着session、graph、operation、 name_scope、variable、tensor、layer等全新的概念,PyTorch 的设计遵循tensor→variable(autograd)→nn.Module 三个由低到高的抽象层次,分别代表高维数组(张量)、自动求导(变量)和神经网络(层/模块),而且这三个 抽象之间联系紧密,可以同时进行修改和操作。
  2. 速度:
    PyTorch 的灵活性不以速度为代价,在许多评测中,PyTorch 的速度表现胜过 TensorFlow和Keras 等框架。
  3. 易用:
    PyTorch 是所有的框架中面向对象设计的最优雅的一个。PyTorch的面向对象的接口设计来源于Torch,而Torch的接口设计以灵活易用而著称,Keras作者最初就是受Torch的启发才开发了Keras。
  4. 活跃的社区:
    PyTorch 提供了完整的文档,循序渐进的指南,作者亲自维护的论坛,供用户交流和求教问题。Facebook 人 工智能研究院对 PyTorch 提供了强力支持。

4.3 Pytorch-常用工具包

  1. torch :类似 NumPy 的张量库,支持GPU;
  2. torch.autograd :基于 type 的自动区别库,支持 torch 之中的所有可区分张量运行;
  3. torch.nn :为最大化灵活性而设计,与 autograd 深度整合的神经网络库;
  4. torch.optim:与 torch.nn 一起使用的优化包,包含 SGD、RMSProp、LBFGS、Adam 等标准优化 方式;
  5. torch.multiprocessing: python 多进程并发,进程之间 torch Tensors 的内存共享;
  6. torch.utils:数据载入器。具有训练器和其他便利功能;
  7. torch.legacy(.nn/.optim) :出于向后兼容性考虑,从 Torch 移植来的 legacy 代码;

特别注意:

通道问题:不同的视觉库对于图像读取的方式不一样,图像的通道也不一样:
opencv的默认imread就是HWC,Pytorch的Tensor为CHW,TensorFlow两者都支持。

4.4 Pytorch-Tensor

Torch 定义了七种 CPU tensor 类型和八种 GPU tensor 类型:
在这里插入图片描述

创建Tensor的常见接口:
在这里插入图片描述

Tensor对象的方法:
在这里插入图片描述

4.5 Pytorch-自动求导

tensor对象通过一系列的运算可以组成动态图,对于每个tensor对象,有下面几个变量控制求导的属性。
在这里插入图片描述

4.6 Pytorch-神经网络

理解pytorch的基础主要从以下三个方面

  1. Numpy风格的Tensor操作。pytorch中tensor提供的API参考了Numpy的设计。
  2. 变量自动求导。在一序列计算过程形成的计算图中,参与的变量可以方便的计算自己对目标函数的 梯度。
  3. 神经网络层与损失函数优化等高层封装。网络层的封装存在于torch.nn模块,损失函数由 torch.nn.functional模块提供,优化函数由torch.optim模块提供。

torch.nn模块提供了创建神经网络的基础构件,这些层都继承自Module类。

下面表格中列出了比较重要的神经网络层组件。
对应的在nn.functional模块中,提供这些层对应的函数实现。

通常对于可训练参数的层使用module,而对于不需要训练参数的层如softmax这些,可以使用functional中的函数

在这里插入图片描述

在这里插入图片描述

  • torch.nn.Module提供了神经网络的基类,当实现神经网络时需要继承自此模块,并在初始化函 数中创建网络需要包含的层,并实现forward函数完成前向计算,网络的反向计算会由自动求 导机制处理。
  • 通常将需要训练的层写在init函数中,将参数不需要训练的层在forward方法里调用对应的函数 来实现相应的层。

在pytorch中跑一个网络就只需要分三步:

  1. 写好网络;
  2. 编写数据的标签和路径索引;
  3. 把数据送到网络。

4.7 Pytorch实现MNIST分类

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms

class Model:
    def __init__(self, net, cost, optimist):
        self.net = net
        self.cost = self.create_cost(cost)
        self.optimizer = self.create_optimizer(optimist)
        pass

    def create_cost(self, cost):
        support_cost = {
            'CROSS_ENTROPY': nn.CrossEntropyLoss(),
            'MSE': nn.MSELoss()
        }

        return support_cost[cost]

    def create_optimizer(self, optimist, **rests):
        support_optim = {
            'SGD': optim.SGD(self.net.parameters(), lr=0.1, **rests),
            'ADAM': optim.Adam(self.net.parameters(), lr=0.01, **rests),
            'RMSP':optim.RMSprop(self.net.parameters(), lr=0.001, **rests)
        }

        return support_optim[optimist]

    def train(self, train_loader, epoches=3):
        for epoch in range(epoches):
            running_loss = 0.0
            for i, data in enumerate(train_loader, 0):
                inputs, labels = data

                self.optimizer.zero_grad()

                # forward + backward + optimize
                outputs = self.net(inputs)
                loss = self.cost(outputs, labels)
                loss.backward()
                self.optimizer.step()

                running_loss += loss.item()
                if i % 100 == 0:
                    print('[epoch %d, %.2f%%] loss: %.3f' %
                          (epoch + 1, (i + 1)*1./len(train_loader), running_loss / 100))
                    running_loss = 0.0

        print('Finished Training')

    def evaluate(self, test_loader):
        print('Evaluating ...')
        correct = 0
        total = 0
        with torch.no_grad():  # no grad when test and predict
            for data in test_loader:
                images, labels = data

                outputs = self.net(images)
                predicted = torch.argmax(outputs, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()

        print('Accuracy of the network on the test images: %d %%' % (100 * correct / total))

def mnist_load_data():
    transform = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize([0,], [1,])])

    trainset = torchvision.datasets.MNIST(root='./data', train=True,
                                            download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=32,
                                              shuffle=True, num_workers=2)

    testset = torchvision.datasets.MNIST(root='./data', train=False,
                                           download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=32,shuffle=True, num_workers=2)
    return trainloader, testloader


class MnistNet(torch.nn.Module):
    def __init__(self):
        super(MnistNet, self).__init__()
        self.fc1 = torch.nn.Linear(28*28, 512)
        self.fc2 = torch.nn.Linear(512, 512)
        self.fc3 = torch.nn.Linear(512, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.softmax(self.fc3(x), dim=1)
        return x

if __name__ == '__main__':
    # train for mnist
    net = MnistNet()
    model = Model(net, 'CROSS_ENTROPY', 'RMSP')
    train_loader, test_loader = mnist_load_data()
    model.train(train_loader)
    model.evaluate(test_loader)

5. 优化算法

深度学习的优化算法主要有GD,SGD,Momentum,RMSProp和Adam算法,还有诸如Adagrad算法, 不过大同小异,理解了前面几个,后面的也就引刃而解了。
在这里插入图片描述

5.1 SGD(随机梯度下降)

SGD 又称 online 的梯度下降, 每次估计梯度的时候, 只选用一个或几个batch训练样本。

当训练数据过大时,用BGD可能造成内存不够用,那么就可以用SGD了。深度学习使用的训练 集一般都比较大(几十万~几十亿)。而BGD算法,每走一步(更新模型参数),为了计算 original-loss上的梯度,就需要遍历整个数据集,这显然效率是很低的。而SGD算法,每次随 机选择一个mini-batch去计算梯度,每走一步只需要遍历一个minibatch(一~几百)的数据。

5.2 Momentum

通常情况我们在训练深度神经网络的时候把数据拆解成一小批一小批地进行训练,这就是我们常用的 mini-batch SGD训练算法,然而虽然这种算法能够带来很好的训练速度,但是在到达最优点的时候并 不能够总是真正到达最优点,而是在最优点附近徘徊。

另一个缺点就是这种算法需要我们挑选一个合适的学习率,当我们采用小的学习率的时候,会导致网 络在训练的时候收敛太慢;当我们采用大的学习率的时候,会导致在训练过程中优化的幅度跳过函数 的范围,也就是可能跳过最优点。

我们所希望的仅仅是网络在优化的时候网络的损失函数有一个很好的收敛速度,同时又不至于摆动幅 度太大。

Momentum(拓展)
在这里插入图片描述

5.3 拓展–RMSprop(Root Mean Square Prop)

在Momentum优化算法中,虽然初步解决了优化中摆动幅度大的问题。所谓的摆动幅度就是在优 化中经过更新之后参数的变化范围。

如下图所示,蓝色的为Momentum优化算法所走的路线,绿色的为RMSProp优化算法所走的路线。
在这里插入图片描述

5.4 拓展–RMSprop(Root Mean Square Prop)

在这里插入图片描述

5.5 拓展–Adam

有了上面两种优化算法,一种可以使用类似于物理中的动量来累积梯度,另一种可以使得收敛速度更 快同时使得波动的幅度更小

那么将两种算法结合起来所取得的表现一定会更好。Adam(Adaptive Moment Estimation)算法是将 Momentum算法和RMSProp算法结合起来使用的一种算法,我们所使用的参数基本和上面的一致,在 训练的最开始我们需要初始化梯度的累积量和平方累积量。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/41347.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

让人恶心的多线程代码,性能怎么优化!

Java 中最烦人的,就是多线程,一不小心,代码写的比单线程还慢,这就让人非常尴尬。 通常情况下,我们会使用 ThreadLocal 实现线程封闭,比如避免 SimpleDateFormat 在并发环境下所引起的一些不一致情况。其实…

【TiDB理论知识 03】TiKV-持久化与数据读取

目录 一 TiKV架构和作用 二 数据持久化 1 RocksDB:写入 写入过程 第一步 :WAL 写日志 (磁盘日志) 第二步:写MemTable (内存中) 第三步 : 转存为immutable MemTable(内存中) …

Web 3.0时代,重塑教育与学习方式的可能性

随着科技的快速发展和互联网的普及,教育领域也面临着巨大的机遇和挑战。Web 3.0时代的到来为教育与学习方式带来了全新的可能性。在这个数字化时代,我们可以探索和利用Web 3.0技术,重塑教育的方式,提供更个性化、互动性和灵活性的…

餐饮业油烟在线监测系统的具体应用 安科瑞 许敏

摘要:本文利用物联网技术,构建了一套餐饮企业智能油烟在线监测系统,该系统前台由厨房端和管道端组成,通过网关接入云平台管理系统,实时监控烟道阀门的启闭、变频风机的启停与风速及功率调节、油烟浓度数据等。结合动态…

RabbitMQ安装及简单使用

说明:RabbitMQ(官网:)是一门异步通讯技术,使用异步通讯技术,可解决同步通讯的一些问题。 安装 本文介绍在云服务器上安装RabbitMQ,操作系统是CentOS 7,远程连接工具是WindTerm&…

opencv -10 基础运算之 图像加权和(图像融合图像修复视频合成)

什么是图像加权和? 所谓图像加权和,就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,可以用公式表示为: dst saturate(src1 𝛼 src2 𝛽 𝛾)式中,satu…

css通过子元素选择父元素

伪类:has选择父元素 td:has(> .unfoldTable){//可选中所有td下包含unfoldTable的class标签的td属性color: red; }td:has(> div){//可选中所有td下包含div标签的td属性color: red; } 特殊举例分析: 个别UI框架个别标签通过事件直接生成或者无法选中的情况。…

SpringAMQP使用

说明:SpringAMQP(官网:https://spring.io/projects/spring-amqp)是基于RabbitMQ封装的一套模板,并利用了SpringBoot对其实现了自动装配,使用起来非常方便。安装和原始使用参考:http://t.csdn.cn…

SpringCloud(五)Gateway 路由网关

一、路由网关 官网地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/ 我们需要连接互联网,那么就需要将手机或是电脑连接到家里的路由器才可以,而路由器则连接光猫,光猫再通过光纤连接到互联网&a…

按键控制led变化

文章目录 按键控制led变化一、简介二、代码三、仿真代码四、仿真结果五、总结 按键控制led变化 一、简介 使用按键控制开发板上一个led灯的亮灭,当按键按下的时候led灯就亮,当再一次按下按键的时候led就不亮了。由于按键存在抖动,按键松开的…

idea 有时提示找不到类或者符号,日志报java: 找不到符号的解决

解决一&#xff1a; idea maven编译成功&#xff0c;运行失败提示找不到符号&#xff0c;主要是get和set方法找不到符号&#xff0c;此时就是idea的lombok版本冲突 IDEA版本导致的Lombok失效&#xff0c;需要更新lombok版本到1.18.14及之后版本得到解决 <dependency>&…

Linux:squid透明代理

在传统代理上进行修改并添加网卡 这次不使用手动代理&#xff0c;而是把网关搞成代理 在下面这个链接里的文章实验下进行修改 Linux&#xff1a;squid传统代理_鲍海超-GNUBHCkalitarro的博客-CSDN博客 完成以后不用再win10上去配置&#xff0c;代理的那一步&#xff0c;然后…

3、Java入门教程【数据类型】

一、概述 java中数据类型分为两大类&#xff1a;【基本数据类型】和【引用数据类型】 二、基础数据类型 数据类型含义默认值取值范围存储大小&#xff08;字节&#xff09;整型byte字节型0-128 到 1271整型short短整型0-2^15 到 2^15-12整型int【默认】整形0-2^31 到 2^31-14…

1186. 删除一次得到子数组最大和;1711. 大餐计数;1834. 单线程 CPU

1186. 删除一次得到子数组最大和 解题思路&#xff1a;如果没做过还不是很好想&#xff0c;当时自己第一反应是双指针&#xff0c;结果是个动态规划的题。 核心就是dp的定义&#xff0c;dp[i][k]表示以arr[i]结尾删除k次的最大和。看到这里其实就有一点思路了 dp[i][0]表示以…

⛳ Git安装与配置

Git安装配置目录 ⛳ Git安装与配置&#x1f3ed; 一&#xff0c;git的安装&#x1f3a8; 1&#xff0c;下载git&#x1f463; 2&#xff0c;下载完成之后&#xff0c;双击安装即可。&#x1f4bb; 3&#xff0c;更改安装目录&#xff08;没有中文且没有空格&#xff09;&#x…

Netty核心技术十一--用Netty 自己 实现 dubbo RPC

1. RPC基本介绍 RPC&#xff08;Remote Procedure Call&#xff09;:远程 过程调用&#xff0c;是一个计算机 通信协议。该协议允许运 行于一台计算机的程序调 用另一台计算机的子程序&#xff0c; 而程序员无需额外地为这 个交互作用编程 两个或多个应用程序都分 布在不同的服…

【已解决】html元素如何使字体占据相同的元素显得整齐

本博文源于自身的亲身实践&#xff0c;让html的文本元素对齐&#xff0c;如果不让其对齐就会变得很丑陋&#xff0c;如下图&#xff0c;那么如何设置才能让元素占据相同呢&#xff1f; 文章目录 1、问题来源2、问题解决思路3、问题解决方案4、问题完整源码及效果 1、问题来源 …

摩尔投票算法(Moore‘s Voting Algorithm)及例题

摩尔投票算法&#xff08;Moores Voting Algorithm&#xff09;及例题 摩尔投票算法简介摩尔投票算法算法思想摩尔投票算法经典题目169. 多数元素229. 多数元素 II6927. 合法分割的最小下标 上午打力扣第 354 场周赛最后十五分钟用摩尔投票算法直接秒了第三题。 摩尔投票算法简…

使用原生Redis命令实现分布式锁

推荐文章&#xff1a; 1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表; ​ 2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据; 3、java后端接口API性能优化技巧 4、SpringBootMyBatis流式查询,处理大规模数据,提高系统的性能和响应…

一零六四、世界杯数据可视化分析(阿里云天池赛)

目录 赛制官方链接 活动背景 活动时间&#xff1a;即日起-12月31日17点 数据说明 世界杯成绩信息表&#xff1a;WorldCupsSummary 世界杯比赛比分汇总表&#xff1a;WorldCupMatches.csv 世界杯球员信息表&#xff1a;WorldCupPlayers.csv 代码实现 赛制官方链接 世界杯…