質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

856閲覧

Not Found The requested URL was not found on the serveの問題解決

jaogjig

総合スコア21

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/03/15 18:34

実現したいこと

pythonで音楽のジャンルを学習して分類するwebアプリをflaskで実装したい

前提

ここに質問の内容を詳しく書いてください。
(例)
TypeScriptで●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

http://127.0.0.1:5000の/ページは実装できているのですが、Uploadボタンを押したら(/predict)
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
のエラーが出てきました。
調べたところ
ルーティングが原因と思いましたが、render_template('predict.html', table_html=table_html)の部分、@app.route('/predict', methods=['POST'])の部分、<form action="/predict" method="post" enctype="multipart/form-data">の部分とスペルの間違いなどがないかチェックしたのですが自分が見た限りでは間違っていないと思われます。
他にどこが原因なのかご教授お願いします。

該当のソースコード

index.html

1<!DOCTYPE html> 2<html> 3 <head> 4 <title>Music Genre Classifier</title> 5 </head> 6 <body> 7 <h1>Music Genre Classifier</h1> 8 <form action="/predict" method="post" enctype="multipart/form-data"> 9 <input type="file" name="file" accept=".wav,.mp3,.au,.aiff"> 10 <input type="submit" value="Upload"> 11 </form> 12 </body> 13</html>

predict.html

1<!DOCTYPE html> 2<html> 3 <head> 4 <title>予測結果</title> 5 </head> 6 <body> 7 <h1>予測結果</h1> 8 {% if table_html %} 9 {{ table_html }} 10 {% else %} 11 <p>分類結果がありません。</p> 12 {% endif %} 13 </form> 14 </body> 15</html> 16

result.py

1import torch 2from app import extract_features,Net 3from flask import Flask, render_template,request 4 5app = Flask(__name__) 6 7@app.route('/predict', methods=['POST']) 8def predict(): 9# モデルの読み込み 10 model = Net() 11 model.load_state_dict(torch.load('model.pt')) 12 model.eval() 13 # 音声ファイルに対して分類結果を取得するコード 14 audio_files = request.files['file'] 15 predicted_classes = [predict_class(audio_file) for audio_file in audio_files] 16 # 分類結果を表示する表のHTMLコード 17 table_html = show_table(audio_files, predicted_classes) 18 return render_template('predict.html', table_html=table_html) 19 20def show_table(audio_files, predicted_classes): 21 rows = [] 22 for i in range(len(audio_files)): 23 rows.append(f"<tr><td>{audio_files[i]}</td><td>{predicted_classes[i]}</td></tr>") 24 table_html = "<table><tr><th>音声ファイル名</th><th>予測ラベル</th></tr>" + "".join(rows) + "</table>" 25 return table_html 26 27# 分類結果を取得するコード 28def predict_class(audio_file): 29 mfcc = extract_features(audio_file) 30 input_tensor = torch.tensor(mfcc, dtype=torch.float32) 31 input_tensor = input_tensor.unsqueeze(0) 32 with torch.no_grad(): 33 model = Net() 34 predicted_class = model(input_tensor).argmax(dim=1).item() 35 return predicted_class 36 37 38# 分類結果を表示するHTMLコード 39html = """ 40<!DOCTYPE html> 41<html> 42 <head> 43 <title>音声分類結果</title> 44 </head> 45 <body> 46 <h1>音声分類結果</h1> 47 {} 48 </body> 49</html> 50""" 51 52if __name__ == '__main__': 53 app.run()

app.py

1import os 2import librosa 3from flask import Flask, render_template,request 4import numpy as np 5import torch 6from torch.nn import CrossEntropyLoss 7import torch.nn.functional as F 8from torch.utils.data import DataLoader, Dataset 9from sklearn.model_selection import train_test_split 10import glob 11 12 13app = Flask(__name__) 14@app.route('/') 15def index(): 16 return render_template('index.html') 17 18def extract_features(file_path): 19 # ファイルから音声データをロード 20 signal, sample_rate = librosa.load(file_path, sr=None) 21 22 # メル周波数ケプストラム係数 (MFCC音声を数値データに変換する際に使われる手法) の算出 23 mfccs = librosa.feature.mfcc(signal, sample_rate, n_mfcc=20) 24 25 # 平均を取ることで、1つのフレームに圧縮 各列(時間軸)に沿った平均値を計算して、結果を1次元の行列に格納します。 26 mfccs = np.mean(mfccs, axis=1) 27 28 return mfccs 29#MFCC1つ目の引数はオーディオ信号を表すnumpy配列2つ目の引数はサンプリングレートを表しますn_mfccパラメータは、計算されるMFCCの数を決定します。 30def mfcc(audio, sr): 31 return librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=40) 32 33# Define the neural network architecture 34class Net(torch.nn.Module): 35 def __init__(self): 36 super(Net, self).__init__() 37 self.fc1 = torch.nn.Linear(20, 100) 38 self.fc2 = torch.nn.Linear(100, 50) 39 self.fc3 = torch.nn.Linear(50, 10) 40 41 def forward(self, x): 42 x = F.relu(self.fc1(x)) 43 x = F.relu(self.fc2(x)) 44 x = self.fc3(x) 45 return F.log_softmax(x, dim=1) 46 def train_net(self, train_loader, optimizer, criterion, epoch): 47 self.train() 48 train_loss = 0#トレーニング中に計算される損失と正確性のための変数 49 correct = 0 50 #batch_idxは、現在のバッチのインデックス 51 for batch_idx, (data, target) in enumerate(train_loader):#enumerate(train_loader)は、データセットのバッチごとにインデックスとそれに対応するデータを返すイテレーターです。イテレーターとは、データの集まりを順番に取り出して処理するための仕組みです。 52 optimizer.zero_grad()#以前のバッチで計算された勾配をリセットします。 53 output = self(data.float())#モデルに入力データを提供し、出力を計算します。 54 loss = criterion(output, target) 55 train_loss += loss.item() 56 pred = output.argmax(dim=1, keepdim=True)#各入力に対する予測クラス 57 correct += pred.eq(target.view_as(pred)).sum().item()#予測クラスとラベルが一致する場合に正解数をインクリメントします。 58 loss.backward()#勾配計算 59 optimizer.step()#最適化関数パラメータを更新します 60 if batch_idx % 50 == 0:#50の倍数の場合、進捗状況を表示します 61 print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( 62 epoch, batch_idx * len(data), len(train_loader.dataset), 63 100. * batch_idx / len(train_loader), loss.item()))#correctは、正解ラベルを予測できたトレーニングデータの数です。 64 train_loss /= len(train_loader.dataset) 65 train_acc = 100. * correct / len(train_loader.dataset) 66 print('Train Epoch: {} \t Loss: {:.6f} \t Accuracy: {}/{} ({:.0f}%)'.format( 67 epoch, train_loss, correct, len(train_loader.dataset),#len(train_loader.dataset)はトレーニングデータの総数です。 68 100. * correct / len(train_loader.dataset)))#train_lossは、現在のエポックで計算されたトレーニングロスをトレーニングデータの数で除算して求めた平均ロスです。 69 print('Train set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format( 70 train_loss, correct, len(train_loader.dataset), train_acc))#{:.0f}%は小数点以下を表示しないようにしてパーセンテージを表示するための指定です。 71 if epoch % 5 == 0: 72 torch.save(self.state_dict(), 'model.pt') 73 74 #クラス終わり 75class MusicDataset(Dataset): 76 def __init__(self, data_path): 77 self.file_paths = glob.glob(data_path) 78 self.sample_rate = 22050 79 80 def __len__(self): 81 return len(self.file_paths) 82 83 def __getitem__(self, index): 84 file_path = self.file_paths[index] 85 86 # ファイルから音声データをロード 87 signal, sample_rate = librosa.load(file_path, sr=self.sample_rate) 88 89 # メル周波数ケプストラム係数 (MFCCs) の算出 90 mfccs = librosa.feature.mfcc(y=signal, sr=self.sample_rate, n_mfcc=40) 91 92 # 平均を取ることで、1つのフレームに圧縮 93 mfccs = np.mean(mfccs.T, axis=0) 94 95 # 正解ラベルの取得 96 label = os.path.splitext(os.path.basename(file_path))[0] 97 98 return mfccs, label 99 100 #ここまでがMusicDatasetクラスの終わり 101 102 103if __name__ == '__main__': 104#データの取得 105 x= []#空のリスト x を作成します 106 y = [] 107 genres= '/Users/genres'#ディレクトリ genres のパスを指定します。 108 for label in os.listdir(genres):#genres 内のディレクトリ内のファイルをループ処理します。 109 label_dir = os.path.join(genres, label)#ディレクトリ genres とループ処理中のファイル名 label を結合して、ファイルのディレクトリパスを取得します。 110 for file in os.listdir(label_dir): 111 file_path = os.path.join(label_dir, file)#具体的に何しているのディレクトリ label_dir とループ処理中のファイル名 file を結合して、ファイルのパスを取得します。 112 mfccs = mfcc(*librosa.load(file_path, sr=None))#librosa.load を使用して、ファイルを読み込み、mfcc 関数を使用してMFCCを抽出します。 113 x.append(mfccs)#MFCCをリスト x に追加します。 114 y.append(label)#ループ処理中のラベル名をリスト y に追加します。 115 x = np.array(x)#x リストを NumPy 配列に変換します。 116 y = np.array(y) 117 # 分割する the dataset into training and testing sets 118 X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42) 119 # Create DataLoader objects 120 train_dataset =MusicDataset(X_train, y_train) 121 test_dataset =MusicDataset(X_test, y_test) 122 train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) 123 test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False) 124 # Initialize the model, optimizer and loss function 125 model = Net() 126 optimizer = torch.optim.Adam(model.parameters(), lr=0.001) 127 criterion = torch.nn.CrossEntropyLoss() 128 # Train the model 129 for epoch in range(1, 51): 130 model.train_net(model, train_loader, optimizer, criterion, epoch) 131# Evaluate the model on the testing set 132 model.eval() 133 test_loss = 0 134 correct = 0 135#勾配を元にパラメータを修正 損失の記録 136 with torch.no_grad(): 137 for data, target in test_loader: 138 output = model(data.float()) 139 test_loss += F.nll_loss(output, target, reduction='sum').item() 140 pred = output.argmax(dim=1, keepdim=True) 141 correct += pred.eq(target.view_as(pred)).sum().item() 142 test_loss /= len(test_loader.dataset) 143 test_acc = 100. * correct / len(test_loader.dataset) 144 #損失の確認 145 print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), test_acc)) 146# Save the trained model 147 torch.save(model.state_dict(), 'model.pt') 148 app.run()

補足情報(FW/ツールのバージョンなど)

フォルダー構造
templates
index.html
predect.html
app.py
result.py
ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ファイルを分けて書く場合は、Blueprintを使用してください。

現状のコードだと、それぞれを起動しないと動きませんが、同じポートだと起動させることができず、同じポートで動かせない場合/predictにアクセスできないので動きません。

投稿2023/03/16 01:26

FiroProchainezo

総合スコア2401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問