模型训练。随着数据量和复杂性的增加,运行脚本可能需要一些时间。您可以在等待数据处理完成的同时做一些其他的工作。为了达到这个目的,作者编写了一套Python脚本来解决这个问题。使用这些脚本向手机发送流程更新、可视化和完成通知。当你偶尔有这些自由的时刻时,你可以享受而不是担心模型的进步。需要什么第一个问题是,你需要知道什么?这取决于你正在做的工作。对笔者来说,可能占用时间的处理工作主要有三种:模型训练数据处理和/或传输金融模型,我们需要对每种情况进行详细分析。模型训练每n个时期更新一次,并且必须包括关键指标。例如,训练集和验证集的损失和准确性。接下来是完整的通知,包括:训练期间关键指标的可视化(同样,训练和验证集的损失和准确性)其他不太重要但仍然有用的信息,例如本地模型目录、训练时间、模型架构等。预测输出,对于文本生成,输出是生成的文本(或它的样本);对于图像生成,输出是(希望如此)很酷的可视化效果,例如训练神经网络来再现给定的艺术风格。我们需要突出显示从模型生成的图像、损失和精度图、当前训练时间和模型名称。importnotifySTART=datetime.now()#thislinewouldbeplacedbeforemodeltrainingbeginsMODELNAME="SynthwaveGAN"#givingusourmodelnameNOTIFY=100#sowesendanupdatenotificationevery100epochs#foreachepoche,wewouldincludethefollowingcodeife%notify_epoch==0ande!=0:#herewecreatetheemailbodymessagetxt=(f"{MODELNAME"f}现在更新).strftime('%H:%M:%S')}.")#webuildtheMIMEmessageobjectwithnotify.messagemsg=notify.message(subject='SynthwaveGAN',text=txt,img=[f'../visuals/{MODELNAME}/epoch_{e}_loss.png',f'../visuals/{MODELNAME}/epoch_{e}_iter_{i}.png'])#notethatweattachtwoimageshere,thelossplotand#...generatedimageoutputfromourmodelnotify.send(msg)#wethensendthemessage每100个纪元,将发送一封包含上述所有内容的电子邮件。这是其中一封电子邮件:DataProcessingandTransfer这封不是很有趣,但它在时间消耗方面排名第一。以使用Python批量上传数据到SQLServer为例(对于没有BULKINSERT的)。在上传脚本结束时,将有一条简单的消息通知上传已完成。importosimportnotifyfromdataimportSql#seehttps://jamescalam.github.io/pysqlplus/lib/data/sql.htmldt=Sql('database123','server001')#setuptheconnectiontoSQLServerfori,fileinenumerate(os.listdir('../data/new')):dt.push_raw(f'../data/new/{file}')#pushafiletoSQLServer#oncetheuploadiscomplete,sendanotification#firstwecreatethemessagemsg=notify.message(subject='SQLDataUpload',text=f'Datauploadcomplete,{i}filesuploaded.',)#sendthemessagenotify.send(msg)如果偶尔会抛出错误,您还可以添加try-except语句来捕获错误并将其添加到列表中以包含在更新和/或完成电子邮件中。FinancialModeling凡是运行在financialmodeling上的东西其实都很快,所以我这里只能举一个例子。以现金流建模工具为例。实际上,这个过程只需要10-20秒,但现在想象一下,你是华尔街最炙手可热的量化分析师,你正在处理数百万笔贷款。在这封电子邮件中,您可能希望包含一份高级概要分析组合。可以随机选择一些贷款,并在给定时间段内可视化关键值——给定一个小样本来交叉检查模型的性能。end=datetime.datetime.now()#gettheendingdatetime#getthetotalruntimeinhours:minutes:secondsshours,rem=divmod((end-start).seconds,3600)mins,secs=divmod(rem,60)runtime='{:02d}:{:02d}:{:02d}'.format(hours,mins,secs)#nowbuiltourmessagenotify.msg(subject="CashflowModelCompletion",text=(f'{len(model.output)}loansprocessed.\n'f'Totalruntime:{runtime}'),img=['../vis/loan01_amortisation.png','../vis/loan07_amortisation.png','../vis/loan01_profit_and_loss.png','../vis/loan07_profit_and_loss.png'])notify.send(msg)#andsendit以上所有函数均摘自名为notify.py的脚本。示例代码中将使用Outlook。这里需要两个Python库,email和smtplib:email:用来管理邮件信息。使用此库可以设置电子邮件消息本身,包括主题、文本和附件。smtplib:处理SMTP连接。简单邮件传输协议(SMTP)是大多数电子邮件系统使用的允许通过Internet发送邮件的协议。图片来源:unsplashMIME消息本身是使用电子邮件模块中的MIMEMultipart对象构建的。还有三个MIME子类需要使用并附加到MIMEMultipart对象:mimetext:这将包含电子邮件“有效负载”,即电子邮件文字中的文本。mimeimage:这是为了在电子邮件中包含图像。mimeapplication:用于MIME消息应用程序对象。那就是文件附件。除了这些子类之外,还有其他参数,例如MimeMultipart中的Subject值。所有这些加起来构成了下面的结构。把它们都放在一起会发生什么:importosfromemail.mime.textimportMIMETextfromemail.mime.imageimportMIMEImagefromemail.mime.applicationimportMIMEApplicationfromemail.mime.multipartimportMIMEMultipartdefmessage(subject="PythonNotification",text="",img=None,attachment=Nonecontents):#buildsmess=MIMEMultipart()msg['Subject']=subject#addinthesubjectmsg.attach(MIMEText(text))#addtextcontents#checkifwehaveanythinggivenintheimgparameterifimgisnotNone:#ifwedo,wewanttoiteratethroughtheimages,让我们检查#whatwehaveisactuallyalistiftype(img)isnotlist:img=[img]#ifitisn'talist,makeitone#nowiteratethroughourlistforone_imginimg:img_data=open(one_img,'rb').read()#readtheimagebinarydata#attachtheimagedatatoMIMEMultipartusingMIMEImage,我们添加#thegivenfilenameuseos.basenamemsg.attach(MIMEImage(img_data,name=os.path.basename(one_img)))#wedothesameforattachmentsaswedidforimagesifattachmentisnotNone:iftype(attachment)isnotlist:attachment=[attachment]#ifitisn'talist,makeitoneforone_attachmentinattachment:withopen(one_attachment,'rb')asf:#readintheattachmentusingMIMEApplicationfile=MIMEApplication(f.read(),name=os.path.basename(one_attachment))#hereweedittheattachedfilemetadatafile['Content-Disposition']=f'attachment;filename="{os.path.basename(one_attachment)}"'msg.attach(file)#finally,addtheattachmenttoourmessageobjectreturnmsg这个脚本在顶部相当简单,有导入(这是之前介绍的MIME部分)和os库Python。接下来定义一个名为消息的函数。这允许使用不同的参数调用函数并轻松构建电子邮件消息对象。例如,您可以编写包含多张图片和附件的电子邮件,如下所示:.csv','data_out.csv'])首先初始化一个MIMEMultipart对象,赋值给msg;然后,使用“主题”键设置电子邮件主题。attach方法将不同的MIME子类添加到MIMEMultipart对象。您可以使用MIMEText子类添加电子邮件文本。对于图像img和附件,您可以不传递任何内容,只需传递文件路径或文件路径数组。我们通过首先检查参数是否为None来处理这个问题,如果是,则传递它;否则,检查给定的数据类型,如果它不是列表,则创建一个列表,这使得可以使用下面的for循环迭代项目。接下来,分别使用MIMEImage和MIMEApplication子类来附加图像和文件。使用os.basename从给定的文件路径中获取文件名,附件名称包括文件名。图片来源:unsplashSMTP现在电子邮件消息对象已经构造完成,下一步就是发送它。这是smtplib模块发挥作用的地方。代码也很简单,只有一处例外。由于直接与不同的电子邮件提供商及其各自的服务器打交道,因此需要不同的SMTP地址。在Google中输入“outlooksmtp”。无需点击页面,即可获取服务器地址smtp-mail.outlook.com和端口号587。使用smtplib.SMTP初始化SMTP对象时,这两种方法都需要。SMTP-接近发送函数的开始:importsmtplibimportsocketdefsend(server='smtp-mail.outlook.com',port='587',msg):#containfollowingintry-exceptincaseofmomentarynetworkerrorstry:#initialiseconnectiontoemailserver,thedefaultisOutlooksmtp=smtplib.SMTP(server,端口)#这是'ExtendedHello'命令,本质上是问候我们的SMTPorESMTP服务器smtp.ehlo()#这是'StartTransportLayerSecurity'命令,告诉服务器我们将#becommunicatingwithTLSencryptionsmtp.starttls()#reademailandpasswordfromfilewithopen('../data/email.txt','r')asf()withopen('../data/password.txt','r')asfp:pwd=fp.read()#logintooutlookserversmtp.login(email,pwd)#sendnotificationtoselfsmtp.sendmail(email,email,msg.as_string())#disconnectfromtheserversmtp.quit()exceptsocket.gaierror:print("Networkconnectionerror,emailnotsent.")smtp.ehlo()和smtp.starttls()都是SMTP命令。ehlo(扩展的Hello)本质上是对服务器的问候。starttls通知服务器将使用加密的传输级别安全(TLS)连接进行通信。在此之后,只需从文件中读取电子邮件和密码,分别存储在电子邮件和密码中。然后,使用smtp.login登录到SMTP服务器。登录并使用smtp.sendmail发送电子邮件。我总是向自己发送通知,但在自动报告的情况下,可能希望将电子邮件发送到其他地方。为此,我将更改目标地址:smtp.sendmail(email,destination_address,msg.as_string)。最后,终止会话并关闭与smtp.quit的连接。将所有这些放在try-except语句中。如果瞬间网络连接丢失,将无法连接到服务器。导致socket.gaierror。使用try-except语句可以防止网络连接失败时程序崩溃。作者将其用于ML模型训练更新和数据传输完成。邮件发不出去也没关系。这种简单的、反应性的连接丢失处理是合适的。全部放在一起来源:unsplash现在两部分代码都已经写好了,我们可以发送邮件了:#buildamessageobjectmsg=message(text="Seeattached!",img='important.png',attachment='data.csv')send(msg)#sendtheemail(defaultstoOutlook)这是使用Python的所有电子邮件通知和/或自动化的整个过程。感谢电子邮件和smptlib库,设置过程非常简单。需要注意的另一件事是公共电子邮件提供商服务器地址和TLS端口。对于任何耗时的处理或训练任务,进度更新和完成通知通常是一种真正的解脱。Python,让工作更美好!
