x的平方
来源:7-1 多层神经网络任务简介

二位取根
2020-06-11
老师您好,看了您的课程也已经有一段时间了。感觉自己听还是听得懂,但是就是很难举一反三,举个简单的例子,比如我想将学习的运用到实践,就一个很简单的非线性问题,求x的平方,就不知道用什么损失函数和激活函数了,网上也很难查到。自己不断去试也没有很好的结果。是因为这个非线性很难还是什么?因为从常理的角度来看就是一个平方应该是很简单的,望老师指点
4回答
-
import * as tf from '@tensorflow/tfjs'; import * as tfvis from '@tensorflow/tfjs-vis'; window.onload = async () => { const len = 40; const xs = Array.from({ length: len }, (v, k) => (k - len / 2) / (len / 20)); const ys = xs.map(x => x ** 2); tfvis.render.scatterplot( { name: 'x 的平方的数据' }, { values: xs.map((x, i) => ({ x, y: ys[i] })) }, { xAxisDomain: [-20, 20], yAxisDomain: [0, 110] } ); const inputs = tf.tensor(xs); const labels = tf.tensor(ys); const model = tf.sequential(); model.add(tf.layers.dense({ units: 200, inputShape: [1], activation: 'sigmoid' })); model.add(tf.layers.dense({ units: 1 })); model.compile({ loss: tf.losses.meanSquaredError, optimizer: tf.train.adam(0.1) }); await model.fit(inputs, labels, { epochs: 200, callbacks: tfvis.show.fitCallbacks( { name: '训练过程' }, ['loss'], { callbacks: ['onEpochEnd'] } ) }); const output = model.predict(tf.tensor(xs)); const ysPred = output.dataSync(); tfvis.render.scatterplot( { name: '预测结果' }, { values: [ xs.map((x, i) => ({ x, y: ys[i] })), xs.map((x, i) => ({ x, y: ysPred[i] })), ], series: ['原始数据', '预测数据'] }, { xAxisDomain: [-20, 20], yAxisDomain: [0, 110] } ); };
这是我写的代码,拿去参考一下。结果:
PS:这种问题几乎不会用神经网络来解,你应该找一些真实世界的数据来拟合。
012020-06-16 -
二位取根
提问者
2020-06-16
老师我还是不是很清楚,首先如果使用xor的模型的话,输出层的激活函数是sigmoid,高函数不是输出概率为0-1之间的吗?并且relu的曲线好像是抛弃了0以下的,不会有影响吗?其次我按照您说的换成了xor的模型使用平方的数据,但是还是没有想要的结果。我的理解是输出层激活函数还是应该使用均方误差,然后隐藏层使用其他的激活函数,归不归一化我都试过了(当然可能归一化理解错了),但是尝试过依旧不行,我将代码附上烦请您抽空帮我看看具体错在哪里,万分感谢。我感觉我还是没有理解到使用的真谛,只会单纯地理解您讲的。
import * as tf from '@tensorflow/tfjs'; import * as tfvis from '@tensorflow/tfjs-vis'; import { getData } from './data'; window.onload = async () => { const data = getData(1000); const xs = data.xArr; const ys = data.yArr; console.log('xs', xs); console.log('ys', ys); /*构造归一化训练数据*/ const xMin = Math.min.apply(null, xs); const xMax = Math.max.apply(null, xs); const yMin = Math.min.apply(null, ys); const yMax = Math.max.apply(null, ys); const inputs = normalizationData(xs, xMax, 0); const labels = normalizationData(ys, yMax, 0); console.log('inputs', inputs.dataSync()); console.log('labels', labels.dataSync()); /*将训练数据转换成tensor*/ /* const inputs = tf.tensor(xs); const labels = tf.tensor(ys); */ /* * 归一化数据 * */ function normalizationData(arr, max, min) { return tf .tensor(arr) .sub(min) .div(max - min); } /* * 反归一化 * */ function unNormalizationData(output, max, min) { return output .mul(max - min) .add(min) .dataSync()[0]; } /* 数据可视化 */ tfvis.render.scatterplot( { name: '非线性回归训练集', }, { values: xs.map((x, i) => ({ x, y: ys[i], })), }, { xAxisDomain: [-10, 10], // 设置x轴范围 yAxisDomain: [0, 100], // 设置y轴范围 } ); /* 初始化模型 */ const model = tf.sequential(); // 连续模型(绝大多数问题都用这个) /*添加隐藏层*/ model.add( tf.layers.dense({ units: 4, // 神经元个数 inputShape: [1], // // 神经元(输入)接受的形状 activation: 'relu', // 这个激活函数可以带来一些非线性的变化,如果这里不要激活函数相当于这个隐藏层没有用,因为无论设置多少个层没有激活函数输出都是线性的 }) ); /*添加输出层*/ model.add( tf.layers.dense({ // sequential为连续输出模型所以这里不需要设置inputshape units: 1, // 只需要输出一个概率 activation: 'sigmoid', // 输出一个0-1的概率只能选sigmoid }) ); /*新增损失函数和优化器*/ model.compile({ loss: tf.losses.logLoss, optimizer: tf.train.adam(0.1), }); /*异步训练模型*/ await model.fit(inputs, labels, { validationData: [tf.tensor(xs), tf.tensor(ys)], // 验证集(格式和训练集一样) batchSize: 200, // 每次样本需要学习的样本数据量 epochs: 100, // 训练轮数 callbacks: tfvis.show.fitCallbacks( // 可视化模拟训练过程 { name: '训练过程' }, ['loss', 'val_loss', 'acc', 'val_acc'] // 训练集损失/验证集损失/训练集准确度/验证集准确度 ), }); $('#test') .removeAttr('disabled') .on('click', function () { /*输出预测结果并显示*/ const output = model.predict( normalizationData([Number($('#input').val())], xMax, 0) /* tf.tensor([Number($('#input').val())]) */ ); // 输入一个tensor帮你预测结果并赋值给变量 console.log('output', output.dataSync()[0]); const resY = unNormalizationData(output, yMax, 0); /* const resY = output; */ console.log('output', resY); }); };
数据代码:
export function getData(numSamples) { let xArr = []; let yArr = []; let count = 0; for (let i = 0; i < numSamples - 1; i++) { count += 1; // 可调 xArr.push(count); yArr.push(count * count); xArr.push(-count); yArr.push(count * count); } let data = { xArr: xArr, yArr: yArr, }; console.log('data', data); return data; }
00 -
二位取根
提问者
2020-06-15
老师您好,多层神经网络的课程我已经看完。给我的感觉是照着您的代码学,也是能够理解,跟着敲也能正确,但是就是不能够很好的举一反三。比如我又尝试了那个求平方的问题,就很迷茫,损失函数使用什么?是否是均方误差?激活函数应该用什么?应该用几层?等等,我尝试了两层添加激活函数,也试过将数据归一化再处理,但是都得不到很好的结果,望老师指点一二
012020-06-15 -
lewis
2020-06-11
看到后面你就知道,多层神经网络可以拟合任何复杂的非线性问题
00
相似问题