目录
波士顿房价预测是一个经典的机器学习任务,类似于程序员世界的“Hello World”。和大家对房价的普遍认知相同,波士顿地区的房价是由诸多因素影响的。该数据集统计了13 种可能影响房价的因素和该类型房屋的均价,期望构建一个基于 13 个因素进行房价预测的模型,如图所示。

对于预测问题,可以根据预测输出的类型是连续的实数值,还是离散的标签,区分为回归任务和分类任务。因为房价是一个连续值,所以房价预测显然是一个回归任务。下面我们尝试用最简单的线性回归模型解决这个问题,并用神经网络来实现这个模型。
数据处理是解决问题的第一步,主要包含五个部分:
先将数据集'housing.data'上传至平台, 并通过 fromfile 语句将数据集导入。由于读入的原始数据是 1 维的,系统默认将所有数据都是连在一起。因此需要我们将数据的形状进行变换,形成一个 2 维的矩阵,每行有一个数据样本的13 个特征(影响房价的特征)和 1 个该类型房屋的均价。
数据集划分主要采用比例划分,本实验采取 80%为训练集,20%为测试集。
归一化处理十分有必要,既可以提高计算机的计算速度,提高模型训练效率, 而且可以减少量纲对结果的影响。本实验采用最大最小值归一化方法,它适用于数据分布有明显边界的情况。
由于面对海量样本的数据集,如果每次计算都使用全部的样本来计算损失函数和梯度,性能很差(计算得慢)。所以我们需要分批读入数据。但越接近最后的几个批次数据对模型参数的影响可能越大,也就是说神经网络的记忆很有可能被最新的数据覆盖。如果训练数据天然的分布不好,比如做分类问题,第 0 类的数据在前,第 1 类的数据都在后面,那么模型肯定偏重第一类样本。所以有必要随机抽取样本进行训练。我们用 np.random.shuffle( )来打乱样本数据。这种方法称为小批量随机梯度下降法。
将一系列对数据的操作封装在 load_data 函数中,以便于后面函数的调用。load_data 函数代码如下
import numpy as np def load_data():
#将数据集导入
datafile = 'data/housing (1).data' data = np.fromfile(datafile, sep=' ') #数据集形状变化
feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE','DIS',
'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]
feature_num = len(feature_names)
data = data.reshape([data.shape[0] // feature_num, feature_num]) maximums, minimums, avgs = \
data.max(axis=0), \ data.min(axis=0), \
data.sum(axis=0) / data.shape[0]
# 数据集的划分
ratio = 0.8
offset = int(data.shape[0] * ratio) training_data = data[:offset] test_data= data[offset:]
# 对数据进行归一化处理(最值归一化)
for i in range(feature_num):
training_data[:, i] = (training_data[:, i] - avgs[i]) / (maximums[i] - minimums[i]) for i in range(feature_num):
test_data[:, i] = (test_data[:, i] - avgs[i]) / (maximums[i] - minimums[i])
return training_data,test_data
本实验需要通过 13 个输入预测一个输出,因此我们构建 13 输入 1 输出的神经元,由于我们采用多元线性回归来进行预测,该神经网络不需要激活函数并且不需要隐藏层。结构如下图所示。

因为模型的初值直接影响模型参数的优化过程的效率与精确性。因此我们需要给模型的权重一组符合正态分布的初值。
将数据读入后我们可以进行神经网络的前向计算,w 和 b 分别表示该线性模型的权重和偏置,公式如下

此时算出的 y 是神经网络的预测值,我们需要其与真实值进行比较,通过均方误差和来表示多样本下神经网络预测结果的误差,L 代表损失函数,n 代表样本数目,公式如下

假如模型就前向计算一次,预测结果一定是不准确的,因为这是一个开环系统, 我们需要设计一个闭环系统,能够反馈得到的误差,然后去矫正,最终预测值逼近真实值。此时问题相当于转换为计算损失函数的全局最小值,但在多元函数的情形下,求极值需要解线性方程组,计算量较大,因此我们采用数值优化的方法, 通过迭代的思想逼近极值。本实验采用小批量随机梯度下降法进行极值近似解的求解。负梯度方向是多元函数某点下降最快的方向,但由于面对海量样本的数据集,如果每次计算都使用全部的样本来计算损失函数和梯度,性能很差(计算得慢)。所以我们需要分批读入数据,也就是只计算一批数据的平均梯度,同时数据的分布、先后对实验结果会有影响,所以我们随机抽取样本进行训练
该损失函数 L 相对权重 w 的梯度与相对偏置 b 的定义如下

为了便于梯度的计算,我们将损失函数除以 2,梯度的分量可以应用链式求导法则计算,此处不再赘述。求出某个点的梯度意味着得到了该点下降最快的方向向量,通过将该点向最快下降方向移动一定步长损失函数就能够下降。此时函数的变量为权重与偏置,所以一下 x 为权重与偏置组成的向量,eta 代表步长(本实验取 0.01),gradient 代表在 x 这个点的梯度向量,迭代公式如下

采用这种迭代的方式求解是无止境的,因此我们需要设定一个终止的准则,本实验为计算方便,采用迭代次数终止准则,下面列举几种终止准则公式

代码如下
class Network(object):
def init__(self, num_of_weights): # 初始化权重值
# 随机产生 w 的初始值,为了保持程序每次运行结果的一致性,设置固定的随机数种子
np.random.seed(0)
self.w = np.random.randn(num_of_weights, 1) #初始参数一般符合标准正态分布self.b = 0.
def forward(self, x):
z = np.dot(x, self.w) + self.b return z
def loss(self, z, y): error = z - y
cost = error * error cost = np.mean(cost) return cost
def gradient(self, x, y, z): gradient_w = (z - y) * x
gradient_w = np.mean(gradient_w, axis=0) gradient_w = gradient_w[:, np.newaxis] gradient_b = (z - y)
gradient_b = np.mean(gradient_b) return gradient_w,gradient_b
def update(self, gradient_w,gradient_b, eta=0.01): self.w = self.w - eta * gradient_w
self.b = self.b - eta * gradient_b
def train(self, training_data, epoch_num=100, batch_size=10, eta=0.01): n=len(training_data)
losses = []
for epoch in range(epoch_num): #打乱数据集并分批
np.random.shuffle(training_data) for k in range(0,n,batch_size):
mini_batches=[training_data[k:k+batch_size]]
for iter_id, mini_batch in enumerate(mini_batches): x=mini_batch[:,:-1]
y=mini_batch[:,-1:] z = self.forward(x) L = self.loss(z, y)
gradient_w, gradient_b = self.gradient(x, y, z) self.update(gradient_w, gradient_b, eta) losses.append(L)
return losses

源程序包含了对不同epoch和batch_size的调参,神经网络的训练过程,以及预测结果及误差。
#对数据的处理
import numpy as np
def load_data():
#将数据集导入
datafile = 'data/housing (1).data'
data = np.fromfile(datafile, sep=' ')
#数据集形状变化
feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE','DIS',
'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]
feature_num = len(feature_names)
data = data.reshape([data.shape[0] // feature_num, feature_num])
maximums, minimums, avgs = \
data.max(axis=0), \
data.min(axis=0), \
data.sum(axis=0) / data.shape[0]
# 数据集的划分
ratio = 0.8
offset = int(data.shape[0] * ratio)
training_data = data[:offset]
test_data= data[offset:]
# 对数据进行归一化处理(最值归一化)
for i in range(feature_num):
training_data[:, i] = (training_data[:, i] - avgs[i]) / (maximums[i] - minimums[i])
for i in range(feature_num):
test_data[:, i] = (test_data[:, i] - avgs[i]) / (maximums[i] - minimums[i])
return training_data,test_data
#定义神经网络
class Network(object):
def __init__(self, num_of_weights): # 初始化权重值
# 随机产生w的初始值,为了保持程序每次运行结果的一致性,设置固定的随机数种子
np.random.seed(0)
self.w = np.random.randn(num_of_weights, 1) #初始参数一般符合标准正态分布
self.b = 0.
def forward(self, x):
z = np.dot(x, self.w) + self.b
return z
def loss(self, z, y):
error = z - y
cost = error * error
cost = np.mean(cost)
return cost
def gradient(self, x, y, z):
gradient_w = (z - y) * x
gradient_w = np.mean(gradient_w, axis=0)
gradient_w = gradient_w[:, np.newaxis]
gradient_b = (z - y)
gradient_b = np.mean(gradient_b)
return gradient_w,gradient_b
def update(self, gradient_w,gradient_b, eta=0.01):
self.w = self.w - eta * gradient_w
self.b = self.b - eta * gradient_b
def train(self, training_data, epoch_num=100, batch_size=10, eta=0.01):
n=len(training_data)
losses = []
for epoch in range(epoch_num):
#打乱数据集并分批
np.random.shuffle(training_data)
for k in range(0,n,batch_size):
mini_batches=[training_data[k:k+batch_size]]
for iter_id, mini_batch in enumerate(mini_batches):
x=mini_batch[:,:-1]
y=mini_batch[:,-1:]
z = self.forward(x)
L = self.loss(z, y)
gradient_w, gradient_b = self.gradient(x, y, z)
self.update(gradient_w, gradient_b, eta)
losses.append(L)
return losses
#参数的调试
plot_y3=[]
for i in range(1,100,3):
losses=net.train(training_data,epoch_num=200,batch_size=i,eta=0.1)
# 画出损失函数的变化趋势
plot_x3=range(1,100,3)
l=losses[-1]
plot_y3.append(l)
plt.plot(plot_x3,plot_y3)
plt.xlabel('batch_size')
plt.ylabel('final losses')
plt.show()
#参数的调试
plot_y3=[]
for i in range(50,1000,20):
losses=net.train(training_data,epoch_num=i,batch_size=30,eta=0.1)
# 画出损失函数的变化趋势
plot_x3=range(50,1000,20)
l=losses[-1]
plot_y3.append(l)
plt.plot(plot_x3,plot_y3)
plt.xlabel('epoch_num')
plt.ylabel('final losses')
plt.show()
# 画出最优参数下损失函数的变化趋势
import matplotlib.pyplot as plt
training_data, test_data = load_data()
x = training_data[:, :-1]
y = training_data[:, -1:]
# 创建网络
net = Network(13)
# 启动训练
losses = net.train(training_data, epoch_num=200, batch_size=30, eta=0.1)
# 画出损失函数的变化趋势
plot_x = np.arange(len(losses))
plot_y = np.array(losses)
plt.plot(plot_x, plot_y)
plt.xlabel('Iteration order')
plt.ylabel('loss')
plt.show
#可视化测试的结果
import matplotlib.pyplot as plt
training_data,test_data=load_data()
x=test_data[:,:-1]
y=test_data[:,-1:]
y_predict=net.forward(x)
plot_x=np.arange(len(y_predict))
plot_y=np.array(y_predict)
plt.plot(plot_x,plot_y)
plot_y1=np.array(y)
plt.plot(plot_x,plot_y1)
plt.legend(['predict','true'],loc='upper left')
plt.ylim([-0.7,0.5])
plt.show()
plot_y2=np.array(y-y_predict)
plt.plot(plot_x,plot_y2)
plt.ylabel('predict error')
plt.show()
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk=Var(yt)Cov(yt,yt−k)其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
进行这种深度检查的最佳方法是什么:{:a=>1,:b=>{:c=>2,:f=>3,:d=>4}}.include?({:b=>{:c=>2,:f=>3}})#=>true谢谢 最佳答案 我想我从那个例子中明白了你的意思(不知何故)。我们检查子哈希中的每个键是否在超哈希中,然后检查这些键的对应值是否以某种方式匹配:如果值是哈希,则执行另一次深度检查,否则,检查值是否相等:classHashdefdeep_include?(sub_hash)sub_hash.keys.all?do|key|self.has_key?(key)&&ifs