AttributeError: Can't get attribute 'hrd' on <module '__main__' from 'app.py'>

Viewed 21

I want to crete a handwritten digit recognition model. And this ml model work as per my need in colab. I upload a photo from from trainig set and it gives the prediction. But when I tried to connect with flask. I needed to dump the model. And in every solution I search they dumped some object that are inbuilt library function. Here I tried to dump the object of the class I created, but it's giving me error. my ml code

import pandas as pd
import numpy as np
import pickle
from keras.datasets import mnist
import matplotlib.pyplot as plt

class hrd:
  def ReLU(Z):
      return np.maximum(Z,0)

  def derivative_ReLU(Z):
      return Z > 0

  def softmax(Z):
      """Compute softmax values for each sets of scores in x."""
      exp = np.exp(Z - np.max(Z)) #le np.max(Z) evite un overflow en diminuant le contenu de exp
      return exp / exp.sum(axis=0)

  def init_params(size):
      W1 = np.random.rand(10,size) - 0.5
      b1 = np.random.rand(10,1) - 0.5
      W2 = np.random.rand(10,10) - 0.5
      b2 = np.random.rand(10,1) - 0.5
      return W1,b1,W2,b2

  def forward_propagation(X,W1,b1,W2,b2):
      Z1 = W1.dot(X) + b1 #10, m
      A1 = ReLU(Z1) # 10,m
      Z2 = W2.dot(A1) + b2 #10,m
      A2 = softmax(Z2) #10,m
      return Z1, A1, Z2, A2

  def one_hot(Y):
      ''' return an 0 vector with 1 only in the position correspondind to the value in Y'''
      one_hot_Y = np.zeros((Y.max()+1,Y.size)) #si le chiffre le plus grand dans Y est 9 ca fait 10 lignes
      one_hot_Y[Y,np.arange(Y.size)] = 1 # met un 1 en ligne Y[i] et en colonne i, change l'ordre mais pas le nombre
      return one_hot_Y

  def backward_propagation(X, Y, A1, A2, W2, Z1, m):
      one_hot_Y = one_hot(Y)
      dZ2 = 2*(A2 - one_hot_Y) #10,m
      dW2 = 1/m * (dZ2.dot(A1.T)) # 10 , 10
      db2 = 1/m * np.sum(dZ2,1) # 10, 1
      dZ1 = W2.T.dot(dZ2)*derivative_ReLU(Z1) # 10, m
      dW1 = 1/m * (dZ1.dot(X.T)) #10, 784
      db1 = 1/m * np.sum(dZ1,1) # 10, 1

      return dW1, db1, dW2, db2

  def update_params(alpha, W1, b1, W2, b2, dW1, db1, dW2, db2):
      W1 -= alpha * dW1
      b1 -= alpha * np.reshape(db1, (10,1))
      W2 -= alpha * dW2
      b2 -= alpha * np.reshape(db2, (10,1))

      return W1, b1, W2, b2

  def get_predictions(A2):
      return np.argmax(A2, 0)

  def get_accuracy(predictions, Y):
      return np.sum(predictions == Y)/Y.size

  def gradient_descent(X, Y, alpha, iterations):
      size , m = X.shape

      W1, b1, W2, b2 = init_params(size)
      for i in range(iterations):
          Z1, A1, Z2, A2 = forward_propagation(X, W1, b1, W2, b2)
          dW1, db1, dW2, db2 = backward_propagation(X, Y, A1, A2, W2, Z1, m)

          W1, b1, W2, b2 = update_params(alpha, W1, b1, W2, b2, dW1, db1, dW2, db2)   

          if (i+1) % int(iterations/10) == 0:
              print(f"Iteration: {i+1} / {iterations}")
              prediction = get_predictions(A2)
              print(f'{get_accuracy(prediction, Y):.3%}')
      return W1, b1, W2, b2

  def make_predictions(X, W1 ,b1, W2, b2):
      _, _, _, A2 = forward_propagation(X, W1, b1, W2, b2)
      predictions = get_predictions(A2)
      return predictions

  def show_prediction(index,X, Y, W1, b1, W2, b2):
      # None => cree un nouvel axe de dimension 1, cela a pour effet de transposer X[:,index] qui un np.array de dimension 1 (ligne) et qui devient un vecteur (colonne)
      #  ce qui correspond bien a ce qui est demande par make_predictions qui attend une matrice dont les colonnes sont les pixels de l'image, la on donne une seule colonne
      
      
      vect_X = X[:, index,None]
      prediction = make_predictions(vect_X, W1, b1, W2, b2)
      label = Y[index]
      print("Prediction: ", prediction)
      print("Label: ", label)

      current_image = vect_X.reshape((WIDTH, HEIGHT)) * SCALE_FACTOR

      plt.gray()
      plt.imshow(current_image, interpolation='nearest')
      plt.show()
      
  def show_from_input(vect_X, W1, b1, W2, b2):
      
      
      prediction = make_predictions(vect_X, W1, b1, W2, b2)
      return prediction
      #label = Y[index]
      #print("Prediction: ", prediction)

      #current_image = vect_X.reshape((WIDTH, HEIGHT)) * SCALE_FACTOR

      #plt.gray()
      #plt.imshow(current_image, interpolation='nearest')
      #plt.show()
  def predict(a):
    show_from_input(a, W1, b1, W2, b2)
      


############## MAIN ##############

(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
SCALE_FACTOR = 255 # TRES IMPORTANT SINON OVERFLOW SUR EXP
WIDTH = X_train.shape[1]
HEIGHT = X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0],WIDTH*HEIGHT).T / SCALE_FACTOR
X_test = X_test.reshape(X_test.shape[0],WIDTH*HEIGHT).T  / SCALE_FACTOR

W1, b1, W2, b2 = hrd.gradient_descent(X_train, Y_train, 0.15, 200)
 

pickle.dump(kt,open('model.pkl','wb'))
model=pickle.load(open('model.pkl','rb'))

It's giving me the error

  File "app.py", line 17, in <module>
    model=pickle.load(open('model.pkl','rb'))

AttributeError: Can't get attribute 'hrd' on <module '__main__' from 'app.py'>

And my server flask code:

from flask import Flask, flash, request, redirect, url_for, render_template
import urllib.request
import os
import pickle
from werkzeug.utils import secure_filename
 
app = Flask(__name__)
 
UPLOAD_FOLDER = 'static/uploads/'
 
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
 
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

model=pickle.load(open('model.pkl','rb'))
 
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
     
 
@app.route('/')
def home():
    return render_template('index.html')
 
@app.route('/', methods=['POST'])
def upload_image():
    if 'file' not in request.files:
        flash('No file part')
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        flash('No image selected for uploading')
        return redirect(request.url)
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        #print('upload_image filename: ' + filename)
        flash('Image successfully uploaded and displayed below')
        img = cv2.imread(filename,0)
        resized = cv2.resize(img, (28,28)) 
        features = resized.reshape(1,-1) / SCALE_FACTOR
        #print(X_test[:,100,None])
        
        x = model.predict(features[0][:,None])
        return render_template('index.html',pred = x, filename=filename)
    else:
        flash('Allowed image types are - png, jpg, jpeg, gif')
        return redirect(request.url)
 
@app.route('/display/<filename>')
def display_image(filename):
    #print('display_image filename: ' + filename)
    return redirect(url_for('static', filename='uploads/' + filename), code=301)
 
if __name__ == "__main__":
    app.run()
enter code here
0 Answers
Related