TensorFlow.NET机器学习入门【2】线性回归
回归分析用于分析输入变量和输出变量之间的一种关系,其中线性回归是最简单的一种。
设: Y=wX+b,现已知一组X(输入)和Y(输出)的值,要求出w和b的值。
举个例子:快年底了,销售部门要发年终奖了,销售员小王想知道今年能拿多少年终奖,目前他大抵知道年终奖是和销售额(特征量)挂钩的,具体什么规则不清楚,那么他大概有两个方法解决这个问题:
1、去问老板,今年的分配规则是什么。【通过算法解决问题】
2、去向同事打听他们的销售额和奖金情况,然后推算自己能拿多少。【通过数据解决问题】
我们当然选择第二种方法了。通过收集数据,我们得到下面这个表格:

拿到这个数据,我们基本上很快就能推算出两者的对应关系,如果推算不出来,我们也可以绘制下面这张图表:

通过图表,我们可以立即看出两者的对应关系了。
以上就是一个典型的线性回归求解的问题,下面我们要用TensorFlow框架解决这个问题。
具体解决思路如下:
1、先设w=1,b=0
2、取得一批训练数据,将X代入函数f(x)=wx+b,计算取得在当前条件下的预测值Y‘
3、计算预测值Y‘和实际值Y的误差
4、根据梯度对w、b进行微调
5、重复上述步骤,直到误差值足够小。
先贴出全部代码,然后再逐一解释。
public class LinearRegression
{
public void Run()
{
// Supper Parameters
float learning_rate = 0.01f; var W = tf.Variable<float>(1);
var b = tf.Variable<float>(0); int epochs = 30;
int steps = 100;
Tensor loss = null; for (int epoch = 0; epoch < epochs; epoch++)
{
for (int step = 0; step < steps; step++)
{
int batch_size = 10;
(NDArray train_X, NDArray train_Y) = LoadBatchData(batch_size); using (var g = tf.GradientTape())
{
//通过当前参数计算预测值
var pred_y = W * train_X + b; //计算预测值和实际值的误差
loss = tf.reduce_sum(tf.pow(pred_y - train_Y, 2)) / batch_size; //计算梯度
var gradients = g.gradient(loss, (W, b)); //更新参数
W.assign_sub(learning_rate * gradients.Item1);
b.assign_sub(learning_rate * gradients.Item2);
}
} Console.WriteLine($"Epoch{epoch + 1}: loss = {loss.numpy()}; W={W.numpy()},b={b.numpy()}");
}
} public (NDArray, NDArray) LoadBatchData(int n_samples)
{
float w = 0.02f;
float b = 1.0f; NDArray train_X = np.arange<float>(start: 1, end: n_samples + 1);
NDArray train_Y = train_X * w + b; return (train_X, train_Y);
}
}
下面对代码进行简单的解释:
首先,我们要读取一批(比如10组 )训练数据,标记为:train_X和train_Y,然后通过现有的w和b值计算预测值:pred_Y=w*train_X_b,此时train_X、train_Y、pred_Y都是10个数据长度的数组。
然后计算预测数据和时间数据之间的误差,我们采用均方误差公式来计算:

然后开始计算W、b对于loss函数的梯度,梯度表达的就是W、b的变化对计算结果的影响,比如将W增大一点,loss的计算结果是变大还是变小,我们的目标是希望loss的值最小,如果w变大时loss变大(梯度为正数),那么我们下一次就将w变小一点,反之同理。

这里的learning_rate表示学习率,表示每次参数进行调整的步进值,就是每次调整一大步,还是一小步。通过多次的循环调整,w和b的值将调整为一个合适的数字,此时loss的值将会很小,线性回归就完成了。以下是运算结果:

在上述过程中,最难理解的就是梯度,以及如何计算梯度的问题,想要进一步了解的话可以参阅相关参考资料。
【相关资源】
源码:Git: https://gitee.com/seabluescn/tf_not.git
项目名称:LinearRegression
【参考资料】
《深度学习入门:基于Python的理论与实践(斋藤康毅)》,网上可以找到电子版
TensorFlow.NET机器学习入门【2】线性回归的更多相关文章
- TensorFlow.NET机器学习入门【0】前言与目录
曾经学习过一段时间ML.NET的知识,ML.NET是微软提供的一套机器学习框架,相对于其他的一些机器学习框架,ML.NET侧重于消费现有的网络模型,不太好自定义自己的网络模型,底层实现也做了高度封装. ...
- TensorFlow.NET机器学习入门【1】开发环境与类型简介
项目开发环境为Visual Studio 2019 + .Net 5 创建新项目后首先通过Nuget引入相关包: SciSharp.TensorFlow.Redist是Google提供的TensorF ...
- TensorFlow.NET机器学习入门【3】采用神经网络实现非线性回归
上一篇文章我们介绍的线性模型的求解,但有很多模型是非线性的,比如: 这里表示有两个输入,一个输出. 现在我们已经不能采用y=ax+b的形式去定义一个函数了,我们只能知道输入变量的数量,但不知道某个变量 ...
- TensorFlow.NET机器学习入门【4】采用神经网络处理分类问题
上一篇文章我们介绍了通过神经网络来处理一个非线性回归的问题,这次我们将采用神经网络来处理一个多元分类的问题. 这次我们解决这样一个问题:输入一个人的身高和体重的数据,程序判断出这个人的身材状况,一共三 ...
- TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST)
从这篇文章开始,终于要干点正儿八经的工作了,前面都是准备工作.这次我们要解决机器学习的经典问题,MNIST手写数字识别. 首先介绍一下数据集.请首先解压:TF_Net\Asset\mnist_png. ...
- TensorFlow.NET机器学习入门【6】采用神经网络处理Fashion-MNIST
"如果一个算法在MNIST上不work,那么它就根本没法用:而如果它在MNIST上work,它在其他数据上也可能不work". -- 马克吐温 上一篇文章我们实现了一个MNIST手 ...
- TensorFlow.NET机器学习入门【7】采用卷积神经网络(CNN)处理Fashion-MNIST
本文将介绍如何采用卷积神经网络(CNN)来处理Fashion-MNIST数据集. 程序流程如下: 1.准备样本数据 2.构建卷积神经网络模型 3.网络学习(训练) 4.消费.测试 除了网络模型的构建, ...
- TensorFlow.NET机器学习入门【8】采用GPU进行学习
随着网络越来约复杂,训练难度越来越大,有条件的可以采用GPU进行学习.本文介绍如何在GPU环境下使用TensorFlow.NET. TensorFlow.NET使用GPU非常的简单,代码不用做任何修改 ...
- 45、Docker 加 tensorflow的机器学习入门初步
[1]最近领导天天在群里发一些机器学习的链接,搞得好像我们真的要搞机器学习似的,吃瓜群众感觉好神奇呀. 第一步 其实也是最后一步,就是网上百度一下,Docker Toolbox,下载下来,下载,安装之 ...
随机推荐
- 【Tool】IntelliJ IDEA 使用技巧
IntelliJ IDEA 使用技巧 2019-11-06 20:51:43 by冲冲 1.快捷键 Ctrl+w //括出相关范围 Ctrl+shift+f //按照代码段在全局搜索 Ctrl+f ...
- 应用程序池自动停止,事件查看器报错6D000780
20210913 今天中午网站突然报错,后台程序无法访问,503错误. 调查发现"应用程序池"被关闭,但是手动开启后不久,又被关闭. 本地调试没问题,所以一开始怀疑是服务器或者Ng ...
- [JSC2021 A~D + F]
半小时打完了\(A~D\),想要一发\(F\)冲进前\(100\),结果平衡树常数大\(T\)了.据说\(G\)是矩阵树定. \(A\) 放代码吧. A // code by Dix_ #includ ...
- 洛谷 P4099 - [HEOI2013]SAO(树形 dp)
题面传送门 题意: 有一个有向图 \(G\),其基图是一棵树 求它拓扑序的个数 \(\bmod (10^9+7)\) \(n \in [1,1000]\) 如果你按照拓扑排序的方法来做,那恐怕你已经想 ...
- Codeforces 772D - Varying Kibibits(高维差分+二项式定理维护 k 次方和)
Codeforces 题目传送门 & 洛谷题目传送门 首先很容易注意到一件事,那就是对于所有 \(f(S)\) 可能成为 \(x\) 的集合 \(S\),必定有 \(\forall y\in ...
- 非标准的xml解析器的C++实现:三、解析器的初步实现
如同我之前的一篇文章说的那样,我没有支持DTD与命名空间, 当前实现出来的解析器,只能与xmlhttp对比,因为chrome浏览器解析大文档有bug,至于其他人实现的,我就不一一测试了,既然都决定自己 ...
- 学习java的第十一天
一.今日收获 1.学习java完全学习手册2.9.3循环结构的内容并验证例题 2.观看哔哩哔哩上的教学视频 二.今日问题 1.基本没有 三.明日目标 1.继续完成2.9.3循环结构的例题 2.哔哩哔哩 ...
- 日常Java 2021/9/20
Java随机数 运用Java的random函数实现猜数字游戏 随机产生一个1-50之间的数字,然后让玩家猜数,猜大猜小都给出提示,猜对后游戏停止 package pingchangceshi; imp ...
- 关于vue-cli中-webkit-flex-direction: column失效问题
我最近在用vue-cli更新项目,在我引入layer.css后会报错并且使用弹性盒时查看元素的时候没有-webkit-flex-direction: column这个属性会失效 这个本身就不打算给di ...
- Linux学习 - shell脚本执行
一.shell概述 shell是一个命令行解释器,为用户提供一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动.挂起.停止甚至是编写一些程序 shell还是一个功能强 ...