PaddleOCR #hello paddle: 从普通程序走向机器学习程序 - 初识机器学习

news2024/12/24 10:49:10

这篇示例向你介绍普通程序跟机器学习程序的区别,并带着你用百度飞桨框架,实现第一个机器学习程序,并初步认识机器学习。

作为一名开发者,你最熟悉的开始学习一门编程语言,或者一个深度学习框架的方式,可能是通过一个 hello world 程序。
学习飞桨也可以这样,这篇小示例教程将会通过一个非常简单的示例来向你展示如何开始使用飞桨。

 

一、普通程序跟机器学习程序的逻辑区别

机器学习程序跟通常的程序最大的不同是,通常的程序是在给定输入的情况下,通过告诉计算机处理数据的规则,然后得到处理后的结果。而机器学习程序则是在并不知道这些规则的情况下,让机器来从数据当中学习出来规则

作为热身,先来看看通常的程序所做的事情。

现在面临这样一个任务:
乘坐出租车的时候,会有一个10元的起步价,只要上车就需要收取。出租车每行驶1公里,需要再支付每公里2元的行驶费用。当一个乘客坐完出租车之后,车上的计价器需要算出来该乘客需要支付的乘车费用。

如果用 python 来实现该功能,会如下所示:

def calculate_fee(distance_travelled):
    return 10 + 2 * distance_travelled

for x in [1.0, 3.0, 5.0, 9.0, 10.0, 20.0]:
    print(calculate_fee(x))

ocr-01-01
接下来,把问题稍微变换一下,现在知道乘客每次乘坐出租车的公里数,也知道乘客每次下车的时候支付给出租车司机的总费用。但是并不知道乘车的起步价,以及每公里行驶费用是多少。 也就是说,除了乘坐总公里数据和总费用,我们并不知道总费的计算规则,我们希望让机器从这些数据当中学习出来计算总费用的规则。

更具体的,想要让机器学习程序通过数据学习出来下面的公式当中的参数 w 和参数 b(这是一个非常简单的示例,所以 w 和 b 都是浮点数,随着对深度学习了解的深入,你将会知道 w 和 b 通常情况下会是矩阵和向量)。这样,当下次乘车的时候,知道了行驶里程 distance_travelled 的时候,就可以估算出来用户的总费用 total_fee 了。

total_fee = w * distance_travelled + b

接下来,看看用飞桨如何实现这个 hello, world 级别的机器学习程序。

 

二、导入飞桨

为了能够使用飞桨,需要先用 python 的 import 语句导入飞桨 paddle。同时,为了能够更好的对数组进行计算和处理,还需要导入 numpy。
如果你是在本机实验,且还没有安装飞桨,请先参考:PaddleOCR #使用PaddleOCR进行光学字符识别 - OCR飞桨实验
亦或者参考官网安装 PaddlePaddle 2.3.0: 开始使用_飞桨-源于产业实践的开源深度学习平台

import paddle
print("paddle " + paddle.__version__)

结果参考:

paddle 2.4.2

 

三、数据准备

在这个机器学习任务中,已经知道了乘客的行驶里程 distance_travelled,和对应的这些乘客的总费用 total_fee。
通常情况下,在机器学习任务中,像 distance_travelled 这样的输入值,一般被称为x(或者特征feature),像 total_fee 这样的输出值,一般被称为y(或者标签label)。
可以用 paddle.to_tensor 把示例数据转换为 paddle 的 Tensor 数据。

x_data = paddle.to_tensor([[1.], [3.0], [5.0], [9.0], [10.0], [20.0]])
y_data = paddle.to_tensor([[12.], [16.0], [20.0], [28.0], [30.0], [50.0]])

 

四、用飞桨定义模型的计算

使用飞桨定义模型的计算的过程,本质上,是用python,通过飞桨提供的API,来告诉飞桨计算规则的过程。回顾一下,想要通过飞桨用机器学习方法,从数据当中学习出来如下公式当中的 w 和 b。这样在未来,给定 x 时就可以估算出来 y 值(估算出来的 y 记为 y_predict)

# 如上述 total_fee = w * distance_travelled + b
y_predict = w * x + b

将会用飞桨的线性变换层:paddle.nn.Linear 来实现这个计算过程,这个公式里的变量 x, y, w, b, y_predict,对应着飞桨里面的 Tensor 概念。

稍微补充一下:在这里的示例中,根据经验,已经事先知道了 distance_travelled 和 total_fee 之间是线性的关系,而在更实际的问题当中,x 和 y 的关系通常是非线性的,因此也就需要使用更多类型,也更复杂的神经网络。(比如,BMI指数跟你的身高就不是线性关系,一张图片里的某个像素值跟这个图片是猫还是狗也不是线性关系。)

# y_predict = w * x + b
# 使用 PaddlePaddle 框架定义一个线性层(linear layer)的代码。
# in_features=1  表示输入特征的维度为 1。这意味着线性层的输入是一个大小为 1 的张量或向量。
# out_features=1 表示输出特征的维度为 1。这意味着线性层的输出也是一个大小为 1 的张量或向量。
# 这样的线性层通常被用于将输入特征映射到输出特征,其中每个输入特征与权重相乘,并加上偏置,从而得到输出特征。在这种情况下,输入特征和输出特征的维度都是 1,因此可以看作是一个简单的一对一映射关系。
# 这个线性层可以用于构建神经网络的一部分,或者作为独立的模型使用。
linear = paddle.nn.Linear(in_features=1, out_features=1)

 

五、准备好运行飞桨

机器(计算机)在一开始的时候会随便猜 w 和 b,先看看机器猜的怎么样。
ocr-01-02
你应该可以看到,这时候的 w 是一个随机值,b 是 0.0,这是飞桨的初始化策略,也是这个领域常用的初始化策略。(如果你愿意,也可以采用其他的初始化的方式,今后你也会看到,选择不同的初始化策略也是对于做好深度学习任务来说很重要的一点)。

 

六、告诉飞桨怎么样学习

前面定义好了神经网络(尽管是一个最简单的神经网络),还需要告诉飞桨,怎么样去学习,从而能得到参数 w 和 b。

这个过程简单的来陈述一下,你应该就会大致明白了(尽管背后的理论和知识还需要逐步的去学习)。在机器学习/深度学习当中,机器(计算机)在最开始的时候,得到参数 w 和 b 的方式是随便猜一下,用这种随便猜测得到的参数值,去进行计算(预测)的时候,得到的 y_predict,跟实际的 y 值一定是有差距的。接下来,机器会根据这个差距来调整 w 和 b,随着这样的逐步的调整,w 和 b 会越来越正确,y_predict 跟 y 之间的差距也会越来越小,从而最终能得到好用的 w 和 b。这个过程就是机器学习的过程。

用更加技术的语言来说,衡量差距的函数(一个公式)就是损失函数,用来调整参数的方法就是优化算法。

在本示例当中,用最简单的均方误差(mean square error)作为损失函数(paddle.nn.MSELoss);和最常见的优化算法SGD(stocastic gradient descent)作为优化算法(传给paddle.optimizer.SGD的参数learning_rate,你可以理解为控制每次调整的步子大小的参数)。

# 最简单的均方误差(mean square error)作为损失函数(paddle.nn.MSELoss)
mse_loss = paddle.nn.MSELoss()
# 最常见的优化算法SGD(stocastic gradient descent)作为优化算法,参数learning_rate,可以理解为控制每次调整的步子大小
sgd_optimizer = paddle.optimizer.SGD(learning_rate=0.001, parameters = linear.parameters())

 

七、运行优化算法

接下来,让飞桨运行一下这个优化算法,这会是一个前面介绍过的逐步调整参数的过程,你应该可以看到 loss 值(衡量 y 和 y_predict 的差距的 loss )在不断的降低。

# 总的迭代次数(控制机器学习次数)
total_epoch = 5000
for i in range(total_epoch):
    # 使用线性模型进行预测
    y_predict = linear(x_data)
    # 计算预测值与真实值之间的均方误差损失
    loss = mse_loss(y_predict, y_data)
    # 反向传播,计算梯度
    loss.backward()
    # 使用随机梯度下降优化器更新模型参数
    sgd_optimizer.step()
    # 清除梯度信息,为下一次迭代做准备
    sgd_optimizer.clear_grad()

    if i % 1000 == 0:
        # 打印每隔1000次迭代的损失值
        print("epoch {} loss {}".format(i, loss.numpy()))

# 打印训练完成后的损失值
print("finished training, loss {}".format(loss.numpy()))

ocr-01-03

 

八、机器学习出来的参数

经过了这样的对参数 w 和 b 的调整(学习),再通过下面的程序,来看看现在的参数变成了多少。完整代码如下:

import paddle
paddle.set_device("cpu")
print("paddle " + paddle.__version__)
print("hello paddle")

import paddle

if paddle.is_compiled_with_cuda():
    print("当前使用的是 GPU 模式")
else:
    print("当前使用的是 CPU 模式")

x_data = paddle.to_tensor([[1.], [3.0], [5.0], [9.0], [10.0], [20.0]])
y_data = paddle.to_tensor([[12.], [16.0], [20.0], [28.0], [30.0], [50.0]])
# y_predict = w * x + b
# 使用 PaddlePaddle 框架定义一个线性层(linear layer)的代码。
# in_features=1  表示输入特征的维度为 1。这意味着线性层的输入是一个大小为 1 的张量或向量。
# out_features=1 表示输出特征的维度为 1。这意味着线性层的输出也是一个大小为 1 的张量或向量。
# 这样的线性层通常被用于将输入特征映射到输出特征,其中每个输入特征与权重相乘,并加上偏置,从而得到输出特征。在这种情况下,输入特征和输出特征的维度都是 1,因此可以看作是一个简单的一对一映射关系。
# 这个线性层可以用于构建神经网络的一部分,或者作为独立的模型使用。
linear = paddle.nn.Linear(in_features=1, out_features=1)

# 获取优化后的线性模型的权重,并转换为标量值
w_before_opt = linear.weight.numpy().item()
# 获取优化后的线性模型的偏置,并转换为标量值
b_before_opt = linear.bias.numpy().item()

print("w before optimize: {}".format(w_before_opt))
print("b before optimize: {}".format(b_before_opt))

# 最简单的均方误差(mean square error)作为损失函数(paddle.nn.MSELoss)
mse_loss = paddle.nn.MSELoss()
# 最常见的优化算法SGD(stocastic gradient descent)作为优化算法,参数learning_rate,可以理解为控制每次调整的步子大小
sgd_optimizer = paddle.optimizer.SGD(learning_rate=0.001, parameters = linear.parameters())

# 总的迭代次数(控制机器学习次数)
total_epoch = 5000
print("机器学习次数 {}".format(total_epoch))

for i in range(total_epoch):
    # 使用线性模型进行预测
    y_predict = linear(x_data)
    # 计算预测值与真实值之间的均方误差损失
    loss = mse_loss(y_predict, y_data)
    # 反向传播,计算梯度
    loss.backward()
    # 使用随机梯度下降优化器更新模型参数
    sgd_optimizer.step()
    # 清除梯度信息,为下一次迭代做准备
    sgd_optimizer.clear_grad()

    if i % 1000 == 0:
        # 打印每隔1000次迭代的损失值
        print("epoch {} loss {}".format(i, loss.numpy()))

# 打印训练完成后的损失值
print("finished training, loss {}".format(loss.numpy()))


# 获取优化后的线性模型的权重,并转换为标量值
w_after_opt = linear.weight.numpy().item()
# 获取优化后的线性模型的偏置,并转换为标量值
b_after_opt = linear.bias.numpy().item()

print("w after optimize: {}".format(w_after_opt))
print("b after optimize: {}".format(b_after_opt))

ocr-01-04
你应该会发现 w 变成了很接近 2.0 的一个值,b 变成了接近 10.0 的一个值。虽然并不是正好的 2 和 10,但却是从数据当中学习出来的还不错的模型的参数,可以在未来的时候,用从这批数据当中学习到的参数来预估了。(如果你愿意,也可以通过控制机器学习次数,让机器多学习一段时间,从而得到更加接近 2.0 和 10.0 的参数值。)

 

九、hello paddle

通过这个小示例,希望你已经初步了解了飞桨,能在接下来随着对飞桨的更多学习,来解决实际遇到的问题。

 

十、参考文档

paddlepaddle官方文档:hello paddle: 从普通程序走向机器学习程序-使用文档-PaddlePaddle深度学习平台
paddlepaddle官方文档:开始使用_飞桨-源于产业实践的开源深度学习平台

系列攻略:
PaddleOCR #使用PaddleOCR进行光学字符识别 - OCR飞桨实验
PaddleOCR #使用PaddleOCR进行光学字符识别 - OCR模型对比

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

万字长文:大模型训练避坑指南

自 2022 年 11 月底 ChatGPT 发布以来,大模型的热度持续发酵,相信高屋建瓴的讨论大家已经看了很多了。今天我们选择从实用角度,分别就算力、算法、工程、数据和团队等方向讨论了训练一个千亿参数量级的大语言模型和 ChatGPT 需要些什么&#…

4.17 TCP三次握手 4.18滑动窗口 4.19TCP四次挥手

4.17 TCP三次握手 TCP 是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如 IP 地址、端口号等。 TCP 可以看成是一种字节流&a…

i.MX 91x推出,飞凌嵌入式携手NXP打造更强大、更经济、更安全的解决方案

NXP在COMPUTEX 2023上发布了i.MX 91应用处理器系列,作为i.MX 9系列的入门级产品,i.MX 91x简化了高性价比边缘设备的开发过程,助力构建需要安全性、高性能表现以及Linux支持的可扩展、高可靠性的平台,可满足下一代基于Linux的物联网…

【数据库三】MySQL索引

MySQL索引、事务与存储引擎 1.MySQL索引1.1 索引的概念1.2 索引的作用​1.3 索引的副作用​1.4 创建索引的原则依据​ 2.索引的分类和创建2.1 普通索引2.2 唯一索引2.3 主键索引2.4 组合索引2.5 全文索引 3. 查看索引4.删除索引5. 知识点总结 1.MySQL索引 1.1 索引的概念 索引…

基于html+css的图展示127

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Unity光照贴图的切换,实现黑夜和白天效果

有这么一个需求,不能使用实时光来进行动态控制光照开关,但是又要实现白天和黑夜的效果,我的场景中有大概十几个点光源和平行光 实现步骤: 一、模型原模原样复制到另一个场景中(因为贴图只能存在于当前的场景文件夹&am…

618私藏好物推荐!看这份清单就够了!

又到了一年一度的618,相信大家的购物车已经堆得满满的, 部分人已经选好了自己想要的东西,但也有一部分人还在纠结自己到底应该买什么。今天就给大家分享我的618私藏好物, 如果你想在这个夏天买到自己心仪的好物,建议你…

IIC总线 测温度和湿度

iic.c #include "iic.h"extern void printf(const char* fmt, ...); /** 函数名 : delay_us* 函数功能:延时函数* 函数参数:无* 函数返回值:无* */ void delay_us(void) {unsigned int i 2000;while(i--); } /** 函数…

字符设备驱动的内部实现

1.inode号的功能 :①inode号是文件存在于文件系统的唯一标识1 ②同时也是索引当前文件的inode结构体的索引导 2.文件信息结构体:只要文件存在于文件系统中,那么内核中一定会存在一个struct inode结构体,这个结构体里面存放了文件…

详解Http的Content-Type

目录 1.概述 2.常用类型 2.1.application/x-www-form-urllencoded 2.2.application/json 3.Spring MVC支持的编码 3.1.实验 3.2.适配器 3.3.自定义适配器 1.概述 HTTP(HyperText Transfer Protocol),超文本传输协议。超文本&#xf…

从redis-trib.rb到集群加减节点实战

redis-trib.rb工具介绍 redis-trib.rb是redis集群管理工具,可以检查集群、创建删除节点、挪key、批量下发实例命令等等。 不是没有redis-trib.rb就没有集群管理了,没有redis-trib.rb照样可以管理集群。redis本身就有集群相关管理命令,redis-…

2021年系统架构设计师考试下午案例分析真题

试题一 阅读以下关于软件架构设计与评估的叙述,在答题纸上回答问题1和问题2。 [说明] 某公司拟开发-套机器学习应用开发平台,支持用户使用浏览器在线进行基于机器学习的智能应用开发活动。 该评台的核心应用场景是用户通过拖拽算法组件灵活定义机器学习流程&#…

“6511”成果显著,联诚发上半年表现企稳高升!

六场巡回演唱会,五大知名展会,一部爆款大电影,一项省级品牌荣誉。 这些关键词,是联诚发(LCF)在短短六个月内取得的各项成果的总览。 ▲联诚发LCF 公司简介 绿树阴浓夏日长,6月的到来也预示着阶…

让小脚本成为自己高效测试的工具(详细版)

目录 测试中会遇到的工具 测试常用的开源工具 Python 移动/UI自动化测试平台 平台需要做什么 自建需要的技术 接口测试平台 运维 Django运维部署框架 单元测试概述 什么是单元测试 单元测试什么进行? 单元测试由谁负责? 单元测试需要注意 …

opencv祛除高光

代码是直接借鉴的Opencv去除高光_SkyrimDragonBorn的博客-CSDN博客 原博客是c,我这边只是使用python进行翻译了一下 import cv2 import numpy as npimg cv2.imread(xxx.jpg)def highlight_remove(img):img cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.floa…

java0615

01java语言背景介绍 02java语言跨平台原理 03JRE和JDK

View UI Plus (iview)表格单选实现教程

View UI Plus 是 View Design 设计体系中基于 Vue.js 3 的一套 UI 组件库,主要用于企业级中后台系统 View UI,即原先的 iView,从 2019 年 10 月起正式更名为 View UI,并使用全新的 Logo View UI Plus 实现表格单选,这…

八股文总结

文章目录 项目介绍1.不动产项目项目难点机器学习算法调研图像提取算法调研数据集-ImageNetXceptionVGGInceptionDensenetMobilenet 系统流程图 2.图书项目技术栈ShiroMybatisMyBatis:Mybatis Plus: 面试问题 Java基础基本数据类型反射接口和抽象类异常代理模式1. 静态代理2. 动…

Java Logback日志框架概述及logback.xml详解

日志技术具备的优势 可以将系统执行的信息选择性的记录到指定的位置(控制台、文件中、数据库中)。 可以随时以开关的形式控制是否记录日志,无需修改源代码。 日志体系结构 Logback日志框架 Logback是由log4j创始人设计的另一个开源日志组件&#xff0…

Android classLoader 双亲委托 反射

双亲委托 双亲委托机制,就是导入类的时候判断parent是否已经导入过该类。 作用 1、避免重复加载,当父加载器已经加载了该类的时候,没有必要子ClassLoader再加载一次。 2、安全性考虑,防止核心API库被随意篡改。 核心代码 pri…