首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Uvicorn修复“‘无法将字典更新序列元素#0转换为序列’”的问题

使用Uvicorn修复“‘无法将字典更新序列元素#0转换为序列’”的问题
EN

Stack Overflow用户
提问于 2021-10-12 15:29:16
回答 1查看 162关注 0票数 0

我有以下代码与FastApi和Uvicorn的ASGI服务器实现。它应该通过post请求获取上传的图像,并在返回响应之前使用模型对其进行分类。这个错误似乎与Uvicorn有关,但我不知所措。任何帮助都将不胜感激。以前有没有人见过这样的错误?代码如下:

代码语言:javascript
运行
复制
import uvicorn
from fastapi import FastAPI, File, UploadFile
import sys

from PIL import Image
from io import BytesIO
import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing import image
import PIL
import sys 
from cv2 import cv2
from scipy import misc
import os

import shutil
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Callable

app = FastAPI()

model = keras.models.load_model('best_model6.h5')
input_shape = (180, 180) 

@app.post('/api/predict')
async def predict_image(file: UploadFile = File(...)):

    suffix = Path(file.filename).suffix

    with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
        shutil.copyfileobj(file.file, tmp)
        tmp_path = Path(tmp.name)
    
    img = keras.preprocessing.image.load_img(
    tmp_path, target_size=input_shape
)
    
    img_array = image.img_to_array(img)

    img_array = tf.expand_dims(img_array, 0)  # Create batch axis

    predictions = model.predict(img_array)
    score = predictions[0]

    file.file.close()
    tmp_path.unlink()
    
    return score


if __name__ == "__main__":
    uvicorn.run(app, port=8080, host='0.0.0.0', debug=True)

错误是:

代码语言:javascript
运行
复制
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]

以及整个回溯:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py", line 96, in __call__
    raise exc from None
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py", line 93, in __call__
    await self.app(scope, receive, inner_send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py", line 61, in app
    response = await func(request)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py", line 234, in app
    response_data = await serialize_response(
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py", line 148, in serialize_response
    return jsonable_encoder(response_content)
  File "/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/encoders.py", line 144, in jsonable_encoder
    raise ValueError(errors)
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]
EN

Stack Overflow用户

回答已采纳

发布于 2021-10-12 17:39:54

从Keras模型返回的predit函数是一个预测的Numpy数组(see here),每个预测也是一个numpy数组。

但是FastApi在响应(see here)中使用了jsonable_encoder,并且numpy数组是不可接受的。例如,您应该转换为list(score.tolist())以返回预测分数。在同一链接中,您将看到可以不使用jsonable_encoder直接返回响应

我希望我对你有所帮助。祝好运

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69543228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档