2025年,回顧一下我做了什麼發現,
對了,我參加了健美比賽。
雖然在比賽中非常不幸未能通過預選,
但由於有以下資料,我打算好好分析一下。
┌─────────────────────┐
│ Step1: 絕對評價 │ ← 以1天為單位的圖像1張的評價及體重數據
└─────────────────────┘
↓
┌─────────────────────┐
│ Step2: 相對評價 │ ← 時序分析趨勢
└─────────────────────┘
↓
┌─────────────────────┐
│ Step3: 總評價 │
└─────────────────────┘
模型有很多,
但我們使用的模型在規格上合理,且適合進行圖像分析。
ollama pull llava:7b
輸出限制在以下6項。
shoulder(肩寬)chest(胸部)waist(腰圍)legs(腿部)bodyfat(外觀脂肪)posture(姿勢)每個項目均以「狹窄 / 普通 / 稍寬 / 寬」等形式,
從預設標籤中選擇一個,以便後續處理。
手動分析數百張照片實在不太現實,
所以透過Python調用Ollama的HTTP API進行批量處理。
大致結構如下:
# analyze_images.py (圖像)
MODEL = "llava:7b"
API_URL = "http://localhost:11434/api/generate"
HEADER = ["filename", "shoulder", "chest", "waist", "legs", "bodyfat", "posture"]
PROMPT = """僅以以下JSON格式輸出。禁止任何描述性的文字。
{
"shoulder": "",
"chest": "",
"waist": "",
"legs": "",
"bodyfat": "",
"posture": ""
}
請從以下候選中選擇一項並填入每個項目。
- shoulder: 狹窄 / 普通 / 稍寬 / 寬
- chest: 未發達 / 普通 / 稍發達 / 發達
- waist: 瘦 / 普通 / 稍胖 / 胖
- legs: 瘦 / 普通 / 稍發達 / 發達
- bodyfat: 少 / 普通 / 稍多 / 多
- posture: 良好 / 普通 / 稍差 / 差
"""
def analyze_image(path: Path) -> dict:
img_b64 = base64.b64encode(path.read_bytes()).decode()
payload = {
"model": MODEL,
"prompt": PROMPT,
"images": [img_b64],
"stream": False,
}
res = requests.post(API_URL, json=payload, timeout=120)
res.raise_for_status()
raw = res.json()["response"].strip()
return json.loads(json_str)
def main():
with OUT_CSV.open("a", newline="") as f:
writer = csv.writer(f)
for img in files:
result = analyze_image(img)
writer.writerow([
img.name,
result.get("shoulder", ""),
result.get("chest", ""),
result.get("waist", ""),
result.get("legs", ""),
result.get("bodyfat", ""),
result.get("posture", ""),
])
執行此腳本後,最終將生成如下CSV:
filename,shoulder,chest,waist,legs,bodyfat,posture
0001.jpg,普通,發達,胖,多,多,差
0002.jpg,普通,發達,胖,普通,多,良好
...
這樣我們就得到了「每張圖像的6個標籤描述數據集」。
從健康管理連接的體重秤應用程式中,
將日期和體重數據匯出為CSV格式。
再將Step1的CSV與體重信息合併。
最終的CSV格式如下:
filename,photo_date,weight_kg,shoulder,chest,waist,legs,bodyfat,posture
0001.jpg,2024-03-12,77.9,普通,普通,普通,普通,普通,普通
0002.jpg,2024-03-13,77.7,普通,發達,稍胖,發達,多,差
:
0227.jpg,2025-02-14,59.4,普通,發達,瘦,發達,少,良好
0228.jpg,2025-02-14,59.4,普通,發達,普通,發達,少,良好
0229.jpg,2025-02-15,59.6,普通,普通,普通,普通,普通,暫時不自然
0230.jpg,2025-02-16,58.8,普通,發達,瘦,瘦,少,良好
到目前為止,
已經整合成一個CSV。
接下來,將這個CSV傳遞給多個本地LLM,
來進行「一年的變化總體回顧」的部分。
這次,我將相同的CSV交給Ollama上的3個模型進行比較。
| 模型 | 特點 |
|---|---|
| phi3:mini | 超輕量且快速,但長文摘要容易失誤 |
| phi3:14b | 分析穩定,家庭電腦也能實用 |
| mixtral:8x7b | 高性能MoE模型 |
將此次的CSV傳遞給多個本地LLM後,各模型的「擅長與不擅長」明顯區分開來。
儘管非常輕量且反應迅速,但在保持長CSV的情況下,同時整合多指標的關聯性處理並不擅長,常出現時序一致性崩潰的狀況。
輕量模型雖然擅長小型標記處理,但跨越多日資料的大型推理似乎達到了極限。
文脈崩潰導致錯字及不同語言的混雜,長文本處理的缺陷顯而易見。
(輸出結果摘錄)
從3月27日(初始體重: 55kg)到2024年2月6日(初始體重: 57kg),體重發生了逆轉。
13月4日的日文推移:體重由55kg減少到57kg
因緊急情況進入降低等待階段...
比起mini更為穩定,能在一定程度上捕捉體重的增減與標籤的趨勢,但摘要略顯不穩定。
在家庭PC上也能有效處理,適合簡易的分析。
(輸出結果摘錄)
體重變化: 「發展期」(2025-06-16至2025-06-23)、「停滯期」(2025-07-21至2025-08-03)、「增長點」(2025-09-07之後)
瘦腹部的偏頭痛改善明顯
學到的:雖然偶有停滯,但從長期來看,體重逐漸減少。
性能符合期望,但因電腦規格不足而凍結,無法用於此次分析。
總的來看,本地LLM的圖像標籤化(Step1)非常有效,
但「整合一年數據進行總評價」這一任務受到模型規模和上下文保持能力的影響,結果反映出明顯差異。
在時序整合1年的標籤和體重後,體型變化呈現出明顯的趨勢。
當體重低於70kg時,腰圍和身體脂肪穩定移向「瘦 / 少」的方向,
與此同時,胸部和腿部的「發達」在體重最小期仍然維持,
表明減肥過程中幾乎未損失肌肉量。
而姿勢(posture)則在體重下降後才逐漸改善,即使在看似停滯的時期,
姿勢及肌肉量的標籤仍有變化,顯示出並非簡單的「不減」期,而是身體調整的階段確實存在。
整體來看,減重不僅僅是數字下降,
而是有分別隨時期變化的“下降指標、維持指標和遲緩變化的指標”,
透過整合圖像標籤和體重,我們能更清楚地看到這一結構。
回顧一年數據,
我發現自己的身體變化超出預期。
數據難以察覺的改善或停滯,
照片未能揭示的趨勢,這次的分析成為了有意義的回顧。
未來,我希望能更好地使用其他LLM。