1. 前言

受到小伙伴的启发,就自己动手写了一个使用邮件监控Mxnet训练的例子。整体不算复杂。

2. 设置一些全局参数

邮箱服务的pop,smtp地址,邮箱账号,接受邮箱号和密码以及当前训练状态

还有训练的超参数和保存路径和文件名参数等

pophost = 'pop.126.com'
smtphost = 'smtp.126.com'
useremail = 'trainmonitor@126.com'
toemail = 'fiercewind@outlook.com'
password = '123456' running = False params = {'ep': 10, 'lr': 0.002, 'bs': 128, 'wd': 0.0}
nameparams = {'dir':'./','params':'NN.params','png':'NN.png'}

3. 打包训练代码

需要进行监控训练,所以需要将训练的代码打包进一个函数内,通过传参的方式进行训练。还是使用FashionMNIST数据集

这样训练的时候就调用函数传参就行了

3.1 训练主函数

训练需要的一些参数都采用传参的形式

这里我新加了一个名叫nameparams的参数,用于设置曲线图,保存的参数文件的路径和文件名

def NN_Train(net, train_data, test_data,params,nameparams):
msg = '' epochs = int(params['ep'])
batch_size = int(params['bs'])
learning_rate = params['lr']
weight_decay = params['wd'] train_loss = []
train_acc = []
dataset_train = gluon.data.DataLoader(train_data, batch_size, shuffle=True)
test_loss = []
test_acc = []
dataset_test = gluon.data.DataLoader(test_data, batch_size, shuffle=True) trainer = gluon.Trainer(net.collect_params(), 'adam',
{'learning_rate': learning_rate,
'wd': weight_decay})
softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss() for epoch in range(epochs):
_loss = 0.
_acc = 0.
t_acc = 0.
for data, label in dataset_train:
data = nd.transpose(data, (0, 3, 1, 2))
data = data.as_in_context(ctx)
label = label.as_in_context(ctx)
with autograd.record():
output = net(data)
loss = softmax_cross_entropy(output, label)
loss.backward()
trainer.step(batch_size) _loss += nd.mean(loss).asscalar()
_acc += accuracy(output, label)
__acc = _acc / len(dataset_train)
__loss = _loss / len(dataset_train)
train_loss.append(__loss)
train_acc.append(__acc) t_acc, t_loss = evaluate_accuracy(dataset_test, net)
test_loss.append(t_loss)
test_acc.append(t_acc) msg += ("Epoch %d. Train Loss: %f, Test Loss: %f, Train Acc %f, Test Acc %f\n" % (
epoch, __loss, t_loss, __acc, t_acc)) fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(train_loss, 'r')
ax1.plot(test_loss, 'g')
ax1.legend(['Train_Loss', 'Test_Loss'], loc=2)
ax1.set_ylabel('Loss') ax2 = ax1.twinx()
ax2.plot(train_acc, 'b')
ax2.plot(test_acc, 'y')
ax2.legend(['Train_Acc', 'Test_Acc'], loc=1)
ax2.set_ylabel('Acc') plt.savefig(os.path.join(nameparams['dir'],nameparams['png']), dpi=600)
net.save_params(os.path.join(nameparams['dir'],nameparams['params']))
return msg

3.2 打包网络模型

同样,需要把网络也打包进函数内

def GetNN():
net = nn.HybridSequential()
with net.name_scope():
net.add(gluon.nn.Conv2D(channels=20, kernel_size=5, activation='relu'))
net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2))
net.add(gluon.nn.Conv2D(channels=50, kernel_size=3, activation='relu'))
net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2))
net.add(gluon.nn.Flatten())
net.add(gluon.nn.Dense(10))
net.initialize(init=mx.init.Xavier(), ctx=ctx)
net.hybridize()
return net

3.3 打包数据读取

然后把数据读取也搞进函数内

def GetDate():
fashion_train = gluon.data.vision.FashionMNIST(
root='./', train=True, transform=transform)
fashion_test = gluon.data.vision.FashionMNIST(
root='./', train=True, transform=transform)
return fashion_train, fashion_test

4. 搞定邮件的接收发送

使用邮件监控,就要搞定在Python上使用邮件的问题,还好Python内置了邮件库

这样接收发送邮件也只用调用函数就好了

4.1 接受邮件

我只接受纯文本的内容,因为HTML内容的太过复杂

def ReEmail():
try:
pp = poplib.POP3(pophost)
pp.user(useremail)
pp.pass_(password)
resp, mails, octets = pp.list()
index = len(mails)
if index > 0:
resp, lines, octets = pp.retr(index)
msg_content = b'\r\n'.join(lines).decode('utf-8')
pp.dele(index)
pp.quit()
msg = Parser().parsestr(msg_content)
message = Get_info(msg)
subject = msg.get('Subject')
date = msg.get('Date')
return message,subject,date
except ConnectionResetError as e:
print('ConnectionResetError')
return None,None,None

4.2 发送邮件

发送邮件我是用了一个第三方邮件库envelopes,因为简单方便。

def SentEmail(message, subject,imgpath):
envelope = Envelope(
from_addr=(Global.useremail, u'Train'),
to_addr=(Global.toemail, u'FierceX'),
subject=subject,
text_body=message
)
if imgpath is not None:
envelope.add_attachment(imgpath) envelope.send(Global.smtphost, login=Global.useremail,
password=Global.password, tls=True)

4.3 解析邮件内容

然后需要解析邮件内容,这段基本从网上抄来的,因为邮件格式很复杂,没深究

def Get_info(msg):
if (msg.is_multipart()):
parts = msg.get_payload()
for n, part in enumerate(parts):
return Get_info(part)
if not msg.is_multipart():
content_type = msg.get_content_type()
if content_type=='text/plain':
content = msg.get_payload(decode=True)
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
return content

5. 使用责任链模式解析命令

在解析命令里,我使用了责任链模式,并且设置了一个前台类,可以添加新的命令解析类,具体看代码

5.1 责任链基类

我在责任链基类里实现了判断当前命令是否是该对象可执行的命令,这样在编写命令解析类时,就可以忽略判断条件,直接重写解析方法Work即可

class BaseCmd:
def __init__(self, cmd):
self.Next = None
self.cmd = cmd def SetNext(self, n):
self.Next = n def DoAnalysis(self, cmd, params):
if cmd == self.cmd:
self.Work(params)
elif self.Next is not None:
self.Next.DoAnalysis(cmd, params) def Work(self, params):
pass

5.2 责任链前台类

在前台类里,我添加了一个Add方法,用于添加新的命令解析类,在此方法里我自动添加该解析类到责任链的尾部。

class CmdAnaly:
def __init__(self):
self.CmdList = []
self.Add(ExitCmd('exit'))
self.Add(TrainCmd('train'))
self.Add(SetNameParamsCmd('setname')) def Add(self, cmd):
self.CmdList.append(cmd)
if len(self.CmdList) > 1:
self.CmdList[len(self.CmdList) - 2].SetNext(self.CmdList[len(self.CmdList) - 1]) def Analy(self, cmd, params):
self.CmdList[0].DoAnalysis(cmd, params)

5.3 命令解析类

我只编写了三个命令解析类

训练类

class TrainCmd(BaseCmd):
def __init__(self, cmd):
BaseCmd.__init__(self, cmd) def Work(self, msg):
print('train')
if Global.running == False:
xx = msg.split('\r\n')
for k in xx:
ks = k.split(' ')
if len(ks) > 1:
Global.params[ks[0]] = float(ks[1])
t = threading.Thread(target=run)
t.start()
else:
message = ('Training is underway\n%s\n%s') %
(str(Global.params),str(Global.nameparams))
EmailTool.SentEmail(message,
'Training is underway',
None)

退出类

class ExitCmd(BaseCmd):
def __init__(self, cmd):
BaseCmd.__init__(self, cmd) def Work(self, params):
print('exit')
os._exit(0)

设置图片,参数文件名称和保存路径类

class SetNameParamsCmd(BaseCmd):
def __init__(self,cmd):
BaseCmd.__init__(self,cmd) def Work(self,msg):
xx = msg.split('\r\n')
for k in xx:
ks = k.split(' ')
if len(ks) > 1:
Global.nameparams[ks[0]] = ks[1]
print(Global.nameparams)
EmailTool.SentEmail(str(Global.nameparams),'NameParams',None)

6. 使用多线程多进程监控训练

由于Python的多线程的性能局限性,我使用了子进程进行训练,这样不会受到主进程循环监控的影响

def nn(params,nameparams):
train, test = NN_Train.GetDate()
print(params)
print(nameparams)
msg = ('%s\n') % str(params)
msg += ('%s\n') % str(nameparams)
msg += NN_Train.NN_Train(
NN_Train.GetNN(),
train_data=train,
test_data=test,
params = params,
nameparams = nameparams)
EmailTool.SentEmail(msg, 'TrainResult',os.path.join(nameparams['dir'],nameparams['png'])) def run():
p = Process(target=nn,args=(Global.params,Global.nameparams,))
print('TrainStrart')
Global.running = True
p.start()
p.join()
Global.running = False

7. 使用循环监控邮箱

在主进程中,使用循环监控邮箱内容并解析邮件命令,交给命令解析类解析处理。

if __name__ == '__main__':
Global.running = False
cmdana = CmdAnalysis.CmdAnaly()
print('Start')
a = 1
while(True):
time.sleep(10)
print(a, Global.running)
try:
msg, sub, date = EmailTool.ReEmail()
except TimeoutError as e:
print('TimeoutError')
cmdana.Analy(sub, msg)
a += 1

8. 效果

发送训练邮件

训练结束返回结果

9. 结语

使用邮件监控并不太复杂,主要在于邮件的解析。邮件格式太复杂,如果全都在主题里,参数多了会显得很乱。

根据需要添加新的命令解析类,然后在前台类里里使用Add方法添加进去就行了。

总之我认为在aws上训练还是可以一用的,总不能一直连着终端。

完整代码

使用邮件监控Mxnet训练的更多相关文章

  1. 【Mxnet】----1、使用mxnet训练mnist数据集

    使用自己准备的mnist数据集,将0-9的bmp图像分别放到0-9文件夹下,然后用mxnet训练. 1.制作rec数据集 (1).制作list

  2. Zabbix配置邮件监控

    zabbix服务端配置 安装软件并配置 使用第三方邮件实现报警 1. 安装软件 $ yum -y install mailx 2. 配置发送邮件账号密码和服务器 $ vim /etc/mail.rc ...

  3. 用C#写个邮件监控服务(一)

    监控服务,首先当然是个服务了.至于什么是windows服务,这里就不多说了.正题 1. 创建服务项目 打开VS编程环境,在C#中创建windows服务项目 2.创建后属性中更改名称和服务名. 3.增加 ...

  4. zabbix增加手机短信、邮件监控的注意要点,SSL邮件发送python脚本

    1.短信接口文档: URL http://xxx.com/interfaces/sendMsg.htm Method POST Description 文字短信调用接口 Request Param L ...

  5. Ambari 邮件监控服务

    配置邮箱授权码 这里演示的是网易邮箱 开启SMTP服务 配置邮件模板 • 下载警告邮件模板 wget https://raw.githubusercontent.com/apache/ambari/b ...

  6. mysqld 与 python 邮件监控脚本 内存消耗对比

    top - 21:38:40 up 1 day, 10:38, 5 users, load average: 0.00, 0.01, 0.17Tasks: 88 total, 1 running, 8 ...

  7. mxnet的训练过程——从python到C++

    mxnet的训练过程--从python到C++ mxnet(github-mxnet)的python接口相当完善,我们可以完全不看C++的代码就能直接训练模型,如果我们要学习它的C++的代码,从pyt ...

  8. 基于Nginx+Keepalived的LB服务监控(邮件报警)

    IDC两台机器上部署了Nginx+Keepalived主从模式的LB代理负载层,现在需要对LB进行每日巡检和服务监控,利用SendEmail邮件监控. 0)SendEmail部署 参考:http:// ...

  9. 使用SQLServer同义词和SQL邮件,解决发布订阅中订阅库丢失数据的问题

    最近给客户做了基于SQLServer的发布订阅的“读写分离”功能,但是某些表数据很大,经常发生某几条数据丢失的问题,导致订阅无法继续进行.但是每次发现问题重新做一次发布订阅又非常消耗时间,所以还得根据 ...

随机推荐

  1. ★电车难题的n个坑爹变种

    哲学家都不会做的电车难题变异 此题会答清华北大 "电车难题(Trolley Problem)"是伦理学领域最为知名的思想实验之一,其内容大致是: 一个疯子把五个无辜的人绑在电车轨道 ...

  2. 201521123033《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. answer: 1.2 选做:收集你认为有用的代码片段 2. 书面作业 本次作业题集集合 1.List中指定元 ...

  3. 201521123053《Java程序设计》第3周学习总结

    ---恢复内容开始--- 1. 本周学习总结 2. 书面作业 1. 代码阅读 以上代码可否编译通过?哪里会出错?为什么?尝试改正?        如果创建3个Test1对象,有内存中有几个i,几个j? ...

  4. We Talk -- 团队博客

    WeTalk --在线群聊程序 团队博客 服务器一直在运行,使用客户端可直接登入使用.(做得很粗糙...) 客户端下载(java环境下直接运行) 0.项目介绍 现在我们网上交流离不开微信和QQ,当然在 ...

  5. 201521123093 java 第十三周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  6. 201521123093 java 第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  7. 201521145048《java程序与设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 Q1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自 ...

  8. 201521123003《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  9. 多线程:多线程设计模式(三):Master-Worker模式

    Master-Worker模式是常用的并行模式之一,它的核心思想是,系统有两个进程协作工作:Master进程,负责接收和分配任务:Worker进程,负责处理子任务.当Worker进程将子任务处理完成后 ...

  10. shell脚本之变量与状态码

    目录: 前言 如何创建一个脚本 脚本调试 变量相关 变量的命令规则 bash中变量的种类 本地变量 环境变量 只读和位置变量 位置变量 查询变量 进程的退出状态与状态码 前言 在linux管理中,sh ...