模型训练
创建感知机对象:我们定义一个感知机类,包含初始化方法、激活函数和预测逻辑。
创建训练函数:定义一个训练方法,使其能够根据正确标签调整权重和偏置。
训练感知机并验证正确性:使用示例数据进行训练和测试。
训练任务
假设平面上有一条直线\( L: w_1x + w_2y + b = 0 \),周围分布着若干\( (x, y) \)点。我们需要训练一个感知机,使其能够正确分类这些点位于直线的上方(1)或下方(0)。
创建感知机对象
创建一个感知机对象(object),可任意命名(例如命名为:Perceptron),让感知机接收两个参数:
- 输入特征的数量(no)
- 学习率参数(learningRate)
其中,学习率参数(learningRate)的默认值设置为0.00001
在对象初始化时,为每个输入节点生成一个随机权重值,权重值的取值范围限定在-1到1之间。
// 感知机对象
function Perceptron(no, learningRate = 0.00001) {
// 设置初始值
this.learnc = learningRate; // 学习率
this.bias = 1; // 偏置值
// 计算随机权重
this.weights = [];
for (let i = 0; i <= no; i++) {
// 生成范围在[-1, 1)的随机权重
this.weights[i] = Math.random() * 2 - 1;
}
}
1. 随机权重初始化
- 感知机(Perceptron)将为每个输入特征分配一个随机初始化的权重值。
2. 学习率参数
- 在训练感知机时,每次出现分类错误,系统都将按特定比例自动修正权重值。
- 这个微小的比例系数,我们称为"感知机学习率"(Perceptron's learning rate)。
- 在感知机对象中,我们将其命名为
learnc
。
3. 偏置项机制
- 当所有输入信号均为零时,感知器可能产生错误输出。
- 为解决此问题,我们为感知机增设一个固定值为1的额外输入项。
- 其对应的权重参数称为"偏置项"(bias)。
添加激活函数
感知器算法执行步骤:
- 将每个输入特征与对应权重相乘。
- 对加权结果进行求和运算。
- 通过激活函数计算输出值。
this.activate = function(inputs) {
let sum = 0;
for (let i = 0; i < inputs.length; i++) {
sum += inputs[i] * this.weights[i];
}
if (sum > 0) {return 1} else {return 0}
}
激活函数的输出规则如下:
- 若加权和大于零,则输出
1
。 - 若加权和小于零,则输出
0
。
创建训练函数
训练函数的工作原理是:基于激活函数对输出结果进行预测判断。
每当预测结果出现误差时,感知器将自动执行权重调整操作。
经过多次迭代预测与权重修正后,感知机的连接权重将最终收敛至最优解。
this.train = function(inputs, desired) {
inputs.push(this.bias);
let guess = this.activate(inputs);
let error = desired - guess;
if (error != 0) {
for (let i = 0; i < inputs.length; i++) {
this.weights[i] += this.learnc * error * inputs[i];
}
}
}
反向传播算法
每次预测后,感知机会执行误差计算,量化预测结果与真实值的偏差程度。
若预测结果错误,感知机将自动调节偏置项与权重参数,使后续预测逐步逼近正确值。
这种学习机制在技术上称为"反向传播算法(Backpropagation)"。
经过数千次迭代训练后,感知器的预测准确度将显著提升至理想水平。
构建自定义机器学习库
自定义库代码:
// 感知器对象构造函数
function Perceptron(no, learningRate = 0.00001) {
// 初始化参数
this.learnc = learningRate; // 学习率参数
this.bias = 1; // 偏置项默认值
// 生成随机权重矩阵
this.weights = [];
for (let i = 0; i <= no; i++) {
this.weights[i] = Math.random() * 2 - 1; // 权重范围[-1,1]
}
// 激活函数实现
this.activate = function(inputs) {
let sum = 0;
for (let i = 0; i < inputs.length; i++) {
sum += inputs[i] * this.weights[i]; // 计算加权和
}
if (sum > 0) {return 1} else {return 0} // 阶跃函数决策
}
// 训练方法
this.train = function(inputs, desired) {
inputs.push(this.bias); // 添加偏置项到输入向量
let guess = this.activate(inputs); // 获取当前预测值
let error = desired - guess; // 计算误差信号
if (error != 0) {
for (let i = 0; i < inputs.length; i++) {
this.weights[i] += this.learnc * error * inputs[i]; // 权重更新规则
}
}
}
// 感知器对象定义结束
}
现在你可以将这个库引入到 HTML 中:
<script src="myperceptron.js"></script>
使用您开发的感知机库
// 初始化数值
const numPoints = 500; // 点的数量
const learningRate = 0.00001; // 学习率
// 创建绘图器
const plotter = new XYPlotter("myCanvas"); // 新建XY绘图器,绑定到画布myCanvas
plotter.transformXY(); // 坐标转换
const xMax = plotter.xMax; // x轴最大值
const yMax = plotter.yMax; // y轴最大值
const xMin = plotter.xMin; // x轴最小值
const yMin = plotter.yMin; // y轴最小值
// 生成随机XY点集
const xPoints = []; // x坐标数组
const yPoints = []; // y坐标数组
for (let i = 0; i < numPoints; i++) {
xPoints[i] = Math.random() * xMax; // 随机生成x坐标
yPoints[i] = Math.random() * yMax; // 随机生成y坐标
}
// 定义线性函数
function f(x) {
return x * 1.2 + 50; // 返回1.2x + 50
}
// 绘制基准线
plotter.plotLine(xMin, f(xMin), xMax, f(xMax), "black"); // 从最小值到最大值画黑色直线
// 计算期望输出值
const desired = []; // 期望值数组
for (let i = 0; i < numPoints; i++) {
desired[i] = 0; // 默认设为0
if (yPoints[i] > f(xPoints[i])) {desired[i] = 1} // 如果点在直线上方则设为1
}
// 创建感知机
const ptron = new Perceptron(2, learningRate); // 2个输入特征,指定学习率
// 训练感知机
for (let j = 0; j <= 10000; j++) { // 训练10000次
for (let i = 0; i < numPoints; i++) {
ptron.train([xPoints[i], yPoints[i]], desired[i]); // 用每个点进行训练
}
}
// 可视化分类结果
for (let i = 0; i < numPoints; i++) {
const x = xPoints[i]; // 当前x坐标
const y = yPoints[i]; // 当前y坐标
let guess = ptron.activate([x, y, ptron.bias]); // 获取感知机预测结果
let color = "black"; // 默认黑色
if (guess == 0) color = "blue"; // 预测为0时显示蓝色
plotter.plotPoint(x, y, color); // 绘制彩色点
}
评论区 0
发表评论
教程介绍
机器学习是人工智能的子领域,通过算法让计算机从数据中自动学习规律,并做出预测或决策。
29
章节
154
阅读
0
评论
反馈提交成功
感谢您的反馈,我们将尽快处理您的反馈