tensorflow PyQT可执行文件崩溃,但在python控制台中工作正常

kcugc4gi  于 2023-03-09  发布在  Python
关注(0)|答案(1)|浏览(100)

我使用PyQT5创建了一个应用程序,它使用Load按钮加载MNIST的图像,然后这个应用程序可以加载h5格式的MNIST上的训练过的Keras模型,使用Classify按钮加载训练过的模型,加载的模型预测输入图像,最后,可以将预测的类及其相应的概率保存到目录中。这款应用在打包并转换为可执行文件之前工作正常,但在Python控制台上运行时,既没有警告也没有错误。在使用“Pyinstaller”包使文件可执行后,在第二阶段,就在按下“Classify”按钮后,连接到“Classify_Image”函数,应用程序崩溃,不再工作。我的代码可以在下面进行额外的检查。

from PIL import Image
from keras.models import load_model
import numpy as np
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(320, 340)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 318, 291))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.Load = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.Load.setObjectName("Load")
        self.horizontalLayout.addWidget(self.Load)
        #########################################################
        self.Load.setEnabled(True)
        self.Load.clicked.connect(self.Load_Image)
        #########################################################
        self.Classify = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.Classify.setObjectName("Classify")
        self.horizontalLayout.addWidget(self.Classify)
        #########################################################
        self.Classify.setEnabled(False)
        self.Classify.clicked.connect(self.Classify_Image)
        #########################################################
        self.Save = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.Save.setObjectName("Save")
        self.horizontalLayout.addWidget(self.Save)
        #########################################################
        self.Save.setEnabled(False)
        self.Save.clicked.connect(self.Save_Result)
        #########################################################
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.Log = QtWidgets.QTextBrowser(self.verticalLayoutWidget)
        self.Log.setObjectName("Log")
        self.verticalLayout.addWidget(self.Log)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 320, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Classifier"))
        self.Load.setText(_translate("MainWindow", "Load"))
        self.Classify.setText(_translate("MainWindow", "Classify"))
        self.Save.setText(_translate("MainWindow", "Save"))
    def Load_Image(self):
        app.processEvents()
        self.Log.clear()
        #self.Save.setEnabled(False)
        #self.Classify.setEnabled(False)
        self.Log.append("Loading The Image...")
        # open the image file and convert to grayscale
        options = QtWidgets.QFileDialog.Options()
        options |= QtWidgets.QFileDialog.DontUseNativeDialog
        image, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image file", "", "Image Files (*.jpg)", options=options)
        image = Image.open('C:/Users/Armin/Desktop/RCDAT/Apps/First App/image.jpg').convert('L')
        self.Log.append("\nThe Image Is Loaded Successfully...")
        # convert the image to a NumPy array
        image_array = np.array(image)
        image_array = image_array.astype('float32') / 255.0
        image_array = image_array.reshape(1,28,28,1)
        self.image_array = image_array
        self.Classify.setEnabled(True)
        return image_array
    def Classify_Image(self):
        app.processEvents()
        image_array = self.image_array
        #path_saved_model  = 'C:/Users/Armin/Desktop/RCDAT/Apps/Second App/Saved Model.h5'
        options = QtWidgets.QFileDialog.Options()
        options |= QtWidgets.QFileDialog.DontUseNativeDialog
        file_name_model, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select saved model file", "", "Model Files (*.h5)", options=options)
        saved_model = load_model(file_name_model,compile=False)
        self.Log.append("\nThe Model Is Loaded Completely...")
        predict = saved_model.predict(image_array)
        Class = predict.argmax(axis=-1)
        Probability = predict[0][predict.argmax(axis=-1)]
        self.Save.setEnabled(True)
        self.Log.append("\nNow You Can Save The Results...")
        self.Class = Class
        self.Probability = Probability
        return Class,Probability
    def Save_Result(self):
        Class = self.Class
        Probability = self.Probability
        np.save('C:/Users/Armin/Desktop/RCDAT/Apps/Second App/Class.npy', Class)
        np.save('C:/Users/Armin/Desktop/RCDAT/Apps/Second App/Probability.npy', Probability)
        self.Log.append("\nThe Results Are Saved Successfully...")
        self.Save.setEnabled(False)
        self.Log.append("\nYou May Use The Classify Button To Classify Another Time...")


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我想这个问题可能与Keras中的load_model函数有关,但是我不知道如何解决它。

vc9ivgsu

vc9ivgsu1#

感谢@musicamante提供的信息,我使用Pyinstall命令pyinstaller --onefile Second_App_Test.py打包了这个应用。现在我在后台运行这个应用的时候有了cmd。我注意到我得到了一个警告和详细信息,这与Tensorflow中的model.predict()函数有关。通过在model.predict()函数中将详细信息更改为verbose=0,问题解决了。处于可执行模式的应用程序不再崩溃。

相关问题