feat(i18n): add AI history components internationalization support
- Add useI18n composable and ai-history locale files - Refactor 10 AI history Vue components to support i18n (GPTEvolutionDemo, AIErasComparisonDemo, AiEvolutionDemo, etc.) - Add English version of AI history appendix article - Add English translations for stage-1 appendix-articles: - vibe-coding-tools-snake-game-tutorial.md - vibe-coding-tools-build-website-with-ai-coding-and-design-agents.md - Use relative paths to reference Chinese version images - Update appendix sidebar config to use English AI history link
This commit is contained in:
@@ -806,7 +806,7 @@ const appendixSidebarEn = [
|
||||
items: [
|
||||
{
|
||||
text: 'AI History & Concepts',
|
||||
link: '/zh-cn/appendix/8-artificial-intelligence/ai-history'
|
||||
link: '/en/appendix/8-artificial-intelligence/ai-history'
|
||||
},
|
||||
{
|
||||
text: 'Neural Networks',
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
<div class="demo-card">
|
||||
<div class="era-container">
|
||||
<div class="era-header">
|
||||
🌟 AI 发展阶段与核心范式全景对比
|
||||
{{ t('erasComparison.header') }}
|
||||
</div>
|
||||
<div class="era-grid">
|
||||
<div v-for="era in eras" :key="era.name" class="era-item" :style="{ borderTopColor: era.color }">
|
||||
<div class="e-icon" :style="{ background: era.color }">{{ era.icon }}</div>
|
||||
<div class="e-name" :style="{ color: era.color }">{{ era.name }}</div>
|
||||
<div v-for="(era, i) in localEras" :key="i" class="era-item" :style="{ borderTopColor: eraStyles[i]?.color }">
|
||||
<div class="e-icon" :style="{ background: eraStyles[i]?.color }">{{ eraStyles[i]?.icon }}</div>
|
||||
<div class="e-name" :style="{ color: eraStyles[i]?.color }">{{ era.name }}</div>
|
||||
<div class="e-time">{{ era.time }}</div>
|
||||
|
||||
|
||||
<div class="e-section">
|
||||
<div class="e-label">驱动方式</div>
|
||||
<div class="e-label">{{ t('erasComparison.driverLabel') }}</div>
|
||||
<div class="e-value">{{ era.driver }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="e-section">
|
||||
<div class="e-label">核心机制</div>
|
||||
<div class="e-label">{{ t('erasComparison.mechanismLabel') }}</div>
|
||||
<div class="e-value">
|
||||
<span class="highlight">{{ era.mechanism }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="e-section">
|
||||
<div class="e-label">典型代表</div>
|
||||
<div class="e-label">{{ t('erasComparison.examplesLabel') }}</div>
|
||||
<div class="e-tags">
|
||||
<span v-for="tag in era.examples" :key="tag" class="e-tag">{{ tag }}</span>
|
||||
</div>
|
||||
@@ -35,52 +35,19 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const eras = [
|
||||
{
|
||||
name: '规则系统时代',
|
||||
time: '1960s - 1980s',
|
||||
icon: '📜',
|
||||
color: '#059669', // emerald
|
||||
driver: '人类硬编码知识',
|
||||
mechanism: 'If-Then 逻辑推演',
|
||||
examples: ['Dendral', '深蓝 (Deep Blue)']
|
||||
},
|
||||
{
|
||||
name: '传统机器学习',
|
||||
time: '1990s - 2000s',
|
||||
icon: '📊',
|
||||
color: '#d97706', // amber
|
||||
driver: '人工特征工程 + 统计学',
|
||||
mechanism: '寻找数学决策边界',
|
||||
examples: ['支持向量机 (SVM)', '随机森林']
|
||||
},
|
||||
{
|
||||
name: '深度学习革命',
|
||||
time: '2010s',
|
||||
icon: '🧠',
|
||||
color: '#dc2626', // red
|
||||
driver: '大数据 + 算力爬升',
|
||||
mechanism: '神经网络自动提取特征',
|
||||
examples: ['AlexNet (CNN)', 'AlphaGo (RL)']
|
||||
},
|
||||
{
|
||||
name: '大语言模型 (LLM)',
|
||||
time: '2018 - 至今',
|
||||
icon: '💬',
|
||||
color: '#7c3aed', // violet
|
||||
driver: '海量无标注数据 + 暴力计算',
|
||||
mechanism: '预测下一个词 + 涌现常识',
|
||||
examples: ['GPT-4', 'Claude 3']
|
||||
},
|
||||
{
|
||||
name: '智能体 (Agentic AI)',
|
||||
time: '现在 - 未来',
|
||||
icon: '🤖',
|
||||
color: '#0284c7', // light blue
|
||||
driver: '大模型大脑 + 环境感知',
|
||||
mechanism: '自主规划 + 工具调用',
|
||||
examples: ['AI 程序员', '具身智能']
|
||||
}
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const localEras = computed(() => messages.value.erasComparison?.eras ?? [])
|
||||
|
||||
const eraStyles = [
|
||||
{ icon: '📜', color: '#059669' },
|
||||
{ icon: '📊', color: '#d97706' },
|
||||
{ icon: '🧠', color: '#dc2626' },
|
||||
{ icon: '💬', color: '#7c3aed' },
|
||||
{ icon: '🤖', color: '#0284c7' },
|
||||
]
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
<template>
|
||||
<div class="demo-card">
|
||||
<div class="timeline-visual">
|
||||
<div v-for="era in eras" :key="era.label" class="era" :style="{ flex: era.flex, background: era.bg }">
|
||||
<div class="era-label">{{ era.label }}</div>
|
||||
<div class="era-years">{{ era.years }}</div>
|
||||
<div v-for="(era, i) in eras" :key="i" class="era" :style="{ flex: era.flex, background: era.bg }">
|
||||
<div class="era-label">{{ localeEras[i]?.label ?? era.label }}</div>
|
||||
<div class="era-years">{{ localeEras[i]?.years ?? era.years }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legend">
|
||||
<span class="legend-item"><span class="dot" style="background:#059669"></span>技术浪潮</span>
|
||||
<span class="legend-item"><span class="dot" style="background:#94a3b8"></span>❄️ AI 寒冬</span>
|
||||
<span class="legend-item"><span class="dot" style="background:#7c3aed"></span>大模型时代</span>
|
||||
<span class="legend-item"><span class="dot" style="background:#059669"></span>{{ t('aiEvolution.legend.wave') }}</span>
|
||||
<span class="legend-item"><span class="dot" style="background:#94a3b8"></span>{{ t('aiEvolution.legend.winter') }}</span>
|
||||
<span class="legend-item"><span class="dot" style="background:#7c3aed"></span>{{ t('aiEvolution.legend.llm') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const localeEras = computed(() => messages.value.aiEvolution?.eras ?? [])
|
||||
|
||||
const eras = [
|
||||
{ label: '理论奠基', years: '1940s-50s', flex: 1.5, bg: 'linear-gradient(135deg, #dbeafe, #bfdbfe)' },
|
||||
{ label: '第一次浪潮', years: '1960s-70s', flex: 1.5, bg: 'linear-gradient(135deg, #d1fae5, #a7f3d0)' },
|
||||
{ label: '❄️ 寒冬 I', years: '1974-80', flex: 0.7, bg: 'linear-gradient(135deg, #e2e8f0, #cbd5e1)' },
|
||||
{ label: '第二次浪潮', years: '1980s', flex: 1, bg: 'linear-gradient(135deg, #d1fae5, #a7f3d0)' },
|
||||
{ label: '❄️ 寒冬 II', years: '1987-93', flex: 0.7, bg: 'linear-gradient(135deg, #e2e8f0, #cbd5e1)' },
|
||||
{ label: 'ML 崛起', years: '1990s-2000s', flex: 1.5, bg: 'linear-gradient(135deg, #d1fae5, #6ee7b7)' },
|
||||
{ label: '深度学习', years: '2010s', flex: 1.2, bg: 'linear-gradient(135deg, #a7f3d0, #34d399)' },
|
||||
{ label: '大模型时代', years: '2018+', flex: 1.2, bg: 'linear-gradient(135deg, #c4b5fd, #a78bfa)' },
|
||||
{ flex: 1.5, bg: 'linear-gradient(135deg, #dbeafe, #bfdbfe)' },
|
||||
{ flex: 1.5, bg: 'linear-gradient(135deg, #d1fae5, #a7f3d0)' },
|
||||
{ flex: 0.7, bg: 'linear-gradient(135deg, #e2e8f0, #cbd5e1)' },
|
||||
{ flex: 1, bg: 'linear-gradient(135deg, #d1fae5, #a7f3d0)' },
|
||||
{ flex: 0.7, bg: 'linear-gradient(135deg, #e2e8f0, #cbd5e1)' },
|
||||
{ flex: 1.5, bg: 'linear-gradient(135deg, #d1fae5, #6ee7b7)' },
|
||||
{ flex: 1.2, bg: 'linear-gradient(135deg, #a7f3d0, #34d399)' },
|
||||
{ flex: 1.2, bg: 'linear-gradient(135deg, #c4b5fd, #a78bfa)' },
|
||||
]
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="demo-card">
|
||||
<div class="attention-layout">
|
||||
<div class="sentence-col">
|
||||
<div class="col-label">处理「<strong>他</strong>」时的注意力分配:</div>
|
||||
<div class="col-label" v-html="colLabel"></div>
|
||||
<div class="sentence-box">
|
||||
<span v-for="(word, i) in sentence" :key="i" class="word-token" :class="{ focus: i === focusIdx }">{{ word }}</span>
|
||||
</div>
|
||||
@@ -18,16 +18,26 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="caption">
|
||||
「他」虽在句中间,模型却把 65% 注意力精准投向句首的「小明」,跨越距离识别代词指代
|
||||
{{ t('attention.caption') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const sentence = ['小明', '把', '苹果', '给了', '他', '的', '母亲']
|
||||
const focusIdx = 4
|
||||
const attn = [0.65, 0.05, 0.10, 0.10, 0.05, 0.03, 0.02]
|
||||
const weights = sentence.map((word, i) => ({ word, w: attn[i] }))
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
|
||||
const attnData = computed(() => messages.value.attention ?? {})
|
||||
const sentence = computed(() => attnData.value.sentence ?? [])
|
||||
const focusIdx = computed(() => attnData.value.focusIdx ?? 4)
|
||||
const rawWeights = computed(() => attnData.value.weights ?? [])
|
||||
const weights = computed(() => sentence.value.map((word, i) => ({ word, w: rawWeights.value[i] ?? 0 })))
|
||||
const focusWord = computed(() => sentence.value[focusIdx.value] ?? '')
|
||||
const colLabel = computed(() => (attnData.value.colLabel ?? '').replace('{word}', focusWord.value))
|
||||
|
||||
const barColor = (v) => v > 0.5 ? '#dc2626' : v > 0.15 ? '#d97706' : v > 0.06 ? '#059669' : 'var(--vp-c-divider)'
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="demo-card">
|
||||
<div class="bp-flow">
|
||||
<div v-for="(step, i) in steps" :key="i" class="step-block" :style="{ borderTopColor: step.color }">
|
||||
<div class="step-num" :style="{ background: step.color }">{{ i + 1 }}</div>
|
||||
<div v-for="(step, i) in localSteps" :key="i" class="step-block" :style="{ borderTopColor: stepColors[i] }">
|
||||
<div class="step-num" :style="{ background: stepColors[i] }">{{ i + 1 }}</div>
|
||||
<div class="step-icon">{{ step.icon }}</div>
|
||||
<div class="step-name">{{ step.name }}</div>
|
||||
<div class="step-desc">{{ step.desc }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loss-visual">
|
||||
<div class="loss-label">Loss(误差)随训练轮次下降:</div>
|
||||
<div class="loss-label">{{ t('backprop.lossLabel') }}</div>
|
||||
<svg viewBox="0 0 320 130" class="loss-svg">
|
||||
<!-- Axes -->
|
||||
<line x1="40" y1="110" x2="300" y2="110" stroke="var(--vp-c-text-3)" stroke-width="1.5" />
|
||||
@@ -21,12 +21,12 @@
|
||||
<polygon points="37,15 40,10 43,15" fill="var(--vp-c-text-3)" />
|
||||
|
||||
<!-- Y Label -->
|
||||
<text x="30" y="25" text-anchor="end" class="ax-text">高</text>
|
||||
<text x="30" y="105" text-anchor="end" class="ax-text">低</text>
|
||||
<text x="30" y="25" text-anchor="end" class="ax-text">{{ t('backprop.axisHigh') }}</text>
|
||||
<text x="30" y="105" text-anchor="end" class="ax-text">{{ t('backprop.axisLow') }}</text>
|
||||
<text x="20" y="65" text-anchor="middle" transform="rotate(-90 20 65)" class="ax-title">Loss</text>
|
||||
|
||||
<!-- X Label -->
|
||||
<text x="300" y="125" text-anchor="end" class="ax-title">训练轮次 (Epochs)</text>
|
||||
<text x="300" y="125" text-anchor="end" class="ax-title">{{ t('backprop.axisEpochs') }}</text>
|
||||
|
||||
<!-- Loss 曲线 -->
|
||||
<polyline :points="lossPoints" fill="none" stroke="var(--vp-c-brand)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||
@@ -36,12 +36,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const steps = [
|
||||
{ icon: '➡️', name: '前向传播', desc: '数据流过网络,得出预测', color: '#3b82f6' },
|
||||
{ icon: '📐', name: '计算误差', desc: '预测值 vs 正确答案,算 Loss', color: '#d97706' },
|
||||
{ icon: '⬅️', name: '反向传播', desc: '逐层追溯每个权重的"责任"', color: '#dc2626' },
|
||||
{ icon: '⚙️', name: '更新权重', desc: '按责任微调,减少下次误差', color: '#059669' },
|
||||
]
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const localSteps = computed(() => messages.value.backprop?.steps ?? [])
|
||||
|
||||
const stepColors = ['#3b82f6', '#d97706', '#dc2626', '#059669']
|
||||
const lossPoints = (() => {
|
||||
const pts = []
|
||||
for (let i = 0; i <= 50; i++) {
|
||||
|
||||
+16
-9
@@ -1,24 +1,31 @@
|
||||
<template>
|
||||
<div class="demo-card">
|
||||
<div class="schools-grid">
|
||||
<div v-for="s in schools" :key="s.name" class="school-card" :style="{ borderTopColor: s.color }">
|
||||
<div v-for="(s, i) in schoolStyles" :key="i" class="school-card" :style="{ borderTopColor: s.color }">
|
||||
<div class="card-head">
|
||||
<span class="school-icon">{{ s.icon }}</span>
|
||||
<span class="school-name" :style="{ color: s.color }">{{ s.name }}</span>
|
||||
<span class="school-name" :style="{ color: s.color }">{{ localeItems[i]?.name }}</span>
|
||||
</div>
|
||||
<div class="school-idea">{{ s.idea }}</div>
|
||||
<div class="school-rep">代表:{{ s.rep }}</div>
|
||||
<div class="school-status">{{ s.status }}</div>
|
||||
<div class="school-idea">{{ localeItems[i]?.idea }}</div>
|
||||
<div class="school-rep">{{ t('schools.repLabel') }}:{{ localeItems[i]?.rep }}</div>
|
||||
<div class="school-status">{{ localeItems[i]?.status }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const schools = [
|
||||
{ name: '符号主义', icon: '📜', color: '#059669', idea: '智能 = 符号推理 / If-Then 规则', rep: '专家系统、深蓝', status: '→ 与连接主义融合(神经符号 AI)' },
|
||||
{ name: '连接主义', icon: '🧠', color: '#7c3aed', idea: '智能 = 神经元网络 + 海量数据', rep: 'AlphaGo、GPT 系列', status: '→ 主导大模型时代,当前主流' },
|
||||
{ name: '行为主义', icon: '🎮', color: '#d97706', idea: '智能 = 与环境互动 / 强化学习', rep: 'AlphaGo(RL 部分)', status: '→ 与连接主义融合(深度强化学习)' },
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const localeItems = computed(() => messages.value.schools?.items ?? [])
|
||||
|
||||
const schoolStyles = [
|
||||
{ icon: '📜', color: '#059669' },
|
||||
{ icon: '🧠', color: '#7c3aed' },
|
||||
{ icon: '🎮', color: '#d97706' },
|
||||
]
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
<template>
|
||||
<div class="demo-card">
|
||||
<div class="demo-label">符号主义的核心思路 ── 把知识写成规则</div>
|
||||
<div class="demo-label">{{ t('foundation.label') }}</div>
|
||||
<div class="code-block">
|
||||
<div class="code-line"><span class="kw">IF</span> 体温 > 38.5°C <span class="kw">AND</span> 白细胞计数 > 11000</div>
|
||||
<div class="code-line indent"><span class="kw">THEN</span> 诊断 = <span class="str">"细菌感染"</span></div>
|
||||
<div class="code-line"><span class="kw">IF</span> 诊断 = <span class="str">"细菌感染"</span> <span class="kw">AND</span> 对青霉素不过敏</div>
|
||||
<div class="code-line indent"><span class="kw">THEN</span> 治疗方案 = <span class="str">"青霉素 400mg / 每日两次"</span></div>
|
||||
<div class="code-line comment">// 早期医疗专家系统(MYCIN,1977)就是由 450+ 条这样的规则组成的</div>
|
||||
<div v-for="(line, i) in foundationLines" :key="i" class="code-line" :class="{ indent: line.indent }">
|
||||
<template v-for="(p, j) in line.parts" :key="j">
|
||||
<span v-if="p.kw" class="kw">{{ p.kw }}</span>
|
||||
<span v-else-if="p.str" class="str">{{ p.str }}</span>
|
||||
<template v-else>{{ p.text }}</template>
|
||||
</template>
|
||||
</div>
|
||||
<div class="code-line comment">{{ t('foundation.comment') }}</div>
|
||||
</div>
|
||||
<div class="demo-caption">人类专家把经验翻译成一条条 IF-THEN 规则,机器逐条匹配执行</div>
|
||||
<div class="demo-caption">{{ t('foundation.caption') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const foundationLines = computed(() => messages.value.foundation?.lines ?? [])
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="demo-card">
|
||||
<div class="gpt-grid">
|
||||
<div v-for="m in models" :key="m.name" class="gpt-card" :style="{ borderTopColor: m.color }">
|
||||
<div v-for="(m, i) in models" :key="i" class="gpt-card" :style="{ borderTopColor: modelColors[i] }">
|
||||
<div class="card-top">
|
||||
<span class="gpt-name" :style="{ color: m.color }">{{ m.name }}</span>
|
||||
<span class="gpt-name" :style="{ color: modelColors[i] }">{{ m.name }}</span>
|
||||
<span class="gpt-year">{{ m.year }}</span>
|
||||
</div>
|
||||
<div class="param-val">{{ m.params }}</div>
|
||||
<div class="param-bar-bg">
|
||||
<div class="param-bar" :style="{ width: m.barWidth, background: m.color }"></div>
|
||||
<div class="param-bar" :style="{ width: m.barWidth, background: modelColors[i] }"></div>
|
||||
</div>
|
||||
<div class="gpt-key">{{ m.key }}</div>
|
||||
</div>
|
||||
@@ -17,12 +17,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const models = [
|
||||
{ name: 'GPT-1', year: '2018', params: '1.17 亿', barWidth: '2%', color: '#94a3b8', key: '预训练+微调范式确立' },
|
||||
{ name: 'GPT-2', year: '2019', params: '15 亿', barWidth: '6%', color: '#3b82f6', key: 'Zero-shot 零样本泛化' },
|
||||
{ name: 'GPT-3', year: '2020', params: '1750 亿', barWidth: '45%', color: '#7c3aed', key: '⚡ 涌现!上下文学习' },
|
||||
{ name: 'GPT-4', year: '2023', params: '~1.8 万亿', barWidth: '100%', color: '#dc2626', key: '多模态 + 复杂推理' },
|
||||
]
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { messages } = useI18n(aiHistoryLocale)
|
||||
const models = computed(() => messages.value.gptEvolution ?? [])
|
||||
|
||||
const modelColors = ['#94a3b8', '#3b82f6', '#7c3aed', '#dc2626']
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
+23
-17
@@ -7,12 +7,12 @@
|
||||
<g v-for="layer in layers" :key="layer.idx">
|
||||
<circle v-for="n in layer.nodes" :key="n.id" :cx="n.x" :cy="n.y" r="15" :fill="layer.fill" :stroke="layer.stroke" stroke-width="2" />
|
||||
</g>
|
||||
<text v-for="layer in layers" :key="'l-'+layer.idx" :x="layer.x" y="194" text-anchor="middle" :fill="layer.stroke" class="lbl">{{ layer.name }}</text>
|
||||
<text v-for="(layer, i) in layers" :key="'l-'+layer.idx" :x="layer.x" y="194" text-anchor="middle" :fill="layer.stroke" class="lbl">{{ localLayers[i]?.name }}</text>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="layer-cards">
|
||||
<div v-for="info in layerInfo" :key="info.name" class="layer-card" :style="{ borderLeftColor: info.color }">
|
||||
<div class="lc-title" :style="{ color: info.color }">{{ info.name }}</div>
|
||||
<div v-for="(info, i) in localLayers" :key="i" class="layer-card" :style="{ borderLeftColor: layerColors[i]?.color }">
|
||||
<div class="lc-title" :style="{ color: layerColors[i]?.color }">{{ info.name }}</div>
|
||||
<div class="lc-desc">{{ info.desc }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,27 +21,33 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { messages } = useI18n(aiHistoryLocale)
|
||||
const localLayers = computed(() => messages.value.neuralNet?.layers ?? [])
|
||||
|
||||
const W = 380, H = 185
|
||||
const layerDef = [
|
||||
{ name: '输入层', count: 3, xFrac: 0.13, color: '#3b82f6', fill: '#dbeafe' },
|
||||
{ name: '隐藏层', count: 4, xFrac: 0.5, color: '#7c3aed', fill: '#ede9fe' },
|
||||
{ name: '输出层', count: 2, xFrac: 0.87, color: '#059669', fill: '#d1fae5' },
|
||||
const layerColors = [
|
||||
{ color: '#3b82f6', fill: '#dbeafe' },
|
||||
{ color: '#7c3aed', fill: '#ede9fe' },
|
||||
{ color: '#059669', fill: '#d1fae5' },
|
||||
]
|
||||
const layers = layerDef.map((l, idx) => {
|
||||
const x = l.xFrac * W
|
||||
const gap = Math.min(46, (H - 36) / (l.count - 1 || 1))
|
||||
const startY = (H - gap * (l.count - 1)) / 2
|
||||
return { idx, x, name: l.name, fill: l.fill, stroke: l.color, nodes: Array.from({ length: l.count }, (_, i) => ({ id: `${idx}-${i}`, x, y: startY + i * gap })) }
|
||||
const layerCounts = [3, 4, 2]
|
||||
const xFracs = [0.13, 0.5, 0.87]
|
||||
|
||||
const layers = layerColors.map((l, idx) => {
|
||||
const x = xFracs[idx] * W
|
||||
const count = layerCounts[idx]
|
||||
const gap = Math.min(46, (H - 36) / (count - 1 || 1))
|
||||
const startY = (H - gap * (count - 1)) / 2
|
||||
return { idx, x, fill: l.fill, stroke: l.color, nodes: Array.from({ length: count }, (_, i) => ({ id: `${idx}-${i}`, x, y: startY + i * gap })) }
|
||||
})
|
||||
const connections = []
|
||||
for (let li = 0; li < layers.length - 1; li++) {
|
||||
layers[li].nodes.forEach(a => { layers[li + 1].nodes.forEach(b => { connections.push({ id: `${a.id}-${b.id}`, x1: a.x, y1: a.y, x2: b.x, y2: b.y }) }) })
|
||||
}
|
||||
const layerInfo = [
|
||||
{ name: '输入层', desc: '原始像素 / 数值信号', color: '#3b82f6' },
|
||||
{ name: '隐藏层(可叠加多层)', desc: '底层识别边缘 → 中层识别形状 → 高层识别语义概念', color: '#7c3aed' },
|
||||
{ name: '输出层', desc: '最终分类或预测结果', color: '#059669' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<div class="demo-card">
|
||||
<div class="perceptron-layout">
|
||||
<div class="inputs-col">
|
||||
<div v-for="inp in inputs" :key="inp.label" class="input-node">
|
||||
<div v-for="(inp, i) in inputs" :key="i" class="input-node">
|
||||
<span class="node-circle">{{ inp.val }}</span>
|
||||
<span class="node-label">{{ inp.label }}</span>
|
||||
<span class="node-label">{{ featureLabels[i] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weights-col">
|
||||
<div v-for="inp in inputs" :key="inp.label" class="weight-arrow">
|
||||
<div v-for="(inp, i) in inputs" :key="i" class="weight-arrow">
|
||||
<span class="arrow">→</span>
|
||||
<span class="w-tag">×{{ inp.weight }}</span>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="n-sym">Σ</div>
|
||||
<div class="n-val">{{ sum }}</div>
|
||||
</div>
|
||||
<span class="bias-tag">偏置 {{ bias }}</span>
|
||||
<span class="bias-tag">{{ t('perceptron.biasLabel') }} {{ bias }}</span>
|
||||
</div>
|
||||
<div class="act-col">
|
||||
<span class="arrow big">→</span>
|
||||
@@ -28,19 +28,23 @@
|
||||
<div class="output-col">
|
||||
<div class="output-node" :class="{ on: output === 1 }">
|
||||
<span class="out-val">{{ output }}</span>
|
||||
<span class="out-lbl">{{ output ? '激活' : '静默' }}</span>
|
||||
<span class="out-lbl">{{ output ? t('perceptron.activated') : t('perceptron.silent') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="caption">
|
||||
① 输入特征 ② 乘以权重(重要性) ③ 求和 + 偏置 ④ 超过阈值就激活输出 1,否则输出 0
|
||||
</div>
|
||||
<div class="caption">{{ t('perceptron.caption') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
const inputs = [{ label: '特征 x₁', val: 1, weight: 0.6 }, { label: '特征 x₂', val: 0, weight: 0.4 }]
|
||||
import { useI18n } from '../../../composables/useI18n.js'
|
||||
import { aiHistoryLocale } from '../../../locales/ai-history/index.js'
|
||||
|
||||
const { t, messages } = useI18n(aiHistoryLocale)
|
||||
const featureLabels = computed(() => messages.value.perceptron?.features ?? [])
|
||||
|
||||
const inputs = [{ val: 1, weight: 0.6 }, { val: 0, weight: 0.4 }]
|
||||
const bias = -0.3
|
||||
const sum = computed(() => Number((inputs.reduce((s, i) => s + i.val * i.weight, 0) + bias).toFixed(2)))
|
||||
const output = computed(() => sum.value > 0 ? 1 : 0)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { computed } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const langMap = {
|
||||
'zh-CN': 'zh-cn',
|
||||
'en-US': 'en',
|
||||
'ja-JP': 'ja-jp',
|
||||
'zh-TW': 'zh-tw',
|
||||
'ko-KR': 'ko-kr',
|
||||
'es-ES': 'es-es',
|
||||
'fr-FR': 'fr-fr',
|
||||
'de-DE': 'de-de',
|
||||
'ar-SA': 'ar-sa',
|
||||
'vi-VN': 'vi-vn'
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight i18n composable for VitePress Vue components.
|
||||
*
|
||||
* @param {Record<string, Record<string, any>>} messages
|
||||
* Locale map, e.g. { 'zh-cn': { title: '标题' }, en: { title: 'Title' } }
|
||||
* @returns {{ t: (key: string) => any, locale: import('vue').ComputedRef<string> }}
|
||||
*/
|
||||
export function useI18n(messages) {
|
||||
const { lang } = useData()
|
||||
|
||||
const locale = computed(() => langMap[lang.value] || 'zh-cn')
|
||||
|
||||
const current = computed(
|
||||
() => messages[locale.value] || messages['zh-cn'] || {}
|
||||
)
|
||||
|
||||
const t = (key) => {
|
||||
const keys = key.split('.')
|
||||
let val = current.value
|
||||
for (const k of keys) {
|
||||
val = val?.[k]
|
||||
if (val === undefined) return key
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
return { t, locale, messages: current }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// AI History – English locale
|
||||
export default {
|
||||
// AiEvolutionDemo
|
||||
aiEvolution: {
|
||||
eras: [
|
||||
{ label: 'Foundations', years: '1940s-50s' },
|
||||
{ label: '1st Wave', years: '1960s-70s' },
|
||||
{ label: '❄️ Winter I', years: '1974-80' },
|
||||
{ label: '2nd Wave', years: '1980s' },
|
||||
{ label: '❄️ Winter II', years: '1987-93' },
|
||||
{ label: 'ML Rise', years: '1990s-2000s' },
|
||||
{ label: 'Deep Learning', years: '2010s' },
|
||||
{ label: 'LLM Era', years: '2018+' }
|
||||
],
|
||||
legend: {
|
||||
wave: 'Tech Wave',
|
||||
winter: '❄️ AI Winter',
|
||||
llm: 'LLM Era'
|
||||
}
|
||||
},
|
||||
|
||||
// DiscriminativeVsGenerativeDemo
|
||||
schools: {
|
||||
repLabel: 'Examples',
|
||||
items: [
|
||||
{
|
||||
name: 'Symbolism',
|
||||
idea: 'Intelligence = symbolic reasoning / If-Then rules',
|
||||
rep: 'Expert Systems, Deep Blue',
|
||||
status: '→ Merging with connectionism (neuro-symbolic AI)'
|
||||
},
|
||||
{
|
||||
name: 'Connectionism',
|
||||
idea: 'Intelligence = neural networks + massive data',
|
||||
rep: 'AlphaGo, GPT series',
|
||||
status: '→ Dominates the LLM era, current mainstream'
|
||||
},
|
||||
{
|
||||
name: 'Behaviorism',
|
||||
idea: 'Intelligence = interaction with environment / RL',
|
||||
rep: 'AlphaGo (RL component)',
|
||||
status: '→ Merging with connectionism (deep RL)'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// FoundationDemo
|
||||
foundation: {
|
||||
label: 'Core idea of Symbolism — encoding knowledge as rules',
|
||||
lines: [
|
||||
{ parts: [{ kw: 'IF' }, { text: ' temperature > 38.5°C ' }, { kw: 'AND' }, { text: ' WBC count > 11000' }] },
|
||||
{ indent: true, parts: [{ kw: 'THEN' }, { text: ' diagnosis = ' }, { str: '"bacterial infection"' }] },
|
||||
{ parts: [{ kw: 'IF' }, { text: ' diagnosis = ' }, { str: '"bacterial infection"' }, { text: ' ' }, { kw: 'AND' }, { text: ' no penicillin allergy' }] },
|
||||
{ indent: true, parts: [{ kw: 'THEN' }, { text: ' treatment = ' }, { str: '"penicillin 400mg / twice daily"' }] }
|
||||
],
|
||||
comment: '// The early medical expert system MYCIN (1977) consisted of 450+ rules like these',
|
||||
caption: 'Human experts translate experience into IF-THEN rules; the machine matches and executes them one by one'
|
||||
},
|
||||
|
||||
// PerceptronDemo
|
||||
perceptron: {
|
||||
features: ['Feature x₁', 'Feature x₂'],
|
||||
biasLabel: 'Bias',
|
||||
activated: 'Fire',
|
||||
silent: 'Silent',
|
||||
caption: '① Input features\u2003② Multiply by weights (importance)\u2003③ Sum + bias\u2003④ Fires output 1 if above threshold, otherwise 0'
|
||||
},
|
||||
|
||||
// BackpropagationDemo
|
||||
backprop: {
|
||||
steps: [
|
||||
{ icon: '➡️', name: 'Forward Pass', desc: 'Data flows through the network to produce a prediction' },
|
||||
{ icon: '📐', name: 'Compute Loss', desc: 'Prediction vs. ground truth → calculate loss' },
|
||||
{ icon: '⬅️', name: 'Backpropagation', desc: 'Trace back each weight\'s "responsibility" layer by layer' },
|
||||
{ icon: '⚙️', name: 'Update Weights', desc: 'Adjust proportionally to reduce future error' }
|
||||
],
|
||||
lossLabel: 'Loss decreases over training epochs:',
|
||||
axisHigh: 'High',
|
||||
axisLow: 'Low',
|
||||
axisEpochs: 'Training Epochs'
|
||||
},
|
||||
|
||||
// NeuralNetworkVisualizationDemo
|
||||
neuralNet: {
|
||||
layers: [
|
||||
{ name: 'Input Layer', desc: 'Raw pixels / numerical signals' },
|
||||
{ name: 'Hidden Layers (stackable)', desc: 'Low → edges; Mid → shapes; High → semantic concepts' },
|
||||
{ name: 'Output Layer', desc: 'Final classification or prediction' }
|
||||
]
|
||||
},
|
||||
|
||||
// AttentionMechanismDemo
|
||||
attention: {
|
||||
colLabel: 'Attention distribution when processing "{word}":',
|
||||
sentence: ['John', 'gave', 'the', 'apple', 'to', 'his', 'mother'],
|
||||
focusIdx: 5,
|
||||
weights: [0.62, 0.08, 0.03, 0.10, 0.05, 0.07, 0.05],
|
||||
caption: '"his" sits mid-sentence, yet the model directs 62% attention to "John" at the start — resolving the pronoun across distance'
|
||||
},
|
||||
|
||||
// GPTEvolutionDemo
|
||||
gptEvolution: [
|
||||
{ name: 'GPT-1', year: '2018', params: '117 M', barWidth: '2%', key: 'Pre-train + fine-tune paradigm' },
|
||||
{ name: 'GPT-2', year: '2019', params: '1.5 B', barWidth: '6%', key: 'Zero-shot generalization' },
|
||||
{ name: 'GPT-3', year: '2020', params: '175 B', barWidth: '45%', key: '⚡ Emergence! In-context learning' },
|
||||
{ name: 'GPT-4', year: '2023', params: '~1.8 T', barWidth: '100%', key: 'Multimodal + complex reasoning' }
|
||||
],
|
||||
|
||||
// AIErasComparisonDemo
|
||||
erasComparison: {
|
||||
header: '🌟 AI Development Stages & Core Paradigms at a Glance',
|
||||
driverLabel: 'Driver',
|
||||
mechanismLabel: 'Core Mechanism',
|
||||
examplesLabel: 'Key Examples',
|
||||
eras: [
|
||||
{ name: 'Rule-Based Era', time: '1960s - 1980s', driver: 'Human-coded knowledge', mechanism: 'If-Then logical deduction', examples: ['Dendral', 'Deep Blue'] },
|
||||
{ name: 'Classical ML', time: '1990s - 2000s', driver: 'Manual feature engineering + statistics', mechanism: 'Finding mathematical decision boundaries', examples: ['SVM', 'Random Forest'] },
|
||||
{ name: 'Deep Learning Revolution', time: '2010s', driver: 'Big data + GPU compute', mechanism: 'Neural nets auto-extract features', examples: ['AlexNet (CNN)', 'AlphaGo (RL)'] },
|
||||
{ name: 'Large Language Models', time: '2018 - present', driver: 'Massive unlabeled data + brute-force compute', mechanism: 'Next-token prediction + emergent knowledge', examples: ['GPT-4', 'Claude 3'] },
|
||||
{ name: 'Agentic AI', time: 'Now - future', driver: 'LLM brain + environment perception', mechanism: 'Autonomous planning + tool use', examples: ['AI Programmer', 'Embodied AI'] }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import zhCn from './zh-cn.js'
|
||||
import en from './en.js'
|
||||
|
||||
export const aiHistoryLocale = {
|
||||
'zh-cn': zhCn,
|
||||
en
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// AI 简史 – 中文语言包
|
||||
export default {
|
||||
// AiEvolutionDemo
|
||||
aiEvolution: {
|
||||
eras: [
|
||||
{ label: '理论奠基', years: '1940s-50s' },
|
||||
{ label: '第一次浪潮', years: '1960s-70s' },
|
||||
{ label: '❄️ 寒冬 I', years: '1974-80' },
|
||||
{ label: '第二次浪潮', years: '1980s' },
|
||||
{ label: '❄️ 寒冬 II', years: '1987-93' },
|
||||
{ label: 'ML 崛起', years: '1990s-2000s' },
|
||||
{ label: '深度学习', years: '2010s' },
|
||||
{ label: '大模型时代', years: '2018+' }
|
||||
],
|
||||
legend: {
|
||||
wave: '技术浪潮',
|
||||
winter: '❄️ AI 寒冬',
|
||||
llm: '大模型时代'
|
||||
}
|
||||
},
|
||||
|
||||
// DiscriminativeVsGenerativeDemo
|
||||
schools: {
|
||||
repLabel: '代表',
|
||||
items: [
|
||||
{
|
||||
name: '符号主义',
|
||||
idea: '智能 = 符号推理 / If-Then 规则',
|
||||
rep: '专家系统、深蓝',
|
||||
status: '→ 与连接主义融合(神经符号 AI)'
|
||||
},
|
||||
{
|
||||
name: '连接主义',
|
||||
idea: '智能 = 神经元网络 + 海量数据',
|
||||
rep: 'AlphaGo、GPT 系列',
|
||||
status: '→ 主导大模型时代,当前主流'
|
||||
},
|
||||
{
|
||||
name: '行为主义',
|
||||
idea: '智能 = 与环境互动 / 强化学习',
|
||||
rep: 'AlphaGo(RL 部分)',
|
||||
status: '→ 与连接主义融合(深度强化学习)'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// FoundationDemo
|
||||
foundation: {
|
||||
label: '符号主义的核心思路 ── 把知识写成规则',
|
||||
lines: [
|
||||
{ parts: [{ kw: 'IF' }, { text: ' 体温 > 38.5°C ' }, { kw: 'AND' }, { text: ' 白细胞计数 > 11000' }] },
|
||||
{ indent: true, parts: [{ kw: 'THEN' }, { text: ' 诊断 = ' }, { str: '"细菌感染"' }] },
|
||||
{ parts: [{ kw: 'IF' }, { text: ' 诊断 = ' }, { str: '"细菌感染"' }, { text: ' ' }, { kw: 'AND' }, { text: ' 对青霉素不过敏' }] },
|
||||
{ indent: true, parts: [{ kw: 'THEN' }, { text: ' 治疗方案 = ' }, { str: '"青霉素 400mg / 每日两次"' }] }
|
||||
],
|
||||
comment: '// 早期医疗专家系统(MYCIN,1977)就是由 450+ 条这样的规则组成的',
|
||||
caption: '人类专家把经验翻译成一条条 IF-THEN 规则,机器逐条匹配执行'
|
||||
},
|
||||
|
||||
// PerceptronDemo
|
||||
perceptron: {
|
||||
features: ['特征 x₁', '特征 x₂'],
|
||||
biasLabel: '偏置',
|
||||
activated: '激活',
|
||||
silent: '静默',
|
||||
caption: '① 输入特征\u2003② 乘以权重(重要性)\u2003③ 求和 + 偏置\u2003④ 超过阈值就激活输出 1,否则输出 0'
|
||||
},
|
||||
|
||||
// BackpropagationDemo
|
||||
backprop: {
|
||||
steps: [
|
||||
{ icon: '➡️', name: '前向传播', desc: '数据流过网络,得出预测' },
|
||||
{ icon: '📐', name: '计算误差', desc: '预测值 vs 正确答案,算 Loss' },
|
||||
{ icon: '⬅️', name: '反向传播', desc: '逐层追溯每个权重的"责任"' },
|
||||
{ icon: '⚙️', name: '更新权重', desc: '按责任微调,减少下次误差' }
|
||||
],
|
||||
lossLabel: 'Loss(误差)随训练轮次下降:',
|
||||
axisHigh: '高',
|
||||
axisLow: '低',
|
||||
axisEpochs: '训练轮次 (Epochs)'
|
||||
},
|
||||
|
||||
// NeuralNetworkVisualizationDemo
|
||||
neuralNet: {
|
||||
layers: [
|
||||
{ name: '输入层', desc: '原始像素 / 数值信号' },
|
||||
{ name: '隐藏层(可叠加多层)', desc: '底层识别边缘 → 中层识别形状 → 高层识别语义概念' },
|
||||
{ name: '输出层', desc: '最终分类或预测结果' }
|
||||
]
|
||||
},
|
||||
|
||||
// AttentionMechanismDemo
|
||||
attention: {
|
||||
colLabel: '处理「{word}」时的注意力分配:',
|
||||
sentence: ['小明', '把', '苹果', '给了', '他', '的', '母亲'],
|
||||
focusIdx: 4,
|
||||
weights: [0.65, 0.05, 0.10, 0.10, 0.05, 0.03, 0.02],
|
||||
caption: '「他」虽在句中间,模型却把 65% 注意力精准投向句首的「小明」,跨越距离识别代词指代'
|
||||
},
|
||||
|
||||
// GPTEvolutionDemo
|
||||
gptEvolution: [
|
||||
{ name: 'GPT-1', year: '2018', params: '1.17 亿', barWidth: '2%', key: '预训练+微调范式确立' },
|
||||
{ name: 'GPT-2', year: '2019', params: '15 亿', barWidth: '6%', key: 'Zero-shot 零样本泛化' },
|
||||
{ name: 'GPT-3', year: '2020', params: '1750 亿', barWidth: '45%', key: '⚡ 涌现!上下文学习' },
|
||||
{ name: 'GPT-4', year: '2023', params: '~1.8 万亿', barWidth: '100%', key: '多模态 + 复杂推理' }
|
||||
],
|
||||
|
||||
// AIErasComparisonDemo
|
||||
erasComparison: {
|
||||
header: '🌟 AI 发展阶段与核心范式全景对比',
|
||||
driverLabel: '驱动方式',
|
||||
mechanismLabel: '核心机制',
|
||||
examplesLabel: '典型代表',
|
||||
eras: [
|
||||
{ name: '规则系统时代', time: '1960s - 1980s', driver: '人类硬编码知识', mechanism: 'If-Then 逻辑推演', examples: ['Dendral', '深蓝 (Deep Blue)'] },
|
||||
{ name: '传统机器学习', time: '1990s - 2000s', driver: '人工特征工程 + 统计学', mechanism: '寻找数学决策边界', examples: ['支持向量机 (SVM)', '随机森林'] },
|
||||
{ name: '深度学习革命', time: '2010s', driver: '大数据 + 算力爬升', mechanism: '神经网络自动提取特征', examples: ['AlexNet (CNN)', 'AlphaGo (RL)'] },
|
||||
{ name: '大语言模型 (LLM)', time: '2018 - 至今', driver: '海量无标注数据 + 暴力计算', mechanism: '预测下一个词 + 涌现常识', examples: ['GPT-4', 'Claude 3'] },
|
||||
{ name: '智能体 (Agentic AI)', time: '现在 - 未来', driver: '大模型大脑 + 环境感知', mechanism: '自主规划 + 工具调用', examples: ['AI 程序员', '具身智能'] }
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user