第4章:机器学习基础
4.1 机器学习核心概念
理论讲解
机器学习是人工智能的一个分支,它使计算机能够从数据中学习并改进性能,而无需显式编程。以下是机器学习的核心概念:
- 数据:机器学习的基础,包括特征和标签
- 特征:数据的属性或特性,用于描述数据
- 标签:数据的输出或结果,用于监督学习
- 模型:从数据中学习的算法或函数
- 训练:使用数据调整模型参数的过程
- 测试:评估模型性能的过程
- 泛化:模型对新数据的适应能力
- 过拟合:模型在训练数据上表现很好,但在新数据上表现差
- 欠拟合:模型在训练数据和新数据上都表现差
机器学习算法通常分为三类:监督学习、无监督学习和强化学习。
代码示例
// 机器学习核心概念的简单演示
class SimpleModel {
constructor() {
this.weight = 0;
this.bias = 0;
}
// 预测函数:y = wx + b
predict(x) {
return this.weight * x + this.bias;
}
// 训练函数:使用最小二乘法更新参数
train(xs, ys, epochs = 100, learningRate = 0.01) {
for (let epoch = 0; epoch < epochs; epoch++) {
let totalError = 0;
for (let i = 0; i < xs.length; i++) {
const x = xs[i];
const y = ys[i];
const prediction = this.predict(x);
const error = y - prediction;
// 更新权重和偏置
this.weight += learningRate * error * x;
this.bias += learningRate * error;
totalError += Math.abs(error);
}
if (epoch % 10 === 0) {
console.log(`Epoch ${epoch}: Average Error = ${totalError / xs.length}`);
}
}
}
}
// 使用示例
const model = new SimpleModel();
const xs = [1, 2, 3, 4, 5];
const ys = [2, 4, 6, 8, 10]; // y = 2x
console.log('Before training:');
console.log(`f(3) = ${model.predict(3)}`); // 应该接近6
model.train(xs, ys);
console.log('After training:');
console.log(`f(3) = ${model.predict(3)}`); // 应该接近6
console.log(`Weight: ${model.weight}, Bias: ${model.bias}`);实践练习
- 运行上面的代码,观察模型训练过程
- 修改训练数据,使y = 3x + 1,重新训练模型
- 尝试不同的学习率和迭代次数,观察对训练结果的影响
- 预测一个新的x值,如x=6,检查结果是否接近预期
4.2 监督学习与无监督学习
理论讲解
监督学习是最常见的机器学习类型,它使用带有标签的数据进行训练。主要包括:
- 分类:预测离散的类别标签,如垃圾邮件检测、图像分类等
- 回归:预测连续的数值,如房价预测、股票价格预测等
- 序列预测:预测时间序列数据,如天气预测、销售额预测等
无监督学习使用没有标签的数据进行训练,主要包括:
- 聚类:将相似的数据点分组,如客户细分、图像聚类等
- 降维:减少数据的维度,同时保留关键信息,如PCA、t-SNE等
- 关联规则学习:发现数据中的关联关系,如购物篮分析
强化学习是一种特殊的机器学习类型,它通过与环境交互来学习最优策略。
代码示例
// 监督学习与无监督学习的简单演示
// 监督学习:分类示例
function supervisedClassification() {
console.log('=== 监督学习:分类示例 ===');
// 训练数据:带有标签
const trainingData = [
{ features: [1, 2], label: 'A' },
{ features: [2, 3], label: 'A' },
{ features: [3, 1], label: 'B' },
{ features: [4, 2], label: 'B' }
];
console.log('训练数据:', trainingData);
console.log('模型:根据特征预测类别标签');
}
// 无监督学习:聚类示例
function unsupervisedClustering() {
console.log('\n=== 无监督学习:聚类示例 ===');
// 训练数据:没有标签
const trainingData = [
{ features: [1, 2] },
{ features: [2, 3] },
{ features: [3, 1] },
{ features: [4, 2] }
];
console.log('训练数据:', trainingData);
console.log('模型:将相似的数据点分组');
}
// 运行演示
supervisedClassification();
unsupervisedClustering();实践练习
- 描述一个你身边的监督学习应用场景
- 描述一个你身边的无监督学习应用场景
- 思考:为什么有些问题适合监督学习,而有些适合无监督学习?
4.3 模型训练流程
理论讲解
一个完整的机器学习模型训练流程包括以下步骤:
- 问题定义:明确要解决的问题和目标
- 数据收集:获取相关的数据
- 数据预处理:清洗、转换和标准化数据
- 特征工程:选择和提取有用的特征
- 模型选择:选择适合问题的机器学习算法
- 模型训练:使用训练数据调整模型参数
- 模型评估:使用测试数据评估模型性能
- 模型优化:调整超参数,改进模型性能
- 模型部署:将模型应用到实际场景中
- 模型监控:监控模型在生产环境中的性能
代码示例
// 模型训练流程的简单演示
function modelTrainingProcess() {
console.log('=== 模型训练流程 ===');
// 1. 问题定义
console.log('1. 问题定义:预测房屋价格');
// 2. 数据收集
console.log('2. 数据收集:获取房屋面积和价格数据');
const data = [
{ area: 100, price: 500000 },
{ area: 150, price: 750000 },
{ area: 200, price: 1000000 },
{ area: 250, price: 1250000 },
{ area: 300, price: 1500000 }
];
// 3. 数据预处理
console.log('3. 数据预处理:标准化数据');
const maxArea = Math.max(...data.map(d => d.area));
const maxPrice = Math.max(...data.map(d => d.price));
const normalizedData = data.map(d => ({
area: d.area / maxArea,
price: d.price / maxPrice
}));
// 4. 特征工程
console.log('4. 特征工程:选择面积作为特征');
const xs = normalizedData.map(d => d.area);
const ys = normalizedData.map(d => d.price);
// 5. 模型选择
console.log('5. 模型选择:使用线性回归模型');
class LinearRegression {
constructor() {
this.weight = 0;
this.bias = 0;
}
predict(x) {
return this.weight * x + this.bias;
}
train(xs, ys, epochs = 100, lr = 0.01) {
for (let epoch = 0; epoch < epochs; epoch++) {
let error = 0;
for (let i = 0; i < xs.length; i++) {
const prediction = this.predict(xs[i]);
const delta = ys[i] - prediction;
this.weight += lr * delta * xs[i];
this.bias += lr * delta;
error += delta ** 2;
}
if (epoch % 20 === 0) {
console.log(` Epoch ${epoch}: MSE = ${error / xs.length}`);
}
}
}
}
// 6. 模型训练
console.log('6. 模型训练:使用训练数据训练模型');
const model = new LinearRegression();
model.train(xs, ys);
// 7. 模型评估
console.log('7. 模型评估:计算训练数据上的误差');
let totalError = 0;
for (let i = 0; i < xs.length; i++) {
const prediction = model.predict(xs[i]);
totalError += Math.abs(prediction - ys[i]);
}
console.log(` Average Error: ${totalError / xs.length}`);
// 8. 模型优化
console.log('8. 模型优化:调整学习率和迭代次数');
// 9. 模型部署
console.log('9. 模型部署:将模型应用到实际场景');
const newArea = 180 / maxArea; // 180平方米
const predictedPrice = model.predict(newArea) * maxPrice;
console.log(` 预测180平方米房屋价格:${predictedPrice.toFixed(2)}`);
// 10. 模型监控
console.log('10. 模型监控:监控模型在生产环境中的性能');
}
modelTrainingProcess();实践练习
- 运行上面的代码,了解完整的模型训练流程
- 修改数据,添加更多特征,如房间数量、楼层等
- 尝试使用不同的学习率和迭代次数,观察对模型性能的影响
- 计算模型在测试数据上的性能指标
4.4 实战:训练简单分类模型
理论讲解
在这个实战中,我们将使用TensorFlow.js训练一个简单的分类模型,用于识别手写数字。我们将使用MNIST数据集,这是一个经典的手写数字数据集,包含60,000个训练样本和10,000个测试样本。
分类模型的训练流程包括:
- 加载和预处理数据
- 定义模型结构
- 编译模型
- 训练模型
- 评估模型
- 使用模型进行预测
代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实战:训练简单分类模型</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.10.0/dist/tf.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
text-align: center;
}
.output {
background-color: #f5f5f5;
padding: 10px;
margin: 10px 0;
border-radius: 4px;
text-align: left;
white-space: pre-wrap;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
border-radius: 4px;
cursor: pointer;
margin: 10px;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="container">
<h1>实战:训练简单分类模型</h1>
<p>使用TensorFlow.js训练一个手写数字分类模型</p>
<button onclick="runTraining()">开始训练</button>
<div class="output" id="output"></div>
<h3>预测示例</h3>
<input type="number" id="testInput" min="0" max="9" value="5">
<button onclick="runPrediction()">预测</button>
<div id="predictionResult"></div>
</div>
<script>
const outputDiv = document.getElementById('output');
const predictionResultDiv = document.getElementById('predictionResult');
let model;
let testData;
// 输出日志
function log(message) {
outputDiv.innerHTML += message + '\n';
console.log(message);
}
// 加载MNIST数据集
async function loadData() {
log('加载MNIST数据集...');
const mnist = await tf.data.webcam.mnist.load();
return mnist;
}
// 预处理数据
function preprocessData(data) {
log('预处理数据...');
// 将图像数据转换为0-1范围
return data.map(item => ({
xs: item.xs.div(255),
ys: item.ys
}));
}
// 定义模型
function createModel() {
log('定义模型结构...');
const model = tf.sequential();
// 添加输入层和卷积层
model.add(tf.layers.conv2d({
inputShape: [28, 28, 1],
filters: 32,
kernelSize: 3,
activation: 'relu'
}));
// 添加池化层
model.add(tf.layers.maxPooling2d({
poolSize: 2,
strides: 2
}));
// 添加展平层
model.add(tf.layers.flatten());
// 添加全连接层
model.add(tf.layers.dense({
units: 128,
activation: 'relu'
}));
// 添加输出层
model.add(tf.layers.dense({
units: 10,
activation: 'softmax'
}));
return model;
}
// 编译模型
function compileModel(model) {
log('编译模型...');
model.compile({
optimizer: 'adam',
loss: 'categoricalCrossentropy',
metrics: ['accuracy']
});
}
// 训练模型
async function trainModel(model, trainData) {
log('开始训练模型...');
const history = await model.fit(
trainData.xs,
trainData.ys,
{
epochs: 5,
batchSize: 32,
validationSplit: 0.2,
callbacks: {
onEpochEnd: (epoch, logs) => {
log(`Epoch ${epoch + 1}: 损失 = ${logs.loss.toFixed(4)}, 准确率 = ${logs.acc.toFixed(4)}, 验证损失 = ${logs.val_loss.toFixed(4)}, 验证准确率 = ${logs.val_acc.toFixed(4)}`);
}
}
}
);
return history;
}
// 评估模型
async function evaluateModel(model, testData) {
log('评估模型...');
const result = await model.evaluate(testData.xs, testData.ys);
log(`测试损失: ${result[0].toFixed(4)}, 测试准确率: ${result[1].toFixed(4)}`);
return result;
}
// 主训练函数
async function runTraining() {
outputDiv.innerHTML = '';
// 1. 加载数据
const mnistData = await loadData();
const trainData = preprocessData(mnistData.train);
testData = preprocessData(mnistData.test);
// 2. 创建模型
model = createModel();
model.summary();
// 3. 编译模型
compileModel(model);
// 4. 训练模型
await trainModel(model, trainData);
// 5. 评估模型
await evaluateModel(model, testData);
log('训练完成!');
}
// 使用模型进行预测
async function runPrediction() {
if (!model || !testData) {
predictionResultDiv.innerHTML = '<p>请先训练模型!</p>';
return;
}
const index = parseInt(document.getElementById('testInput').value);
if (isNaN(index) || index < 0 || index >= testData.xs.shape[0]) {
predictionResultDiv.innerHTML = '<p>请输入有效的索引!</p>';
return;
}
// 获取测试样本
const testSample = testData.xs.slice([index, 0, 0, 0], [1, 28, 28, 1]);
const actualLabel = testData.ys.slice([index, 0], [1, 10]);
// 进行预测
const prediction = model.predict(testSample);
const predictedLabel = tf.argMax(prediction, 1).dataSync()[0];
const actualLabelValue = tf.argMax(actualLabel, 1).dataSync()[0];
// 显示结果
predictionResultDiv.innerHTML = `
<h4>预测结果</h4>
<p>实际标签:${actualLabelValue}</p>
<p>预测标签:${predictedLabel}</p>
<p>预测正确:${predictedLabel === actualLabelValue ? '是' : '否'}</p>
`;
}
</script>
</body>
</html>实践练习
- 运行上面的代码,训练一个手写数字分类模型
- 观察训练过程中的损失和准确率变化
- 使用不同的测试样本进行预测,观察模型性能
- 尝试修改模型结构,如添加更多卷积层或调整滤波器数量
- 调整训练参数,如批次大小、迭代次数等,观察对模型性能的影响
章节总结
核心知识点回顾
- 机器学习核心概念:数据、特征、标签、模型、训练、测试等
- 监督学习与无监督学习的区别和应用场景
- 完整的模型训练流程:从数据收集到模型部署
- 使用TensorFlow.js训练简单分类模型的实战
学习收获
- 理解了机器学习的基本原理和分类
- 掌握了模型训练的完整流程
- 学会了使用TensorFlow.js构建和训练简单的分类模型
- 能够评估模型性能并进行预测
下一步学习
在下一章中,我们将学习计算机视觉应用,包括图像识别基础、预训练模型使用,以及实战开发图像分类和物体检测应用。
课程分类:前端开发、AI技术开发
学习建议:
- 深入学习线性代数和统计学基础知识
- 了解更多机器学习算法的原理和应用
- 实践不同类型的机器学习任务
- 关注深度学习的最新发展
资源链接: