Python 使用MVC设计模式时如何加载重型模型
我正在用wxPython和我用Tensorflow创建的深度学习模型构建一个应用程序。我使用的设计模式是MVC。 我的问题是深度学习模型非常繁重,加载需要很长时间(大约2分钟),同时GUI挂起。 我创建了一个示例代码来描述这个过程。 以下是加载时GUI的外观: 这就是加载后GUI的外观: 问题是如何在加载模型时让应用程序运行? 我还想在GUI中添加一个状态行,指示模型正在加载或已经加载 我正在添加示例代码,演示如何构建我的应用程序Python 使用MVC设计模式时如何加载重型模型,python,model-view-controller,deep-learning,wxpython,Python,Model View Controller,Deep Learning,Wxpython,我正在用wxPython和我用Tensorflow创建的深度学习模型构建一个应用程序。我使用的设计模式是MVC。 我的问题是深度学习模型非常繁重,加载需要很长时间(大约2分钟),同时GUI挂起。 我创建了一个示例代码来描述这个过程。 以下是加载时GUI的外观: 这就是加载后GUI的外观: 问题是如何在加载模型时让应用程序运行? 我还想在GUI中添加一个状态行,指示模型正在加载或已经加载 我正在添加示例代码,演示如何构建我的应用程序 import wx import time class M
import wx
import time
class Model:
def __init__(self):
'''This part is simulating the loading of tensorflow'''
x = 0
while x < 15:
time.sleep(1)
print(x)
x += 1
class View(wx.Frame):
def __init__(self, parent, title):
super(View, self).__init__(parent, title=title, size=(400, 400))
self.InitUI()
def InitUI(self):
# Defines the GUI controls
masterPanel = wx.Panel(self)
masterPanel.SetBackgroundColour("gold")
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.fgs = wx.FlexGridSizer(6, 2, 10, 25)
id = wx.StaticText(self, label="ID:")
firstName = wx.StaticText(self, label="First name:")
lastName = wx.StaticText(self, label="Last name:")
self.idTc = wx.TextCtrl(self)
self.firstNameTc = wx.TextCtrl(self)
self.lastNameTc = wx.TextCtrl(self)
self.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
firstName, (self.firstNameTc, 1, wx.EXPAND),
lastName, (self.lastNameTc, 1, wx.EXPAND)])
self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
border=15)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
self.model = Model()
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
当x<15时:
时间。睡眠(1)
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化(父级,标题=标题,大小=(400400))
self.InitUI()
def InitUI(self):
#定义GUI控件
主面板=wx.面板(自)
主面板.镶嵌底色(“金色”)
self.vbox=wx.BoxSizer(wx.VERTICAL)
self.fgs=wx.FlexGridSizer(6,2,10,25)
id=wx.StaticText(self,label=“id:”)
firstName=wx.StaticText(self,label=“First name:”)
lastName=wx.StaticText(self,label=“Last name:”)
self.idTc=wx.TextCtrl(self)
self.firstNameTc=wx.TextCtrl(self)
self.lastNameTc=wx.TextCtrl(self)
self.fgs.AddMany([id,(self.idTc,1,wx.EXPAND),
名字,(self.firstNameTc,1,wx.EXPAND),
lastName,(self.lastNameTc,1,wx.EXPAND)])
self.vbox.Add(self.fgs,比例=1,标志=wx.ALL | wx.EXPAND,
边框=15)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
类控制器:
定义初始化(自):
self.view=view(无,title='Test')
self.view.Show()
self.model=model()
def main():
app=wx.app()
控制器=控制器()
app.MainLoop()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
您应该在self.view.Show()
命令之后调用wx.GetApp().Yield()
,该命令会立即将控制释放到MainLoop
如果以增量方式执行模型加载代码,您也可以在加载期间定期调用Yield。
下面是一个简单的方法,告诉用户发生了什么事情。如果需要取消模型加载的选项,则必须将其包装在对话框中,假设它是增量加载的
import wx
import time
class Model:
def __init__(self):
'''This part is simulating the loading of tensorflow'''
x = 0
#If the model load is perform in increments you could call wx.Yield
# between the increments.
while x < 15:
time.sleep(1)
wx.GetApp().Yield()
print(x)
x += 1
class View(wx.Frame):
def __init__(self, parent, title):
super(View, self).__init__(parent, title=title, size=(400, 400))
self.InitUI()
def InitUI(self):
# Defines the GUI controls
#masterPanel = wx.Panel(self)
#masterPanel.SetBackgroundColour("gold")
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.fgs = wx.FlexGridSizer(6, 2, 10, 25)
id = wx.StaticText(self, label="ID:")
firstName = wx.StaticText(self, label="First name:")
lastName = wx.StaticText(self, label="Last name:")
self.idTc = wx.TextCtrl(self)
self.firstNameTc = wx.TextCtrl(self)
self.lastNameTc = wx.TextCtrl(self)
self.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
firstName, (self.firstNameTc, 1, wx.EXPAND),
lastName, (self.lastNameTc, 1, wx.EXPAND)])
self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
border=15)
self.CreateStatusBar() # A Statusbar in the bottom of the window
self.StatusBar.SetStatusText("No model loaded", 0)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
self.view.SetStatusText("Model loading", 0)
wait = wx.BusyInfo("Please wait, loading model...")
#Optionally add parent to centre message on self.view
#wait = wx.BusyInfo("Please wait, loading model...", parent=self.view)
wx.GetApp().Yield()
self.model = Model()
self.view.SetStatusText("Model loaded", 0)
del wait
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
#如果以增量执行模型负载,则可以调用wx.Yield
#在增量之间。
当x<15时:
时间。睡眠(1)
wx.GetApp().Yield()
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化(父级,标题=标题,大小=(400400))
self.InitUI()
def InitUI(self):
#定义GUI控件
#主面板=wx.面板(自)
#主面板.镶嵌底色(“金色”)
self.vbox=wx.BoxSizer(wx.VERTICAL)
self.fgs=wx.FlexGridSizer(6,2,10,25)
id=wx.StaticText(self,label=“id:”)
firstName=wx.StaticText(self,label=“First name:”)
lastName=wx.StaticText(self,label=“Last name:”)
self.idTc=wx.TextCtrl(self)
self.firstNameTc=wx.TextCtrl(self)
self.lastNameTc=wx.TextCtrl(self)
self.fgs.AddMany([id,(self.idTc,1,wx.EXPAND),
名字,(self.firstNameTc,1,wx.EXPAND),
lastName,(self.lastNameTc,1,wx.EXPAND)])
self.vbox.Add(self.fgs,比例=1,标志=wx.ALL | wx.EXPAND,
边框=15)
self.CreateStatusBar()#窗口底部的状态栏
self.StatusBar.SetStatusText(“未加载模型”,0)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
类控制器:
定义初始化(自):
self.view=view(无,title='Test')
self.view.Show()
self.view.SetStatusText(“模型加载”,0)
wait=wx.busynfo(“请稍候,正在加载模型…”)
#可选择在self.view上添加家长至中心消息
#wait=wx.busynfo(“请稍候,加载模型…”,parent=self.view)
wx.GetApp().Yield()
self.model=model()
self.view.SetStatusText(“模型加载”,0)
德尔等待
def main():
app=wx.app()
控制器=控制器()
app.MainLoop()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
您应该在self.view.Show()
命令之后调用wx.GetApp().Yield()
,该命令会立即将控制释放到MainLoop
如果以增量方式执行模型加载代码,您也可以在加载期间定期调用Yield。
下面是一个简单的方法,告诉用户发生了什么事情。如果需要取消模型加载的选项,则必须将其包装在对话框中,假设它是增量加载的
import wx
import time
class Model:
def __init__(self):
'''This part is simulating the loading of tensorflow'''
x = 0
#If the model load is perform in increments you could call wx.Yield
# between the increments.
while x < 15:
time.sleep(1)
wx.GetApp().Yield()
print(x)
x += 1
class View(wx.Frame):
def __init__(self, parent, title):
super(View, self).__init__(parent, title=title, size=(400, 400))
self.InitUI()
def InitUI(self):
# Defines the GUI controls
#masterPanel = wx.Panel(self)
#masterPanel.SetBackgroundColour("gold")
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.fgs = wx.FlexGridSizer(6, 2, 10, 25)
id = wx.StaticText(self, label="ID:")
firstName = wx.StaticText(self, label="First name:")
lastName = wx.StaticText(self, label="Last name:")
self.idTc = wx.TextCtrl(self)
self.firstNameTc = wx.TextCtrl(self)
self.lastNameTc = wx.TextCtrl(self)
self.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
firstName, (self.firstNameTc, 1, wx.EXPAND),
lastName, (self.lastNameTc, 1, wx.EXPAND)])
self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
border=15)
self.CreateStatusBar() # A Statusbar in the bottom of the window
self.StatusBar.SetStatusText("No model loaded", 0)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
self.view.SetStatusText("Model loading", 0)
wait = wx.BusyInfo("Please wait, loading model...")
#Optionally add parent to centre message on self.view
#wait = wx.BusyInfo("Please wait, loading model...", parent=self.view)
wx.GetApp().Yield()
self.model = Model()
self.view.SetStatusText("Model loaded", 0)
del wait
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
#如果以增量执行模型负载,则可以调用wx.Yield
#在增量之间。
当x<15时:
时间。睡眠(1)
wx.GetApp().Yield()
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu=(
import wx
import time
from threading import Thread
import wx.lib.newevent
progress_event, EVT_PROGRESS_EVENT = wx.lib.newevent.NewEvent()
load_status=["Model Loading","Model Loaded","Model Cancelled"]
class Model(Thread):
def __init__(self,parent):
Thread.__init__(self)
'''This thread simulates the loading of tensorflow'''
self.stopthread = 0
self.target = parent
self.start()
def run(self):
while not self.stopthread:
for i in range(20):
if self.stopthread:
break
time.sleep(0.5)
evt = progress_event(count=i, status=self.stopthread)
wx.PostEvent(self.target, evt)
if self.stopthread == 0:
self.stopthread = 1
evt = progress_event(count=i, status=self.stopthread)
wx.PostEvent(self.target, evt)
def terminate(self):
self.stopthread = 2
class View(wx.Frame):
def __init__(self, parent, title):
super(View, self).__init__(parent, title=title, size=(400, 400))
self.InitUI()
def InitUI(self):
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.fgs = wx.FlexGridSizer(6, 2, 10, 25)
id = wx.StaticText(self, label="ID:")
firstName = wx.StaticText(self, label="First name:")
lastName = wx.StaticText(self, label="Last name:")
self.idTc = wx.TextCtrl(self)
self.firstNameTc = wx.TextCtrl(self)
self.lastNameTc = wx.TextCtrl(self)
self.stop = wx.Button(self, -1, "Stop Load")
self.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
firstName, (self.firstNameTc, 1, wx.EXPAND),
lastName, (self.lastNameTc, 1, wx.EXPAND),
(self.stop,1,wx.EXPAND)])
self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,border=15)
#Bind to the progress event issued by the thread
self.Bind(EVT_PROGRESS_EVENT, self.OnProgress)
#Bind to Stop button
self.Bind(wx.EVT_BUTTON, self.OnStop)
#Bind to Exit on frame close
self.Bind(wx.EVT_CLOSE, self.OnExit)
self.SetSizer(self.vbox)
self.Layout()
self.statusbar = self.CreateStatusBar(2)
self.text = wx.StaticText(self.statusbar,-1,("No Model loaded"))
self.progress = wx.Gauge(self.statusbar, range=20)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.text, 0, wx.ALIGN_TOP|wx.ALL, 5)
sizer.Add(self.progress, 1, wx.ALIGN_TOP|wx.ALL, 5)
self.statusbar.SetSizer(sizer)
wx.BeginBusyCursor()
self.loadthread = Model(self)
def OnProgress(self, event):
self.text.SetLabel(load_status[event.status])
#self.progress.SetValue(event.count)
#or for indeterminate progress
self.progress.Pulse()
if event.status != 0:
self.statusbar.Hide()
wx.EndBusyCursor()
self.Layout()
def OnStop(self, event):
if self.loadthread.isAlive():
self.loadthread.terminate() # Shutdown the thread
self.loadthread.join() # Wait for it to finish
def OnExit(self, event):
if self.loadthread.isAlive():
self.loadthread.terminate() # Shutdown the thread
self.loadthread.join() # Wait for it to finish
self.Destroy()
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()