| <!DOCTYPE html>
|
| <html lang="zh-TW">
|
| <head>
|
| <meta charset="UTF-8">
|
| <title>AI 情緒分析 - ONNX Web</title>
|
| <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
|
| <style>
|
| body { font-family: sans-serif; max-width: 600px; margin: 40px auto; padding: 20px; line-height: 1.6; }
|
| textarea { width: 100%; padding: 10px; margin-bottom: 10px; border-radius: 8px; border: 1px solid #ccc; }
|
| button { padding: 10px 20px; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 5px; }
|
| #result { margin-top: 20px; padding: 15px; border-radius: 8px; background: #f8f9fa; font-weight: bold; }
|
| </style>
|
| </head>
|
| <body>
|
| <h2>🎭 電影評論情緒分析 (邊緣運算)</h2>
|
| <p>輸入一段英文短句進行測試:</p>
|
| <textarea id="inputText" rows="3">This Movie is incredibly helpful and well-organized!</textarea>
|
| <button id="runBtn">開始分析</button>
|
|
|
| <div id="result">正在初始化模型...</div>
|
|
|
| <script>
|
| let session;
|
| let wordIndex;
|
| const MAX_LEN = 48;
|
|
|
|
|
| async function init() {
|
| try {
|
|
|
| session = await ort.InferenceSession.create('./best_lstm.onnx');
|
|
|
| wordIndex = await fetch('./word_index.json').then(r => r.json());
|
| document.getElementById('result').innerText = "✅ 模型載入成功,可以開始分析。";
|
| } catch (e) {
|
| document.getElementById('result').innerText = "❌ 錯誤: " + e.message;
|
| }
|
| }
|
|
|
|
|
| function preprocess(text) {
|
|
|
| const tokens = text.toLowerCase().replace(/[^\w\s]/g, '').trim().split(/\s+/);
|
|
|
| let sequence = tokens.map(t => wordIndex[t] || 1);
|
|
|
|
|
| if (sequence.length > MAX_LEN) {
|
| sequence = sequence.slice(0, MAX_LEN);
|
| } else {
|
| while (sequence.length < MAX_LEN) sequence.push(0);
|
| }
|
|
|
| return new Float32Array(sequence);
|
| }
|
|
|
|
|
| async function runInference() {
|
| const text = document.getElementById('inputText').value;
|
| if (!text.trim()) return;
|
|
|
| document.getElementById('result').innerText = "分析中...";
|
|
|
| const inputData = preprocess(text);
|
| const tensor = new ort.Tensor('float32', inputData, [1, MAX_LEN]);
|
|
|
|
|
| const feeds = { input_layer: tensor };
|
| const results = await session.run(feeds);
|
| const output = results.output_0.data;
|
|
|
|
|
| const predIdx = output.indexOf(Math.max(...output));
|
| const labels = ["👿 極度負面", "🙁 負面", "😐 中性", "🙂 正面", "🌟 極度正面"];
|
| const colors = ["#d9534f", "#f0ad4e", "#6c757d", "#5bc0de", "#5cb85c"];
|
|
|
| const resDiv = document.getElementById('result');
|
| resDiv.innerText = `結果:${labels[predIdx]}`;
|
| resDiv.style.color = "white";
|
| resDiv.style.backgroundColor = colors[predIdx];
|
| }
|
|
|
| document.getElementById('runBtn').onclick = runInference;
|
| init();
|
| </script>
|
| </body>
|
| </html> |