我使用带 flask 的python创建了一个简单的ML API。它从sample.csv获取数据,并基于该数据训练逻辑回归模型。我还有一个'/ predict'端点,可以在其中输入参数以供模型进行预测。


localhost:80/predict?weight1=1.2&weight2=0.00123&&weight3=0.45将输出{ "predicted": 1}
main.py:

from sklearn.linear_model import LogisticRegression
from flask import Flask, request
import numpy as np

# Create Flask object to run
app = Flask(__name__)

@app.route('/')
def home():
    return "Predicting status from other features"


@app.route('/predict')
def predict():
    # Get values from the server
    weight1 = request.args['weight1']
    weight2 = request.args['weight2']
    weight3 = request.args['weight3']

    testData = np.array([weight1, weight2, weight3]).reshape(1, -1)

    class_predicted = logisticRegr.predict(testData.astype(float))

    output = "{ \"predicted\": " + "\"" + class_predicted[0] + "\"" +  "}"

    return output


# Train and load the model based on the MetroPCS_Sample
def load_model():
    global logisticRegr
    label_y = []
    label_x = []

    with open('sample.csv') as f:
        lines = f.readlines()
        for line in lines[1:]:
            # Adding labels to label_y
            label_y.append(int(line[0]))
            line = line.strip().split(",")
            x_data = []
            for e in line[1:]:
            # Adding other features to label_x
                x_data.append(float(e))
            label_x.append(x_data)


    train_x = label_x[:700]
    train_y = label_y[:700]

    test_x = label_x[700:1000]
    test_y = label_y[700:1000]

    logisticRegr = LogisticRegression()


    logisticRegr.fit(train_x, train_y)

    predictions = logisticRegr.predict(test_x)

    score = logisticRegr.score(test_x, test_y)
    # print score

if __name__ == "__main__":
    print("Starting Server...")

    # Call function that loads Model
    load_model()

    # Run Server
    app.run(host="127.0.0.1", debug=True, port=80)

当我在没有容器的情况下运行此脚本时,一切工作正常。

但是,当我将其放在容器中并运行它时,出现以下错误:
NameError: global name 'logisticRegr' is not not defined
Dockerfile
FROM tiangolo/uwsgi-nginx-flask:python2.7

# copy over our requirements.txt file
COPY requirements.txt /tmp/

# upgrade pip and install required python packages
RUN pip install -U pip
RUN pip install -r /tmp/requirements.txt

COPY ./app /app

ENV MESSAGE "hello"

requirements.txt
Flask
numpy
sklearn
scipy

您知道脚本在容器内时会导致NameError的原因吗?

最佳答案

在您的def load_model()中。您有global logisticRegr
仅使用global关键字不会使您的变量成为全局变量。

当您要访问和更改函数内部的全局变量时,使用global。由于您的logisticRegr不是全局的,

当您尝试使用def predict()访问它时,
class_predicted = logisticRegr.predict(testData.astype(float))您将获得NameError: global name 'logisticRegr' is not defined

现在解决您的问题。像这样初始化logisticRegr变量后,初始化/声明app模型变量:

# Create Flask object to run
app = Flask(__name__)
logisticRegr = LogisticRegression()

然后从load_model之后的test_y = label_y[700:1000]中删除变量初始化

PS:建议大写全局变量。以便在您的代码中轻松识别它们。

10-07 12:53