AIを実装したWebアプリ(犬猫判定)のフロントエンドとバックエンドの接続の仕方(?)がよくわかりません。助けてください。
実現したいこと
- 犬か猫のjpgを入れるとどちらか判定してくれるwebアプリを作っています。ターミナル上では判定結果が表示されるのですが、ブラウザのフロントエンドではうまくいきません。なんとかしてフロントエンドでもうまく結果が表示される様にしたいです。
前提
VSCodeにおいて、Live Serverを使っています。
ターミナル上(つまりバックエンドだけ?)ならうまくいきます
ブラウザのフロントエンドでやると、コンソールにこの様にエラーが表示されます
DogvsCatAPPというファイルの中に関連するものを入れています。h5のやつがトレーニングしたmodelです。DogvsCat.ipynbとdogs-vs-cats(トレーニングに使用した写真が入ってる)は関係ないです(多分)。
発生している問題・エラーメッセージ
Access to fetch at 'http://localhost:5000/predict' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST http://localhost:5000/predict net::ERR_FAILED 403 (Forbidden)
classifyImage @ index.html:25
onclick @ index.html:11
Error during fetch operation: TypeError: Failed to fetch
at classifyImage (index.html:25:40)
at HTMLButtonElement.onclick (index.html:11:39)
classifyImage @ index.html:39
await in classifyImage (async)
onclick @ index.html:11
Ensure CORS response header values are valid
該当のソースコード
from flask import Flask, request, jsonify
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
import io
from PIL import Image
from flask_cors import CORS
from flask_cors import cross_origin
app = Flask(__name__)
CORS(app)
# モデルのロード
model = load_model('/Users/shosukesato/DogvsCatAPP/cats_vs_dogs.h5')
@app.route('/predict', methods=['POST'])
@cross_origin()
def predict():
if 'file' not in request.files:
return jsonify({'error': 'no file'}), 400
file = request.files['file']
if file.filename == '':
return jsonify({'error': 'no filename'}), 400
# 画像の読み込みと前処理
img = image.load_img(io.BytesIO(file.read()), target_size=(150, 150))
img_array = image.img_to_array(img)
img_array_expanded_dims = np.expand_dims(img_array, axis=0)
preprocessed_img = img_array_expanded_dims / 255. # モデルのトレーニング時と同じスケーリング
# 予測
prediction = model.predict(preprocessed_img)
# レスポンスの作成
if prediction >= 0.5:
predicted_class = 'dog'
else:
predicted_class = 'cat'
response = {'class': predicted_class}
return jsonify(response), 200, {'Access-Control-Allow-Origin': '*'}
# ローカルでAPIサーバーを実行
if __name__ == '__main__':
app.run(port=5000, debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cat or Dog Classifier</title>
</head>
<body>
<h1>Is it a cat or a dog?</h1>
<input type="file" id="fileInput" accept="image/*">
<button onclick="classifyImage()">Classify</button>
<p id="result"></p>
<script>
async function classifyImage() {
const fileInput = document.getElementById('fileInput');
const resultParagraph = document.getElementById('result');
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
resultParagraph.textContent = 'Classifying...';
try {
const response = await fetch('http://localhost:5000/predict', {
method: 'POST',
body: formData
});
if (!response.ok) {
console.error('Network response was not ok:', response);
resultParagraph.textContent = 'Network response was not ok';
return;
}
const result = await response.json();
resultParagraph.textContent = `It's a ${result.class}!`;
} catch (error) {
console.error('Error during fetch operation:', error);
resultParagraph.textContent = 'Error during classification';
}
}
</script>
</body>
</html>
試したこと
ChatGPTに聞いて一日中色々試した結果上記の様なコードになったのですが、もう無理です。
補足情報(FW/ツールのバージョンなど)
macbookairを使っています。初心者で他にどの様な情報が必要かわからないので、何か必要な情報があれば指摘してください。お願いいたします。