基于ray的分布式机器学习(二)
基本思路:
基于parameter server + multiple workers模式。
同步方式:
parameter server负责网络参数的统一管理,每次迭代均将参数发送给每一个worker,多个worker同时迭代数据集,计算当前批次的损失和梯度,
当所有worker全部完成当前批次的计算后,将每个worker的梯度回传给parameter server,parameter server使用该梯度进行参数优化。
异步方式:
与同步方式不同的是,parameter server不需要每次等待所有worker全部完成一个批次的计算后再利用所有worker的梯度更新网络参数,
而是每当有一个worker完成一个批次的计算时,立刻进行网络参数的更新,并将新的参数下发给该worker。
1、定义模型
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.conv1 = nn.Conv2d(1, 3, kernel_size=3)
self.fc = nn.Linear(192, 10) def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 3))
x = x.view(-1, 192)
x = self.fc(x)
return F.log_softmax(x, dim=1) def get_weights(self):
return {k: v.cpu() for k, v in self.state_dict().items()} def set_weights(self, weights):
self.load_state_dict(weights) def get_gradients(self):
grads = []
for p in self.parameters():
grad = None if p.grad is None else p.grad.data.cpu().numpy()
grads.append(grad)
return grads def set_gradients(self, gradients):
for g, p in zip(gradients, self.parameters()):
if g is not None:
p.grad = torch.from_numpy(g) 2、定义parameter server
@ray.remote
class ParameterServer(object):
def __init__(self, lr):
self.model = ConvNet()
self.optimizer = torch.optim.SGD(self.model.parameters(), lr=lr) def apply_gradients(self, *gradients):
summed_gradients = [
np.stack(gradient_zip).sum(axis=0)
for gradient_zip in zip(*gradients)
]
self.optimizer.zero_grad()
self.model.set_gradients(summed_gradients)
self.optimizer.step()
return self.model.get_weights() def get_weights(self):
return self.model.get_weights() 3、定义worker
@ray.remote
class DataWorker(object):
def __init__(self):
self.model = ConvNet()
self.data_iterator = iter(get_data_loader()[0]) def compute_gradients(self, weights):
self.model.set_weights(weights)
try:
data, target = next(self.data_iterator)
except StopIteration: # When the epoch ends, start a new epoch.
self.data_iterator = iter(get_data_loader()[0])
data, target = next(self.data_iterator)
self.model.zero_grad()
output = self.model(data)
loss = F.nll_loss(output, target)
loss.backward()
return self.model.get_gradients() 4、同步训练
iterations = 200
num_workers = 2 ray.init(ignore_reinit_error=True)
ps = ParameterServer.remote(1e-2)
workers = [DataWorker.remote() for i in range(num_workers)] model = ConvNet()
test_loader = get_data_loader()[1] print("Running synchronous parameter server training.")
current_weights = ps.get_weights.remote()
for i in range(iterations):
gradients = [
worker.compute_gradients.remote(current_weights) for worker in workers
] current_weights = ps.apply_gradients.remote(*gradients) if i % 10 == 0:
model.set_weights(ray.get(current_weights))
accuracy = evaluate(model, test_loader)
print("Iter {}: \taccuracy is {:.1f}".format(i, accuracy)) print("Final accuracy is {:.1f}.".format(accuracy))
ray.shutdown() 5、异步训练
print("Running Asynchronous Parameter Server Training.") ray.init(ignore_reinit_error=True)
ps = ParameterServer.remote(1e-2)
workers = [DataWorker.remote() for i in range(num_workers)] current_weights = ps.get_weights.remote() gradients = {}
for worker in workers:
gradients[worker.compute_gradients.remote(current_weights)] = worker for i in range(iterations * num_workers):
ready_gradient_list, _ = ray.wait(list(gradients))
ready_gradient_id = ready_gradient_list[0]
worker = gradients.pop(ready_gradient_id) current_weights = ps.apply_gradients.remote(*[ready_gradient_id])
gradients[worker.compute_gradients.remote(current_weights)] = worker if i % 10 == 0:
model.set_weights(ray.get(current_weights))
accuracy = evaluate(model, test_loader)
print("Iter {}: \taccuracy is {:.1f}".format(i, accuracy)) print("Final accuracy is {:.1f}.".format(accuracy))
基于ray的分布式机器学习(二)的更多相关文章
- 基于ray的分布式机器学习(一)
基本思路:1.对数据分块,使用多个worker分别处理一个数据块,每个worker暴露两个接口,分别是损失计算的接口loss和梯度计算的接口grad:2.同时定义full_loss和full_grad ...
- 基于redis的分布式锁二种应用场景
“分布式锁”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种.具体到业务场景中,我们要考虑二种情况: 一.抢不到锁的请求,允许丢弃(即:忽略) ...
- 谈谈分布式事务之二:基于DTC的分布式事务管理模型[下篇]
[续上篇] 当基于LTM或者KTM的事务提升到基于DTC的分布式事务后,DTC成为了本机所有事务型资源管理器的管理者:此外,当一个事务型操作超出了本机的范 围,出现了跨机器的调用后,本机的DTC需要于 ...
- 基于zookeeper实现分布式配置中心(二)
上一篇(基于zookeeper实现分布式配置中心(一))讲述了zookeeper相关概念和工作原理.接下来根据zookeeper的特性,简单实现一个分布式配置中心. 配置中心的优势 1.各环境配置集中 ...
- 分布式机器学习框架:MxNet 前言
原文连接:MxNet和Caffe之间有什么优缺点一.前言: Minerva: 高效灵活的并行深度学习引擎 不同于cxxnet追求极致速度和易用性,Minerva则提供了一个高效灵活的平台 ...
- [转帖]Greenplum :基于 PostgreSQL 的分布式数据库内核揭秘 (上篇)
Greenplum :基于 PostgreSQL 的分布式数据库内核揭秘 (上篇) https://www.infoq.cn/article/3IJ7L8HVR2MXhqaqI2RA 学长的文章.. ...
- 分布式机器学习:逻辑回归的并行化实现(PySpark)
1. 梯度计算式导出 我们在博客<统计学习:逻辑回归与交叉熵损失(Pytorch实现)>中提到,设\(w\)为权值(最后一维为偏置),样本总数为\(N\),\(\{(x_i, y_i)\} ...
- 分布式机器学习:同步并行SGD算法的实现与复杂度分析(PySpark)
1 分布式机器学习概述 大规模机器学习训练常面临计算量大.训练数据大(单机存不下).模型规模大的问题,对此分布式机器学习是一个很好的解决方案. 1)对于计算量大的问题,分布式多机并行运算可以基本解决. ...
- 基于scrapy-redis的分布式爬虫
一.介绍 1.原生的scrapy框架 原生的scrapy框架是实现不了分布式的,其原因有: 1. 因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...
随机推荐
- 2019 GDUT Rating Contest III : Problem A. Out of Sorts
题面: 传送门 A. Out of Sorts Input file: standard input Output file: standard output Time limit: 1 second M ...
- python爬去壁纸网站上的所有壁纸
import requests as r 2 from bs4 import BeautifulSoup 3 import os 4 base_url = "http://www.win40 ...
- salesforce零基础学习(一百零二)Limitation篇之 CPU Limit
本篇参考: https://help.salesforce.com/articleView?id=000339361&type=1&mode=1 https://developer.s ...
- Python3实现短信轰炸机
短信轰炸机的基本原理:利用某些限制不严格的网站短信注册接口,用Python模拟请求,传入被炸人手机号码,实现轰炸 实现方式:利用requests模块.time模块.完成请求模拟 模块安装: 在终端窗口 ...
- 13 条高效实用的 JavaScript 单行代码
JavaScript可以实现很多令人惊奇的事! 从复杂的框架到处理API,有太多的东西可以学习. 甚至,仅用一行代码,它也能完成一些很棒的工作. 不信?那么请看这13条JavaScript单行代码,用 ...
- 总结traefik 在k8s 环境中的配置文件
总结traefik 在k8s 环境中的配置文件 traefik.toml配置文件引用 [www@localhost traefik-ingress]$ more * :::::::::::::: co ...
- SpringBoot整合Swagger2及使用
简介 swagger是一个流行的API开发框架,这个框架以"开放API声明"(OpenAPI Specification,OAS)为基础, 对整个API的开发周期都提供了相应的解决 ...
- Dynamics CRM使用JS隐藏自定义按钮
在我们平时客制化开发的时候会经常遇到要制作自定义按钮的情况,而这个自定义按钮的功能又经常会有一些隐藏逻辑需要实现,所以每次通过获取控件查找这个按钮再隐藏比较麻烦,而且偶尔会出现代码没起作用的效果.下面 ...
- Linux apt命令使用 以及 文本流和重定向
apt (Advanced Packaging Tool) 是一个在Debian和Ubuntu中的Shell前端软件包管理器. apt命令执行需要超级管理员权限(root). apt语法 apt [o ...
- python中栈的实现
栈是一种线性数据结构,用先进后出或者是后进先出的方式存储数据,栈中数据的插入删除操作都是在栈顶端进行,常见栈的函数操作包括 empty() – 返回栈是否为空 – Time Complexity : ...