# 过拟合和欠拟合
# 代码展示
import * as tf from '@tensorflow/tfjs';
import * as tfvis from '@tensorflow/tfjs-vis';
// import { getData } from '../xor/data';
import { getData } from './data';
window.onload = async () => {
const data = getData(200, 5);
console.log('data', data);
tfvis.render.scatterplot(
{ name: '训练数据' },
{
values: [
data.filter((p) => p.label === 1),
data.filter((p) => p.label === 0),
],
}
);
const model = tf.sequential();
model.add(
tf.layers.dense({
units: 10, // 神经元个数
inputShape: [2], // 神经元(输入)接受的形状
activation: 'tanh', // 这个激活函数可以带来一些非线性的变化,如果这里不要激活函数相当于这个隐藏层没有用,因为无论设置多少个层没有激活函数输出都是线性的
// kernelRegularizer: tf.regularizers.l2({ l2: 1 }), // l2正则化相当于设置权重衰减 l2为超参数
})
);
/*使用丢弃法解决过拟合-添加一个dropout层*/
model.add(tf.layers.dropout({ rate: 0.3 })); // 相当于10个神经元随机丢弃了N个
model.add(
tf.layers.dense({
units: 1,
inputShape: [2],
activation: 'sigmoid',
})
);
model.compile({
loss: tf.losses.logLoss,
optimizer: tf.train.adam(0.1),
});
const inputs = tf.tensor(data.map((p) => [p.x, p.y]));
const labels = tf.tensor(data.map((p) => p.label));
await model.fit(inputs, labels, {
epochs: 200,
validationSplit: 0.2, // 从训练集分出20%数据作为验证集
callbacks: tfvis.show.fitCallbacks(
{ name: '训练效果' },
['loss', 'val_loss'],
{ callbacks: ['onEpochEnd'] }
),
});
window.predict = (form) => {
const pred = model.predict(
tf.tensor([[form.x.value * 1, form.y.value * 1]])
);
alert(`预测结果:${pred.dataSync()[0]}`);
};
};
# 重点笔记
- validationSplit: 0.2, 表示从训练集分出 20%数据作为验证集
await model.fit(inputs, labels, {
epochs: 200,
validationSplit: 0.2, // 从训练集分出20%数据作为验证集
callbacks: tfvis.show.fitCallbacks(
{ name: '训练效果' },
['loss', 'val_loss'],
{ callbacks: ['onEpochEnd'] }
),
});
欠拟合的解决方案是增加模型的复杂程度(层和神经元),也可能需要增加训练时间
过拟合的应对法:早停法、权重衰减(l2 正则化)、丢弃法
早停法就是观察训练集的损失从哪里增长然后将训练停掉即可(但是如果刚开始训练集损失就猛增那么就相当于失败了,所以这种方式不推荐)
权重衰减简单来说就是把权重的复杂度作为损失的一部分,那么过于复杂的权重也在训练的过程中被衰减掉了
model.add(
tf.layers.dense({
units: 10,
inputShape: [2],
activation: 'tanh',
kernelRegularizer: tf.regularizers.l2({ l2: 1 }), // l2正则化相当于设置权重衰减 l2为超参数
})
);
丢弃法是在神经网络的隐藏层设置丢弃率,丢弃某几个神经元的权重,相当于把隐藏层的神经元个数减少了
model.add(
tf.layers.dense({
units: 10,
inputShape: [2],
activation: 'tanh',
})
);
/*使用丢弃法解决过拟合(添加一个dropout层)*/
model.add(tf.layers.dropout({ rate: 0.3 })); // rate是丢弃率,相当于10个神经元随机丢弃了3个权重