用华为MindSpore框架训练数据库类型的数据集
技术背景
在前面一篇博客我们讲到三种用python去读取一个文件的指定行的操作,最终给出的一个结论大概是,对于大型的数据而言,最快的找到指定行的方法是Linux系统自带的sed
指令,那么是否只有这一种办法了呢?很显然不是,之所以采用这些方法,是因为我们被局限在数据的存储格式上,如果在处理数据或者产生数据的阶段,就把数据按照特定的数据结构进行存储,那么就能够大大的提高数据读取的效率。这里我们要介绍一个用sqlite3
来读取数据用于MindSpore的训练的案例,在有限的内存空间中避免完整的去加载整个数据集。
Sqlite3产生随机数据
因为大部分的Python中是预装了sqlite3的,这就避免了我们自己再去重复安装的麻烦,比如Spark和PySpark就是安装起来比较麻烦的典型案例,当然其性能和分布式的处理也是非常具有优越性的。这里我们看一个用sqlite3产生训练数据的案例,这个案例的原型来自于这篇博客,其函数表达形式为:
\]
# store_data_to_db.py
import numpy as np
import sqlite3
from tqdm import trange
conn = sqlite3.connect('xyz.db') # 创建或者链接一个已有db文件
cur = conn.cursor()
try:
sql_1 = '''CREATE TABLE number
(i NUMBER,
x NUMBER,
y NUMBER,
z NUMBER);'''
cur.execute(sql_1) # 执行数据库指令,创建一个新的表单
except:
pass
def get_data(num, a=2.0, b=3.0, c=5.0):
for _ in trange(num):
x = np.random.uniform(-1.0, 1.0)
y = np.random.uniform(-1.0, 1.0)
noise = np.random.normal(0, 0.03)
z = a * x ** 2 + b * y ** 3 + c + noise # 计算数据
# 将一行数据写入数据库
cur.execute("INSERT INTO number VALUES({},{},{},{})".format(_, x**2, y**3, z))
get_data(100) # 产生100组数据
conn.commit()
cur.close()
conn.close()
在这个案例中我们一共产生了100组的测试数据,运行过程如下:
(base) dechin@ubuntu2004:~/projects/gitlab/dechin/src/mindspore$ python3 store_data_to_db.py
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:00<00:00, 29504.11it/s]
(base) dechin@ubuntu2004:~/projects/gitlab/dechin/src/mindspore$ ll | grep xyz.db
-rw-r--r-- 1 dechin dechin 8192 6月 1 15:43 xyz.db
运行完成后,会在当前目录下产生一个名为xyz.db
的数据库文件,在可迁移性上是比较灵活的。需要特别提及的是,这里我们不仅存储了x,y,z这3个变量,同时也存储了index数据,这样方便我们对数据进行检索和查找。在程序的最后一步,一定要执行commit
才能够将数据保存到数据库文件中,否则不会被保存。
数据库文件的读取
接着上一个章节的内容,我们用Ipython来测试一下是否成功的将数据写入到了数据库文件中(这里number
是表单的名字):
(base) dechin@ubuntu2004:~/projects/gitlab/dechin/src/mindspore$ ipython
Python 3.8.5 (default, Sep 4 2020, 07:30:14)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import sqlite3
In [2]: conn = sqlite3.connect('xyz.db')
In [3]: cur = conn.cursor()
In [4]: cur.execute('SELECT * FROM number WHERE i=0')
Out[4]: <sqlite3.Cursor at 0x7fd08bd5cc70>
In [5]: print (cur.fetchall())
[(0, 0.0099305893254821, -0.003805282402773131, 5.014158221453069)]
In [6]: cur.execute('SELECT * FROM number WHERE i=99')
Out[6]: <sqlite3.Cursor at 0x7fd08bd5cc70>
In [7]: print (cur.fetchall())
[(99, 0.1408058052492868, -0.5207606243222331, 3.7101686456005116)]
In [8]: cur.execute('SELECT * FROM number WHERE i=100')
Out[8]: <sqlite3.Cursor at 0x7fd08bd5cc70>
In [9]: print (cur.fetchall())
[]
In [10]: cur.close()
...: conn.close()
在这个案例中我们可以看到,成功的读取了第0个数据和第99个数据,如果超过这个范围去检索,会返回一个空的值。返回的结果是被包在一个list中的tuple,所以注意读取的方式要用cur.fetchall()[0][0]
才能够读取到这一列中的第一个元素。
与MindSpore的结合
在介绍完数据的产生和存储、数据库文件的读取两个工作后,结合起来我们可以尝试从数据库文件中去加载训练数据,用于MindSpore的模型训练。这里我们不展开去介绍MindSpore的模型和代码,在前面的这一篇博客中有介绍相关的细节,让我们直接看一下代码:
# dataset_test.py
from mindspore import context
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
import numpy as np
from mindspore import dataset as ds
from mindspore import nn, Tensor, Model
import time
from mindspore.train.callback import Callback, LossMonitor
import sqlite3
conn = sqlite3.connect('xyz.db')
cur = conn.cursor()
def get_data(num, a=2.0, b=3.0, c=5.0):
for _ in range(num):
cur.execute('SELECT * FROM number WHERE i={}'.format(_))
data = cur.fetchall()[0]
yield np.array([[float(data[1])],
[float(data[2])]],dtype=np.float32).reshape(1,2), np.array([float(data[3])]).astype(np.float32)
def create_dataset(num_data, batch_size=16, repeat_size=1):
input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['xy','z'])
input_data = input_data.batch(batch_size)
input_data = input_data.repeat(repeat_size)
return input_data
data_number = 100
batch_number = 10
repeat_number = 20
ds_train = create_dataset(data_number, batch_size=batch_number, repeat_size=repeat_number)
class LinearNet(nn.Cell):
def __init__(self):
super(LinearNet, self).__init__()
self.fc = nn.Dense(2, 1, 0.02, 0.02)
def construct(self, x):
x = self.fc(x)
return x
net = LinearNet()
model_params = net.trainable_params()
print ('Param Shape is: {}'.format(len(model_params)))
for net_param in net.trainable_params():
print(net_param, net_param.asnumpy())
net_loss = nn.loss.MSELoss()
optim = nn.Momentum(net.trainable_params(), learning_rate=0.01, momentum=0.6)
model = Model(net, net_loss, optim)
epoch = 1
model.train(epoch, ds_train, callbacks=[LossMonitor(10)], dataset_sink_mode=False)
for net_param in net.trainable_params():
print(net_param, net_param.asnumpy())
cur.close()
conn.close()
跟前面的博客中类似的是,我们还是用了MindSpore的GeneratorDataset
这个方法来构造数据,并且通过get_data
函数逐个的返回数据库中对应位置的数据。可以看一下是否能够成功训练:
(base) dechin@ubuntu2004:~/projects/gitlab/dechin/src/mindspore$ singularity exec --nv /home/dechin/tools/singularity/mindspore-gpu_1.2.0.sif python dataset_test.py
Param Shape is: 2
Parameter (name=fc.weight, shape=(1, 2), dtype=Float32, requires_grad=True) [[0.02 0.02]]
Parameter (name=fc.bias, shape=(1,), dtype=Float32, requires_grad=True) [0.02]
epoch: 1 step: 10, loss is 15.289665
epoch: 1 step: 20, loss is 4.292768
epoch: 1 step: 30, loss is 2.199254
epoch: 1 step: 40, loss is 0.558127
epoch: 1 step: 50, loss is 1.2218236
epoch: 1 step: 60, loss is 2.0977945
epoch: 1 step: 70, loss is 2.0961792
epoch: 1 step: 80, loss is 1.107859
epoch: 1 step: 90, loss is 1.1687267
epoch: 1 step: 100, loss is 1.166467
epoch: 1 step: 110, loss is 0.73308593
epoch: 1 step: 120, loss is 1.2287892
epoch: 1 step: 130, loss is 1.2843382
epoch: 1 step: 140, loss is 1.996727
epoch: 1 step: 150, loss is 1.9126663
epoch: 1 step: 160, loss is 1.1095876
epoch: 1 step: 170, loss is 1.1662093
epoch: 1 step: 180, loss is 2.1144183
epoch: 1 step: 190, loss is 1.6211499
epoch: 1 step: 200, loss is 2.0198507
Parameter (name=fc.weight, shape=(1, 2), dtype=Float32, requires_grad=True) [[1.0131103 0.27144054]]
Parameter (name=fc.bias, shape=(1,), dtype=Float32, requires_grad=True) [5.3248053]
训练完成,虽然我们看到最终拟合出来的数据效果不是很好,但是从流程上来说我们已经达成了通过数据库格式的数据来构造MindSpore的训练数据输入的目的。
总结概要
本文按照数据流的顺序,分别介绍了:使用sqlite3数据库存储数据、从sqlite3数据库中读取数据、使用从sqlite3数据库中的数据构造MindSpore可识别的训练数据集。对于输入的数据量比较大的场景,我们不太可能将全部的数据都加载到内存中,这就要考虑各种可以快速存储和读取的方案,数据库就是一种比较常见的方案。而sqlite3作为一款非常轻量级的数据库,在大部分的Python3中都是内置的,省去了很多编译安装的繁琐。当然性能表现可能不如其他的数据库,但是在我们这边给定的场景下,表现还是非常优秀的!
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/ms-sql.html
作者ID:DechinPhy
更多原著文章请参考:https://www.cnblogs.com/dechinphy/
打赏专用链接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
腾讯云专栏同步:https://cloud.tencent.com/developer/column/91958
用华为MindSpore框架训练数据库类型的数据集的更多相关文章
- 用华为MindSpore进行分布式训练
技术背景 分布式和并行计算,在计算机领域是非常重要的概念.对于一些行外人来说,总觉得这是一些很简单的工作,但是如果我们纵观计算机的硬件发展史,从CPU到GPU,再到TPU和华为的昇腾(NPU),乃至当 ...
- RDIFramework.NET 框架兼容各种数据库类型事务使用范例参考
RDIFramework.NET 框架兼容各种数据库类型事务使用范例参考 RDIFramwork.NET框架对数据库的事务做了很好的控制,对多表或多条语句需要在同一事务执行提供了很好的支持,同时支持任 ...
- 1.NetDh框架之数据库操作层--Dapper简单封装,可支持多库实例、多种数据库类型等(附源码和示例代码)
1.NetDh框架开始的需求场景 需求场景: 1.之前公司有不同.net项目组,有的项目是用SqlServer做数据库,有的项目是用Oracle,后面也有可能会用到Mysql等,而且要考虑后续扩展成主 ...
- 基于MIndSpore框架的道路场景语义分割方法研究
基于MIndSpore框架的道路场景语义分割方法研究 概述 本文以华为最新国产深度学习框架Mindspore为基础,将城市道路下的实况图片解析作为任务背景,以复杂城市道路进行高精度的语义分割为任务目标 ...
- Winform开发框架中实现同时兼容多种数据库类型处理
在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适 ...
- Winform开发框架中实现多种数据库类型切换以及分拆数据库的支持
在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适 ...
- Spring MVC动态切换数据源(多数据库类型)
最近由于项目需求,需要将Sql Server 和 Mysql 两种数据库整合到一个项目,项目的用到的框架是SSM. 因此尝试了利用AOP切面来切每次执行的Servcie方法,根据Service所在的包 ...
- ThinkPhp框架对“数据库”的基本操作
框架有时会用到数据库的内容,在"ThinkPhp框架知识"的那篇随笔中提到过,现在这篇随笔详细的描述下. 数据库的操作,无疑就是连接数据库,然后对数据库中的表进行各种查询,然后就是 ...
- TP框架对数据库的基本操作
数据库的操作,无疑就是连接数据库,然后对数据库中的表进行各种查询,然后就是对数据的增删改的操作,一步步的讲述一下框架对数据库的操作 想要操作数据库,第一步必然是要:链接数据库 一.链接数据库 (1)找 ...
随机推荐
- MySQL学习之路(一)锁机制
1 锁的分类 1.1 操作类型 读锁(共享锁):针对同一份数据,多个操作可以同时进行而不会互相影响 写锁(排它锁):当写操作没有完成前,它会阻塞其他读锁或者写锁 1.2 操作粒度 表锁:锁住整张表 行 ...
- kubernetes资源优化
kubernetes资源优化方向 系统参数限制 设置系统内核参数: vm.overcommit_memory = 0 vm.swappiness = 0 sysctl -p #生效 内核参数overc ...
- 手把手教你SonarQube入门安装与使用
简介 Sonar (SonarQube)是一个开源平台,用于管理源代码的质量. Sonar 不只是一个质量数据报告工具,更是代码质量管理平台. 支持Java, C#, C/C++, PL/SQL, C ...
- C/C++ 手工实现IAT导入表注入劫持
DLL注入有多种方式,今天介绍的这一种注入方式是通过修改导入表,增加一项导入DLL以及导入函数,我们知道当程序在被运行起来之前,其导入表中的导入DLL与导入函数会被递归读取加载到目标空间中,我们向导入 ...
- POJ1018贪心(多路归并的想法)
题意: 有n个服务器,每个服务器都要安装网线(必须也只能安装一个),然后每个服务器都有mi种选择网线的方式,每种方式两个参数,一个是速度b,另一个是价钱p,然后让你找到一个最大的比值 min ...
- windows-CODE注入(远程线程注入)
远程线程注入(先简单说,下面会详细说)今天整理下代码注入(远程线程注入),所谓代码注入,可以简单的理解为是在指定内进程里申请一块内存,然后把我们自己的执行代码和一些变量拷贝进去(通常是以启线程的方式) ...
- scrapy爬虫案例--爬取阳关热线问政平台
阳光热线问政平台:http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1 爬取最新问政帖子的编号.投诉标题.投诉内容以 ...
- .NET Core-全局性能诊断工具
前言: 现在.NET Core 上线后,不可避免的会出现各种问题,如内存泄漏.CPU占用高.接口处理耗时较长等问题.这个时候就需要快速准确的定位问题,并解决. 这时候就可以使用.NET Core 为开 ...
- 远程连接mysql出现"Can't connect to MySQL server 'Ip' ()"的解决办法
1.大多是防火墙的问题(参考链接:https://blog.csdn.net/jiezhi2013/article/details/50603366) 2.上面方法不能解决,不造成影响情况下可关闭防火 ...
- Python 之父爆料:明年至少令 Python 提速 1 倍!
大概在半年前,我偶然看到一篇文章,有人提出了给 Python 提速 5 倍的计划,并在寻找经费赞助.当时并没有在意,此后也没有看到这方面的消息. 但是,就在 5 月 13 日"2021 年 ...