如果你是一个安卓开发,最近大概率被这样的需求找过:给 App 加一个智能客服入口,把用户评论自动分类,或者让拍照识别植物。问题是,你打开技术方案一看,满屏都是模型、特征、损失函数、Transformer、端侧推理……这些词单独看都认识,连在一起完全不知道在说什么。

这篇文章要做的事很简单:用安卓开发能听懂的方式,把 AI 和机器学习里的高频术语全部讲清。它不是让你转行做算法,而是让你做到三件事:第一,看懂同事或外包给的方案文档;第二,知道哪些 AI 能力适合集成到 App,哪些不适合;第三,真正动手把一个最小模型跑在手机或服务器上。

先给一个判断:机器学习不是什么玄学,它本质上是一个“用数据找规律的程序”。传统程序是你写规则,机器执行;机器学习是机器从数据里总结规则,你只负责提供数据和反馈。这个区别,是理解所有 AI 术语的第一把钥匙。

1. 为什么安卓开发者也必须懂 AI 术语

过去,AI 是算法工程师的专属领域,移动端开发只需要调用后端接口。但最近两年的变化非常明显:端侧智能、端云协同、大模型应用、智能体 Agent,已经越来越多地出现在安卓项目方案里。

这种变化背后有三个实际推力。

第一个是硬件红利。现在的手机普遍配备 NPU 或独立 AI 加速单元,端侧跑一个轻量模型已经不是实验性质,而是常见的性能优化手段。人脸解锁、实时美颜、语音唤醒、相册分类,这些功能在系统层已经跑了好几年。作为应用层开发者,你迟早要面对“这个模型能不能放到客户端跑”的问题。

第二个是隐私合规压力。很多数据不适合上传云端处理,比如医疗影像、财务票据、用户的本地聊天内容。此时更合理的方案是让模型直接跑在设备端,数据不出手机。如果你不懂端侧部署的基本原理,就没法判断方案到底可不可行。

第三个是成本控制。云端推理按照调用量计费,日活百万的应用,每天光模型调用费就是一笔不小的开支。把部分简单推理放到端侧,既能降低延迟,又能减少服务端成本。但这个优化有没有上限、什么场景适合,需要你理解模型大小、推理耗时、资源占用这些概念。

所以,这篇文章并不是为了让你“追赶热点”,而是给安卓开发者补上 AI 协作能力中最低成本的一块拼图:术语系统。术语一旦通了,文档能看懂,会议能对话,代码能落地。

2. AI、机器学习、深度学习、生成式 AI、智能体:别再混为一谈

很多初学者把 AI、机器学习、深度学习当成同义词,这是第一个需要纠正的概念。

AI 是最大的概念,指的是让机器表现出智能行为的所有技术。机器学习是 AI 的一个子集,强调“从数据中学习规律而不是人工编写规则”。深度学习又是机器学习的一个子集,使用多层神经网络自动提取特征。生成式 AI 是深度学习发展到一定阶段后的产物,重点是从训练数据中学习分布,然后生成新的文本、图像或音频。

而智能体 Agent 是另一个维度。它不是一个独立的算法类别,而是一套系统组合:把大模型作为“大脑”,配合工具调用、记忆、规划和行动,完成某个目标。安卓开发最常见到的 Agent 形态,是那些会调日历、发短信、查天气的“语音助手”或“自动化助理”。

术语 核心含义 安卓开发者常见接触场景
AI 让机器表现出智能的统称 泛指各类智能功能
机器学习 从数据中学习规律 分类、回归、推荐
深度学习 多层神经网络学习 图像识别、语音识别
生成式 AI 生成新内容 AI 对话、文案生成、图像生成
智能体 Agent 模型 + 工具 + 记忆 + 规划 自动化操作、智能助理

这个区分为什么重要?因为在技术方案评审时,如果你听到“这个功能用深度学习来做”,你至少能意识到:第一,它需要数据;第二,它需要训练;第三,它可能还需要 GPU 资源。如果你只是笼统地听到“用 AI”,你根本无法评估成本和风险。

对安卓开发来说,还有一个务实的判断标准:凡是把任务定义成“从已知样本中找规律”的,基本都是机器学习问题;凡是涉及连续决策和工具调用的,才是 Agent 问题。大多数 App 里的“智能”需求,本质上还是机器学习问题。

3. 数据类术语:特征、标签、训练集、测试集

机器学习的第一步永远是数据。数据相关术语是安卓开发者读算法文档时最先遇到的一批词,也是最容易被忽略的一批。

3.1 特征与标签

特征是你用来做判断的输入信息。标签是你希望模型预测的结果。

举个安卓场景:你做一个“用户评论情绪分类”功能,输入是一条评论文本,输出是“正面”或“负面”。这里评论的文本内容、评论长度、感叹号数量、是否包含某些情绪词,都是特征;而“正面 / 负面”就是标签。

如果一条评论是“这个版本启动速度很快,界面也很清爽”,那这条数据可以表示成:

{
  "text": "这个版本启动速度很快,界面也很清爽",
  "length": 18,
  "exclamation_count": 0,
  "sentiment": "positive"
}

这里的 length exclamation_count 是结构化特征, text 是原始文本, sentiment 是标签。模型训练时做的事,就是找到这些特征和标签之间的映射关系。

还有一种区分方式:有标签的是监督学习,没有标签的是无监督学习。你想让模型自动判断情绪,属于监督学习;你想让模型把相似的用户评论自动聚类,但没有预定义类别,属于无监督学习。绝大多数 App 内 AI 功能是监督学习。

3.2 训练集、验证集、测试集

数据不是随随便便扔给模型就行。实践中会把数据集切成三份。

训练集用于让模型拟合规律,占据数据的大部分。验证集用于训练过程中调整超参数,防止模型只记住训练数据。测试集用于最终评估,模拟模型在真实新数据上的表现。这三份数据之间必须没有交叉,否则评估结果会虚高。

很多新手犯的错误是:用训练集的数据去做最终评估,得出一个 99% 的准确率,上线后被真实数据打回原形。这就是数据泄漏的典型表现。

3.3 数据清洗与特征工程

原始数据往往不能直接训练。文本里有噪声字符,数值字段有缺失,图片尺寸不统一,这些都需要清洗。

特征工程是把原始数据转换成更有表达能力的特征。同一个问题,特征工程做得好的团队,哪怕模型复杂度不高,效果也可能碾压花哨的大模型。对安卓开发来说,你不需要亲自做大量特征工程,但要知道它存在,并且知道它是项目耗时的重灾区。

数据增强是在原有数据基础上生成更多变化样本,常见于图像任务:旋转、裁剪、调亮度。端侧图像识别项目如果遇到效果不稳,通常会从这个方向补强。

这里想提醒一点:很多团队一上来就追求“模型越复杂越好”,实际项目里数据质量才是最大的瓶颈。数据数量少、标签错误、类别不均衡,这些问题靠调模型很难解决。

4. 模型与算法术语:神经网络、CNN、RNN、Transformer

这一节是全文术语最密集的部分。我尽量用安卓开发的日常经验来类比。

4.1 模型和算法的区别

算法是一套学习规则,模型是学习完成之后保存下来的参数集合。

你可以把算法理解成一套“训练流程”,把模型理解成流程跑完后的产物。安卓集成时拿到的是模型文件,比如 .tflite .onnx .pt ,这些文件本质上存储的就是一堆权重参数和网络结构配置。

所以当你听到“我们用了 Transformer”,他可能是在说训练时用的网络结构;当你听到“这个模型有 70 亿参数”,他是在说模型文件里权重规模。两者不在同一个层次。

4.2 神经网络的基础组成

神经网络由神经元、层、权重、偏置组成。一个神经元接收输入,乘以权重,再加上偏置,最后经过激活函数输出结果。很多神经元堆叠成层,很多层串联成网络。

安卓开发里能类比的场景是 View 树:单个 TextView 是神经元,一个 LinearLayout 是一层,整棵 View 树是网络。输入从最底层传入,经过一层层计算,最终在顶层输出预测结果。

权重是网络最核心的东西。训练的时候,网络不断调整权重,让预测结果逼近真实标签。训练完成后权重固定下来,推理时只做前向计算,不再更新权重。

4.3 CNN、RNN、Transformer 各自擅长什么

CNN,卷积神经网络,擅长图像任务。它的核心操作是卷积和池化。卷积可以理解为用一个小窗口在图片上滑动,提取局部特征;池化是下采样,压缩信息、降低计算量。为什么不用全连接网络直接处理图片?因为图片像素太多,全连接参数量爆炸,而且无法保留空间结构。CNN 用局部连接和权值共享解决了这个问题。

RNN,循环神经网络,擅长序列数据。它把上一个时刻的输出作为下一个时刻的输入,从而形成“记忆”。LSTM 是 RNN 的改进版,解决了长序列中的梯度消失问题。语音、文本、时间序列,这些场景以前主要靠 RNN 系列。

Transformer 是 2017 年后最重要的模型结构,核心是注意力机制。注意力机制让模型在处理一个位置时可以同时关注序列中的所有其他位置,从而捕捉长距离依赖。相比 RNN 的逐步串行,Transformer 可以并行计算,训练效率更高。

为什么现在大模型都基于 Transformer?因为语言本质上是一种长距离依赖非常明显的序列。一句话的意思可能由很远的上下文决定。RNN 处理这种长距离依赖很吃力,Transformer 则天然擅长。

对安卓开发来说,这些结构不需要你都手动实现,但你至少要知道:图像任务默认可以选 CNN 或 MobileNet 这类轻量网络;文本分类任务可以从 Transformer 家族的轻量模型入手;简单场景甚至用传统机器学习就够了。

5. 训练术语:损失函数、优化器、过拟合、评估指标

模型不是一次训练就完成。训练过程有一些高频术语,方案文档里几乎必定出现。

5.1 损失函数

损失函数衡量模型预测结果和真实标签之间的差距。损失越小,说明预测越准。分类任务常用交叉熵损失,回归任务常用均方误差 MSE。

可以把它类比成安卓开发里的单元测试失败数:每次迭代,模型都在想办法降低这个失败数。不同任务要选不同的“评分标准”。选错损失函数,模型会学偏。

5.2 优化器与梯度下降

优化器是“如何调整权重”的策略,梯度下降是最基本的优化思想。每次计算损失后,根据梯度方向更新权重,让损失逐步下降。

SGD 和 Adam 是两种常见优化器。SGD 简单稳定,Adam 收敛快、对超参数不敏感。实际项目中 Adam 用得更多。但 Adam 不保证一定比 SGD 泛化好,具体要看任务。

这里有个概念容易混淆:epoch 和 batch size。一个 epoch 表示模型遍历完整个训练集一次。如果数据量太大,不能一次性全部塞进内存,就把数据切成多个 batch 轮流训练。batch size 是每个批次的数据量。学习率是每次权重更新的步长,设置过大会震荡,设置过小则训练太慢。

5.3 过拟合与欠拟合

过拟合是训练中最常见的问题:模型在训练集上表现很好,在测试集上表现很差。相当于一个学生把练习题答案背下来了,遇到新题目就蒙。

欠拟合相反:模型连训练集都拟合不好,说明容量不够或训练不足。

解决过拟合的常用手段包括正则化、Dropout、数据增强和早停。正则化给权重增加惩罚项,让权重不要过大;Dropout 在训练时随机丢弃一部分神经元,防止网络过于依赖某一特征;早停是在验证集效果开始变差时停止训练。

5.4 评估指标

一个模型好不好,不能只看准确率。分类任务常用的指标有准确率、精确率、召回率和 F1。

准确率是预测正确的比例。精确率是“预测为正例的样本中真正为正例的比例”,召回率是“真实正例中被预测出来的比例”。两者常常此消彼长,F1 是两者的调和平均。

在样本类别不均衡的场景下,准确率会骗人。比如 99% 的样本是负例,模型全部预测为负例也能获得 99% 准确率,但没有任何使用价值。这时候需要看精确率和召回率。

指标 关注点 安卓场景类比
准确率 整体正确比例 全部判断里有几个是对的
精确率 预测正例的可靠性 拦截的垃圾评论里有多少真垃圾
召回率 正例被找到的比率 真实垃圾评论被拦住多少
F1 精确率和召回率的均衡 综合评分

6. 安卓端落地术语:ML Kit、TFLite、ONNX、量化

术语讲到这里,开始进入安卓开发者真正动手的部分。AI 能力集成到 Android App,大致有三种路线。

6.1 三种集成路线

第一种是纯云端 API。App 把图片或文本上传到服务端,服务端调用训练好的模型,返回结果。这种路线适合大模型、复杂推理,但依赖网络,且要考虑成本和隐私。

第二种是端侧 SDK,最有代表性的是 ML Kit。ML Kit 提供文本识别、人脸检测、物体识别、翻译、条码扫描等即用能力,不需要你懂模型训练,包一个 SDK 就能调用。适合需求固定、不想折腾算法的团队。

第三种是自定义模型部署。你把训练好的模型转成 TFLite 或 ONNX 格式,放进 App 的 assets 目录,用推理引擎本地运行。这种路线适合有定制模型、对离线能力和隐私要求高的场景。

对大多数安卓项目,我的建议是:优先考虑 ML Kit,它封装得很好;当 ML Kit 满足不了需求,才考虑自定义模型部署。

6.2 模型格式与推理引擎

TensorFlow Lite 是谷歌推出的端侧推理方案,支持 Android 和 iOS。模型通常以 .tflite 格式保存,使用 Interpreter API 加载执行。

ONNX 是一个跨框架模型格式标准。用 PyTorch 训练的模型可以导出成 ONNX,再用 ONNX Runtime 在安卓端运行。它解决了框架锁定问题,团队里既有 TensorFlow 又有 PyTorch 时比较有价值。

模型压缩是端侧部署必须考虑的问题。量化把模型里的浮点参数从 32 位降到 8 位或更低,可以显著减小体积、提升推理速度,但会带来少量精度损失。剪枝把不重要的权重直接置零或移除,让模型更小。很多端侧模型必须经过量化才能在手机上跑得流畅。

6.3 ML Kit 快速上手示例

下面用一个文本识别示例展示 ML Kit 的使用方式。

// 文件路径:app/src/main/java/com/example/mlbasics/TextRecognitionHelper.kt
import android.util.Log
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.TextRecognition
import com.google.mlkit.vision.text.latin.TextRecognizerOptions

fun recognizeText(image: InputImage) {
    val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)

    recognizer.process(image)
        .addOnSuccessListener { visionText ->
            val resultText = visionText.text
            Log.d("MLKitDemo", "识别结果: $resultText")
        }
        .addOnFailureListener { e ->
            Log.e("MLKitDemo", "识别失败", e)
        }
}

接入步骤很简单:在 build.gradle 里添加 ML Kit 依赖,把要识别的图片转成 InputImage ,然后调用 process 方法。失败时优先检查图片方向、清晰度和模型依赖是否正确下载。

6.4 TFLite 推理示例

如果你的模型已经转成 .tflite ,那就要用 Interpreter 来加载和推理。

// 文件路径:app/src/main/java/com/example/mlbasics/Classifier.kt
import android.content.Context
import org.tensorflow.lite.Interpreter
import java.io.FileInputStream
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel

class Classifier(context: Context, modelPath: String) {

    private var interpreter: Interpreter? = null

    fun load(): Boolean {
        return try {
            val assetFileDescriptor = context.assets.openFd(modelPath)
            val inputStream = FileInputStream(assetFileDescriptor.fileDescriptor)
            val fileChannel = inputStream.channel
            val startOffset = assetFileDescriptor.startOffset
            val declaredLength = assetFileDescriptor.declaredLength
            val modelBuffer: MappedByteBuffer = fileChannel.map(
                FileChannel.MapMode.READ_ONLY,
                startOffset,
                declaredLength
            )
            interpreter = Interpreter(modelBuffer)
            true
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }

    fun classify(input: FloatArray, labelSize: Int): Int? {
        val output = Array(1) { FloatArray(labelSize) }
        interpreter?.run(input, output)
        return output[0].indices.maxByOrNull { output[0][it] }
    }

    fun close() {
        interpreter?.close()
        interpreter = null
    }
}

代码本身不复杂,但有几个容易踩的坑。第一,模型文件必须放在 assets 目录,路径要和传入一致。第二,Input 输出数组的 shape 必须严格匹配模型要求,可以用 interpreter.getInputTensor(0).shape() 查看。第三,Interpreter 使用完毕要调用 close() ,否则会有内存泄漏。

7. 一个最小实战流程:从数据到端侧推理

为了让上面的概念串起来,我们走一个端到端的最小流程:判断用户评论的情绪是正面还是负面。

这一步的关键不是模型多强大,而是让你亲眼看一次“数据 -> 训练 -> 导出 -> 集成”的完整闭环。

7.1 准备数据

先准备少量带标签的评论数据。

[
  {"text": "这个版本的启动速度很快", "sentiment": "positive"},
  {"text": "升级后经常闪退", "sentiment": "negative"},
  {"text": "界面设计很清爽", "sentiment": "positive"},
  {"text": "耗电比之前严重", "sentiment": "negative"},
  {"text": "拍照效果提升明显", "sentiment": "positive"},
  {"text": "通知栏卡死了", "sentiment": "negative"}
]

真实项目中数据量至少几千条,这里只用于演示流程。

7.2 训练一个简单模型

为了不在文章里展开完整的深度学习训练代码,我们用 scikit-learn 的逻辑回归来做演示。这个环节只需要电脑有 Python 环境。

# 文件路径:train_demo.py
import numpy as np
from sklearn.linear_model import LogisticRegression

# 特征1:评论长度;特征2:感叹号数量
X = np.array([
    [12, 0],
    [35, 2],
    [18, 1],
    [50, 4],
    [28, 0],
    [45, 3]
])
# 1 表示正面情绪,0 表示负面情绪
y = np.array([0, 1, 0, 1, 0, 1])

model = LogisticRegression()
model.fit(X, y)

print("模型系数:", model.coef_)
print("模型截距:", model.intercept_)

# 预测一条新评论:长度 20,感叹号数量 1
new_sample = np.array([[20, 1]])
prediction = model.predict(new_sample)
print("预测结果:", prediction)

运行前需要安装依赖:

pip install numpy scikit-learn

运行后你就能看到模型系数和预测结果。逻辑回归的预测逻辑本身很简单,就是加权求和加 sigmoid,但它包含了你需要理解的完整流程:喂数据、训练、预测。

7.3 导出并集成到安卓

在真实项目中,训练好的模型会转换成 TFLite 格式放进 assets 。然后使用上一节的 Classifier 类完成加载和推理。

你需要提前确定:模型输入是几个特征,输出是几个类别。以当前示例来说,输入是两个 Float,输出是两个类别的得分,取得分高的作为预测结果。

调用时只需:

// 文件路径:app/src/main/java/com/example/mlbasics/MainActivity.kt
val classifier = Classifier(this, "sentiment_model.tflite")
classifier.load()
val resultIndex = classifier.classify(floatArrayOf(20f, 1f), 2)
println("预测结果索引: $resultIndex")
classifier.close()

到这里,你实际上已经走完了一个完整的 AI 功能集成流程。剩下的工作就是把真实数据集、真实模型结构和评估指标替换进来。

7.4 如何验证效果

端到端流程跑通后,不能只看一次预测结果。建议分三步验证:

第一步,在训练集上预测,确认模型没有代码层面的 bug。第二步,在测试集上做批量评估,计算准确率、精确率、召回率和 F1。第三步,拿真实用户数据做小流量测试,观察线上效果。

如果训练集效果很好、测试集效果很差,基本可以判断为过拟合,需要回到数据处理和正则化方向。

8. 常见问题与排查思路

安卓开发集成机器学习功能时,有一些问题高频出现。这里汇总成表格,方便你排查。

问题现象 可能原因 排查方式 解决方案
加载 TFLite 模型失败 assets 路径错误,或模型文件损坏 检查 assets 目录和模型大小 确认路径拼写,重新导出模型
推理结果与预期完全不符 输入数据没有做和训练时相同的预处理 检查特征归一化逻辑 在训练和推理两端保持完全一致的预处理流程
模型文件太大,APK 体积暴涨 没有做量化压缩 查看模型原始大小 使用量化、剪枝,或改用 ML Kit 等封装能力
低端机运行卡顿 模型输入尺寸过大,CPU 推理耗时高 监控推理耗时和内存占用 降低输入分辨率,启用 GPU/NPU 加速,或换用更小模型
端侧效果比云端差 端侧模型做了量化,精度下降 对比量化前后评估指标 接受精度损失,或采用端云混合策略,只把复杂样本发到云端
ML Kit 依赖下载超时 网络问题或依赖配置错误 检查 Gradle 日志 切换到稳定的镜像源,或增加超时时间

这里想重点强调第一个问题的排查顺序:先确认 assets 路径正确,再确认模型没有在传输过程中损坏,最后确认 TFLite 版本和模型算子兼容。很多看起来复杂的问题,源头只是一个路径拼写错误。

9. 最佳实践与工程建议

术语掌握之后,真正拉开差距的是工程习惯。

9.1 先定义评估指标,再开始训练

很多项目一开始只关心“能不能跑通”,忽略了效果评估。上线前临时发现准确率不够,又不知道该怎么调。正确的做法是在项目启动时就把任务定义清楚:这个是分类还是回归,正例是什么,评估指标用准确率还是 F1,最低可接受值是多少。指标先定,训练才有方向。

9.2 端侧能力要控制体积和功耗

移动端资源有限。模型文件尽量控制在 10MB 以内,输入图片尽量压缩分辨率,推理操作放到后台线程。不要在主线程里跑推理,否则 UI 会掉帧,甚至触发 ANR。如果 App 有大量模型同时加载,要设计合理的加载时机和释放策略。

9.3 重视数据隐私和权限提示

如果模型在端侧处理用户数据,表面上减少了云上传,但仍然需要在隐私政策中说明。如果使用云 API,则要明确用户数据和第三方服务之间的边界。合适合规的问题不是技术问题,但技术方案会影响合规判断。

9.4 用灰度发布和监控保障迭代

模型上线不是终点。线上数据分布会漂移,用户使用习惯会变化,模型效果会衰减。建议在 App 内加入轻量埋点,统计推理请求量、成功率、耗时和用户反馈。新模型先对一小部分用户开放,对比指标后再全量发布。

9.5 与算法团队协同的版本管理

模型也需要版本管理。建议约定模型文件的命名规则,例如 sentiment_model_v3_quantized.tflite ,并在代码里记录模型 hash。后端模型、安卓端模型、iOS 端模型要统一登记,避免多人协作时搞混。

9.6 从已有模板而不是从零开始

如果想快速在安卓端跑通一个 demo,建议先从 ML Kit 和 TensorFlow Lite 官方示例仓库入手。官方 example 覆盖了图像分类、对象检测、文本分类等常见场景,直接改造成本远低于从零写一套。理解代码后再替换成自己的模型。

10. 总结与后续学习方向

这篇文章把所有高频术语按照“数据 -> 模型 -> 训练 -> 部署 -> 评测 -> 工程化”的顺序串了一遍。你会发现它们不是零散的知识点,而是同一条流水线上的不同环节。AI 功能要落地,离不开清晰的业务问题定义、高质量的数据、合适的模型、可靠的部署和持续的评估。

对安卓开发者来说,接下来的学习路径可以分三步走。第一步,把 ML Kit 的官方文档过一遍,亲手跑两个 demo,建立端侧 AI 的体感。第二步,用 TensorFlow Lite 把你的自定义模型部署到手机,理解模型转换、输入输出 shape 和推理性能。第三步,如果在工作中遇到需要训练模型的需求,再系统学习机器学习基础,比如吴恩达的机器学习公开课,或是周志华的《机器学习》重点章节。

建议把本文收藏备用。下次有人再跟你说“这个功能用 AI 实现一下”,你至少能提出几个决定性追问:数据从哪来?标签怎么定义?效果怎么评估?什么时候能见到第一个可运行的模型?能回答清楚这三个问题的团队,项目才值得启动。

更多推荐