Reputation: 21
The problem is I have a flask app, which predict spam or ham text, by taking input from user. I have two 'joblib' models with pipelines for text preprocessing and prediction (with tensorflow)
This is my app.py
from flask import Flask, render_template,request, jsonify
import joblib
import os
import pickle
from pipe_classes import TextPreprocessor, KerasClassifier
app = Flask(__name__)
@app.route("/") # Site end
def hello():
return render_template("index.html")
@app.route("/predict", methods=['POST', 'GET'])
def predict():
data = request.get_json()
text = data.get('inputText')
if text != None:
print(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'))
with open(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'), 'rb') as f:
preprocess = pickle.load(f)
# preprocess = joblib.load(os.path.join(os.path.dirname(__file__), 'Models', 'Preprocessing.joblib'))
# model = joblib.load(os.path.join(os.path.dirname(__file__), 'Models', 'spam-ham-pipe.joblib'))
with open(os.path.join(os.path.dirname(__file__), 'Models', 'spam-ham-pipe.joblib'), 'rb') as f:
model = pickle.load(f)
ans = model.predict(preprocess.transform([text]))
ans = ans[0]
else:
ans=""
# return render_template("index.html", answer=ans)
return jsonify({'answer': ans})
if __name__ == "__main__":
from pipe_classes import TextPreprocessor, KerasClassifier
app.run(debug=True)
And these are the classes it takes for pipeline to load pipe_classes.py
from sklearn.base import TransformerMixin, BaseEstimator, ClassifierMixin
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import numpy as np
class TextPreprocessor(BaseEstimator, TransformerMixin):
def __init__(self, max_vocab_size=20000, max_len=None):
self.max_vocab_size = max_vocab_size
self.max_len = None
self.tokenizer = Tokenizer(num_words=self.max_vocab_size)
def fit(self, X, y=None):
print("Text: ", X)
self.tokenizer.fit_on_texts(X)
self.word_index = self.tokenizer.word_index
self.max_len = len(self.word_index)
self.vocab_size = len(self.word_index)
if self.max_len is None:
self.max_len = max(len(seq) for seq in self.tokenizer.texts_to_sequences(X))
return self
def transform(self, X, y=None):
print("Inside tranform function")
seqs = self.tokenizer.texts_to_sequences(X)
X_padded = pad_sequences(seqs, maxlen=self.max_len)
print("X_padded: ", X_padded)
return X_padded
class KerasClassifier(BaseEstimator, ClassifierMixin):
def __init__(self, model):
self.model = model
def fit(self, X, y):
print("Inside Keras Clasifier fit")
# Next time I will do training of model here
return self
def label(self, predictions):
# ans = ["Spam" if pred_i[0]==1 else "Ham" for pred_i in predictions]
ans = []
print("Inside label")
for pred_i in predictions:
print(pred_i)
if pred_i == 1:
ans.append("Spam")
else:
ans.append("Ham")
return ans
def predict(self, X):
print(X)
predictions = self.model.predict(X)
pred = (predictions >= 0.5).astype(int)
print("Predictions: ", predictions)
return self.label(pred)
Problem:
When I am running app.py
, in local system its giving correct output, but as soon as i deployed the whole site in Render,
But when I input some text, it shows this error:
AttributeError: Can't get attribute 'TextPreprocessor' on <module '__main__' from '/opt/render/project/src/.venv/bin/gunicorn'>
Seems like it can't find TextPreprocessor
class, when i used these classes in app.py
same issue occured..
I am stuck in this issue
Upvotes: 1
Views: 24