📜  Python的手写方程式求解器

📅  最后修改于: 2021-05-24 18:11:57             🧑  作者: Mango

获取培训数据

  • 下载数据集
      从此链接下载数据集。解压缩zip文件。将有不同的文件夹包含不同数学符号的图像。为简单起见,请在方程式求解器中使用0–9位数字,+,?-?和乘以图像。在观察数据集时,我们可以看到它对某些数字/符号有偏见,因为它包含某些符号的12000张图像和其他符号的3000张图像。要消除这种偏见,请将每个文件夹中的图像数量减少到大约。 4000
  • 提取特征
      我们可以使用轮廓提取来获得特征。
    1. 反转图像,然后将其转换为二进制图像,因为当对象为白色且周围为黑色时,轮廓提取可提供最佳效果。
    2. 要查找轮廓,请使用“ findContour”函数。对于要素,请使用“ boundingRect”函数获取轮廓的边界矩形(边界矩形是包围整个轮廓的最小水平矩形)。
    3. 由于我们的数据集中的每个图像仅包含一个符号/数字,因此我们只需要最大尺寸的边界矩形。为此,我们计算每个轮廓的边界矩形的面积,然后选择面积最大的矩形。
    4. 现在,将最大区域边界矩形的大小调整为28 x28。将其重塑为784 x1。因此现在将有784个像素值或特征。现在,给它加上相应的标签(例如,对于0–9图像,其数字相同,对于– –分配标签10,对于+分配标签11,对于时间分配标签12)。因此,现在我们的数据集包含784个要素列和一个标签列。提取特征后,将数据保存到CSV文件。

    使用卷积神经网络训练数据

      由于卷积神经网络适用于二维数据,并且我们的数据集采用785 by 1的形式。因此,我们需要对其进行重塑。首先,将数据集中的标签列分配给变量y_train。然后从数据集中删除标签列,然后将数据集重塑为28 x28。现在,我们的数据集已准备就绪,可以用于CNN。
  • 建立卷积神经网络
      为了制作CNN,请导入所有必需的库。
    import pandas as pd
    import numpy as np
    import pickle
    np.random.seed(1212)
    import keras
    from keras.models import Model
    from keras.layers import * from keras import optimizers
    from keras.layers import Input, Dense
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import Dropout
    from keras.layers import Flatten
    from keras.layers.convolutional import Conv2D
    from keras.layers.convolutional import MaxPooling2D
    from keras.utils import np_utils
    from keras import backend as K
    K.set_image_dim_ordering('th')
    from keras.utils.np_utils import to_categorical
    from keras.models import model_from_json
    
      使用’to_categorical’函数将y_train数据转换为分类数据。要制作模型,请使用以下代码行。
    model = Sequential()
    model.add(Conv2D(30, (5, 5), input_shape =(1, 28, 28), activation ='relu'))
    model.add(MaxPooling2D(pool_size =(2, 2)))
    model.add(Conv2D(15, (3, 3), activation ='relu'))
    model.add(MaxPooling2D(pool_size =(2, 2)))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(128, activation ='relu'))
    model.add(Dense(50, activation ='relu'))
    model.add(Dense(13, activation ='softmax'))
    # Compile model
    model.compile(loss ='categorical_crossentropy', 
                  optimizer ='adam', metrics =['accuracy'])
    
  • 将模型拟合到数据
      为了使CNN适合数据,请使用以下代码行。
    model.fit(np.array(l), cat, epochs = 10, batch_size = 200, 
              shuffle = True, verbose = 1)
    
      训练我们的模型大约需要3个小时,准确率为98.46%。训练后,我们可以将模型另存为json文件以备将来使用,这样我们就不必训练模型,每次都不需要等待三个小时。要保存我们的模型,我们可以使用以下代码行。
    model_json = model.to_json()
    with open("model_final.json", "w") as json_file:
        json_file.write(model_json)
    # serialize weights to HDF5
    model.save_weights("model_final.h5")
    

    测试我们的模型或使用它求解方程

      首先,使用以下代码行导入我们保存的模型。
    json_file = open('model_final.json', 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    loaded_model = model_from_json(loaded_model_json)
    # load weights into new model
    loaded_model.load_weights("model_final.h5")
    
  • 现在,输入包含手写方程式的图像。将图像转换为二进制图像,然后反转图像(如果数字/符号为黑色)。
  • 现在获取图像的轮廓,默认情况下,它将从左到右获取轮廓。
  • 获取每个轮廓的边界矩形。
  • 有时,对于相同的数字/符号,这将导致两个或更多个轮廓。为避免这种情况,请检查这两个轮廓的边界矩形是否重叠。如果它们重叠,则丢弃较小的矩形。
  • 现在,将所有剩余边界矩形的大小调整为28 x 28。
  • 使用该模型,为每个边界矩形预测相应的数字/符号,并将其存储在字符串。
  • 之后,在字符串上使用“ eval”函数来求解方程。


      从此处下载手写方程式求解器的完整代码。