手机网站方案,上海建站模板平台,网站建设的行业,淮安市哪里有做网站代码上有注释#xff01;#xff01;#xff01;#xff01;#xff01;#xff01;
本篇主要包括三大部分#xff1a;
第一部分#xff1a;导入数据集导入第三方库数据集简单介绍与可视化数据集简单预处理
第二部分#xff1a;手写神经网络代码实现气温预测#…代码上有注释
本篇主要包括三大部分
第一部分导入数据集导入第三方库数据集简单介绍与可视化数据集简单预处理
第二部分手写神经网络代码实现气温预测手写
第三部分调包搭建神经网络实现气温预测调包找到最优网络模型及其参数
目录
第一部分 准备数据
(一)导入第三方库
(二) 导入数据集
(三)数据可视化
编辑 (四)独热编码处理 (五)数据标准化
第二部分 人工手写神经网络
(一)将数据转换成tensor形式 (二)权重、偏置初始化
(三)设置学习率
(四) 训练网络
第三部分 调包实现神经网络预测气温
(一)设置参数
(二)调用torch.nn中的Sequential序列模块 (三)损失函数
(四)优化器
(五)训练网络
(六)预测结果 (七)预测结果和真实标签进行可视化对比 (八)找到最优模型及其参数 第一部分 准备数据
(一)导入第三方库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
import warnings
warnings.filterwarnings(ignore)
%matplotlib inline
①import warnings 和 warnings.filterwarnings(ignore)
导入Python的warnings模块用于处理警告信息。设置忽略警告信息这样在后续运行代码时不会显示警告。主要是排除版本不同时的警告。 ②%matplotlib inline
这是Jupyter Notebook的魔术命令用于在Notebook中显示matplotlib绘制的图形而不是弹出新窗口显示图形。
(二) 导入数据集
features pd.read_csv(temps.csv)#看看数据长什么样子
features.head() 前五行数据如下 数据表中
year,moth,day,week分别表示的具体的时间temp_2前天的最高温度值temp_1昨天的最高温度值average在历史中每年这一天的平均最高温度值actual这就是我们的标签值了当天的真实最高温度friend这一列是凑热闹的猜测的可能值不用管这一列
print(数据维度:, features.shape) 说明数据中一共有348个样本9个特征。
(三)数据可视化
# 处理时间数据
import datetime
# 分别得到年月日
years features[year]
months features[month]
days features[day]# datetime格式
dates [str(int(year)) - str(int(month)) - str(int(day)) for year, month, day in zip(years, months, days)]
dates [datetime.datetime.strptime(date, %Y-%m-%d) for date in dates]
dates[:5]
打印一下dates[:5],查看前五行数据结果如下
两个零分别代表小时和分钟 # 准备画图
# 指定默认风格
plt.style.use(fivethirtyeight)# 设置布局
fig, ((ax1, ax2), (ax3, ax4)) plt.subplots(nrows2, ncols2, figsize (10,10))
#subplots就是画子图2*2((ax1, ax2), (ax3, ax4))分别是四个子图
fig.autofmt_xdate(rotation 45)#x轴标签旋转度# 标签值
ax1.plot(dates, features[actual])#表示第一个子图里边x轴和y轴分别是什么
ax1.set_xlabel(); ax1.set_ylabel(Temperature); ax1.set_title(Max Temp)
#在这x轴没画值因为和子图3是一样的y轴y轴的名称是Temperature图的名字是Max Temp# 昨天
ax2.plot(dates, features[temp_1])
ax2.set_xlabel(); ax2.set_ylabel(Temperature); ax2.set_title(Previous Max Temp)# 前天
ax3.plot(dates, features[temp_2])
ax3.set_xlabel(Date); ax3.set_ylabel(Temperature); ax3.set_title(Two Days Prior Max Temp)#猜测的数值
ax4.plot(dates, features[friend])
ax4.set_xlabel(Date); ax4.set_ylabel(Temperature); ax4.set_title(Friend Estimate)plt.tight_layout(pad2)#每个子图之间的间隔
结果如下 (四)独热编码处理
# 独热编码 one-hot
# features pd.get_dummies(features)#帮你判断哪一列是字符串自动地帮你把字符串直接展开
features pd.get_dummies(features).astype(int)#输出打印体会一下加不加.astype(int)的区别
features.head(5)
前五行数据如下 # 标签
labels np.array(features[actual])# 在特征中去掉标签
features features.drop(actual, axis 1)#把标签这一列踢出去# 名字单独保存一下以备后患
feature_list list(features.columns)# 转换成合适的格式
features np.array(features)features.shape (五)数据标准化
#标准化
from sklearn import preprocessing
#preprocessing预处理模块
input_features preprocessing.StandardScaler().fit_transform(features) 结果如下 如上 现在所有的值都是数组的结构但torch要tensor的格式结构所以下面要将数组形式转换成tensor的形式。
第二部分 人工手写神经网络
(一)将数据转换成tensor形式
#把要用的数据转换成tensor的格式
x torch.tensor(input_features, dtype float)
y torch.tensor(labels, dtype float) x就作为输入数据是348*14的维度 (二)权重、偏置初始化
# 权重参数初始化
#w,b都是随机初始化
weights torch.randn((14, 128), dtype float, requires_grad True)
biases torch.randn(128, dtype float, requires_grad True)
weights2 torch.randn((128, 1), dtype float, requires_grad True)
biases2 torch.randn(1, dtype float, requires_grad True)
requires_grad True进行计算梯度 在这里构建了两个隐藏层权重w和偏置b都是进行的随机初始化
由于输入数据的维度是384*14
故第一个隐藏层的权重weights是14*128的矩阵偏置biases长度为128
第二个隐藏层的权重weights2是128*1的行向量偏置biases2长度为1
因为这里是做回归也就是预测某一时刻的温度最终输出的是一个值故最终的权重weights的维度是128*1 这里补充一点
输入数据x的维度是348*14第一个隐藏层的权重weights维度为14*128那么x*weights做矩阵运算后的结果维度是348*128但是偏置biases的维度是torch.Size([128])相当于可以看作是有128个元素的行向量那么一个348*128的矩阵怎么和一个1*128的行向量进行加法运算呢
在这种情况下PyTorch会自动将大小为 [128] 的张量 biases扩展为大小为 [348, 128] 的张量使得两个张量的形状相匹配然后再进行逐元素的加法运算。具体来说PyTorch会将大小为 [128] 的行向量biases 在第二维上进行复制扩展为大小为 [348, 128] 的矩阵然后再与x*weights的结果进行逐元素相加。
(三)设置学习率
learning_rate 0.001
学习率是可以自己设置的
更新参数的话我们要沿着一个方向进行参数更新这个学习率就是告诉我们要沿着这个方向走多大的距离
一般来说学习率要相对小一点如果太大了模型可能做的就相对没有那么好了
(四) 训练网络
losses []#损失
#迭代更新1000次
for i in range(1000):# 计算隐层hidden x.mm(weights) biases#x.mm就是一个矩阵乘法 x*wb#一般计算好隐藏层后都要进行一个非线性映射#非线性映射里边也有很多函数比如这里就用到了rule,小于0的时候都等于0大于0的时候都等于xyx# 加入激活函数hidden torch.relu(hidden)#得到实际隐藏层结果# 预测结果predictions hidden.mm(weights2) biases2#计算损失loss torch.mean((predictions - y) ** 2) #计算的是均方误差#现在loss是tensor的格式如果要画图的话需要的是数组的格式losses.append(loss.data.numpy())# 打印损失值#每隔一百次打印一次损失if i % 100 0:print(loss:, loss)#返向传播计算loss.backward()#更新参数w,b#在这里这么理解一下一会其实可以调包的weights.data.add_(- learning_rate * weights.grad.data) #weights.grad.data取这一次反向传播的梯度值#沿着梯度的反方向进行更新所以有这个-负号biases.data.add_(- learning_rate * biases.grad.data)weights2.data.add_(- learning_rate * weights2.grad.data)biases2.data.add_(- learning_rate * biases2.grad.data)# 每次迭代都得记得清空#每一次迭代都应该是独立的和上一次没关系#torch如果没有清零它会累加weights.grad.data.zero_()biases.grad.data.zero_()weights2.grad.data.zero_()biases2.grad.data.zero_() 通过下边的结果可以发现它的losse是随着迭代次数的增加不断降低的最终趋于平稳。 结果如下 下边是迭代结束后第一个隐藏层权重和偏置的参数明显和初始随机初始化的参数不同说明参数进行了梯度更新。 注意
循环结束后打印的参数值是最后一次迭代后的参数值但不一定是最优参数值。要获取最优参数值需要在训练过程中记录并比较每次迭代的性能从而找到最佳的参数。
第三部分 调包实现神经网络预测气温
(一)设置参数
input_size input_features.shape[1]#输入特征的个数 14个
hidden_size 128#隐藏层 可以自己改
output_size 1#输出值 一个
batch_size 16
input_size表示输入特征的个数这里是14个
hidden_size 128:隐藏层有128个隐藏单元。
output_size 1这行代码定义了输出值的大小,即模型输出一个标量值。
batch_size:表示每个批次包含16个样本
(二)调用torch.nn中的Sequential序列模块
在调包环节中和我们第二部分手写神经网络代码不同权重参数、偏置参数是自动帮我们初始化的
#下边就是调包环节了
#torch.nn中的一个Sequential序列模块就是按顺序先执行第一个再执行第二个以此类推
#我定义的序列叫做my_nn
my_nn torch.nn.Sequential(torch.nn.Linear(input_size, hidden_size),#全连接层权重参数是自动帮我们初始化的torch.nn.Sigmoid(),#nn.ReLu()#激活函数torch.nn.Linear(hidden_size, output_size),
) (三)损失函数
cost torch.nn.MSELoss(reductionmean)#损失函数 torch.nn.MSELoss这是 PyTorch 中用于计算均方误差的类。 reductionmean这是 torch.nn.MSELoss 类的一个参数用于指定损失的计算方式。 在这里设置为 mean 表示计算所有样本的均方误差后再取平均值作为最终损失值
(四)优化器
optimizer torch.optim.Adam(my_nn.parameters(), lr 0.001)
Adam优化器效率高 效果好
my_nn.parameters()表示将神经网络模型my_nn的所有参数传递给优化器以便优化这些参数。lr0.001表示学习率为0.001即Adam优化器在更新参数时所采用的学习率。
(五)训练网络
# 训练网络
losses []
for i in range(1000):batch_loss []# MINI-Batch方法来进行训练for start in range(0, len(input_features), batch_size):end start batch_size if start batch_size len(input_features) else len(input_features)
# 如果 start batch_size 的结果小于 input_features 的长度即 len(input_features)则将 end 的值设为 start batch_size。
# 否则如果 start batch_size 的结果大于或等于 input_features 的长度那么 end 的值将设为 len(input_features)xx torch.tensor(input_features[start:end], dtype torch.float, requires_grad True)yy torch.tensor(labels[start:end], dtype torch.float, requires_grad True)prediction my_nn(xx)loss cost(prediction, yy)optimizer.zero_grad()#梯度清零loss.backward(retain_graphTrue)#反向传播optimizer.step()#反向传播之后再进行参数更新batch_loss.append(loss.data.numpy())#print(len(batch_loss))#结果是22 len(input_features)348 batch_size16,21*1612348# 打印损失每更新迭代一百次打印一次损失if i % 1000:losses.append(np.mean(batch_loss))
# print(losses)print(i, np.mean(batch_loss))
结果如下 在这段代码中通过迭代训练神经网络来降低损失函数值使得神经网络的预测结果更接近真实标签。在每次迭代过程中会计算一个 mini-batch 的损失值并根据这个 mini-batch 更新神经网络的参数。 最终目的是通过不断迭代训练使得损失函数值逐渐减小达到一个较好的模型效果。 # 在代码中损失值逐渐减小的原因可能有以下几点
梯度下降优化算法通过调用 optimizer.step() 方法使用梯度下降算法来更新神经网络的参数使得损失值逐渐减小。
学习率调整在梯度下降算法中学习率的设置对模型训练的效果有很大影响。合适的学习率能够使得模型更快地收敛到最优解。
迭代次数在迭代次数足够多的情况下模型有更多的机会逐渐优化参数从而使得损失值逐渐减小。
Mini-batch 训练使用 mini-batch 训练方法可以更有效地利用计算资源同时也有助于模型的收敛。
综合以上因素随着迭代次数的增加损失值逐渐减小是一个正常的训练过程。当损失值趋于稳定时可以认为模型已经收敛到一个较好的状态。
(六)预测结果
x torch.tensor(input_features, dtype torch.float)
predict my_nn(x).data.numpy() #每一个样本也就是每一天的预测值 预测结果如下 (七)预测结果和真实标签进行可视化对比
# 转换日期格式
dates [str(int(year)) - str(int(month)) - str(int(day)) for year, month, day in zip(years, months, days)]
dates [datetime.datetime.strptime(date, %Y-%m-%d) for date in dates]# 创建一个表格来存日期和其对应的标签数值
true_data pd.DataFrame(data {date: dates, actual: labels}) # 同理再创建一个来存日期和其对应的模型预测值
months features[:, feature_list.index(month)]
days features[:, feature_list.index(day)]
years features[:, feature_list.index(year)]test_dates [str(int(year)) - str(int(month)) - str(int(day)) for year, month, day in zip(years, months, days)]test_dates [datetime.datetime.strptime(date, %Y-%m-%d) for date in test_dates]predictions_data pd.DataFrame(data {date: test_dates, prediction: predict.reshape(-1)}) # 真实值
plt.plot(true_data[date], true_data[actual], b-, label actual)# 预测值
plt.plot(predictions_data[date], predictions_data[prediction], ro, label prediction)
plt.xticks(rotation 60)
plt.legend()#添加图例# 图名
plt.xlabel(Date); plt.ylabel(Maximum Temperature (F)); plt.title(Actual and Predicted Values);结果如下 (八)找到最优模型及其参数
我们试想上边预测出来的结果是在最优参数模型情况下吗其实并不是的是在最后一次迭代结束后的参数基础上进行的预测。
下边我们一起学习一下寻找最优模型及其参数的过程。
# 训练网络
losses []
# 初始化 best_loss 为一个很大的值确保第一次比较不会出错
best_loss float(inf)
import copyfor i in range(1000):batch_loss []# MINI-Batch方法来进行训练for start in range(0, len(input_features), batch_size):end start batch_size if start batch_size len(input_features) else len(input_features)
# 如果 start batch_size 的结果小于 input_features 的长度即 len(input_features)则将 end 的值设为 start batch_size。
# 否则如果 start batch_size 的结果大于或等于 input_features 的长度那么 end 的值将设为 len(input_features)xx torch.tensor(input_features[start:end], dtype torch.float, requires_grad True)yy torch.tensor(labels[start:end], dtype torch.float, requires_grad True)prediction my_nn(xx)#print(prediction)loss cost(prediction, yy)optimizer.zero_grad()#梯度清零loss.backward(retain_graphTrue)#反向传播optimizer.step()#反向传播之后再进行参数更新batch_loss.append(loss.data.numpy())#print(len(batch_loss))#结果是22 len(input_features)348 batch_size16,21*1612348# 计算整体损失xx_val torch.tensor(input_features, dtypetorch.float)yy_val torch.tensor(labels, dtypetorch.float)prediction_val my_nn(xx_val)loss_val cost(prediction_val, yy_val)val_loss loss_val.data.numpy()# 如果当前epoch的验证损失更低则保存当前模型的权重if val_loss best_loss:best_loss val_lossbest_model_weights copy.deepcopy(my_nn.state_dict())# # 打印损失
# if i % 1000:
# losses.append(np.mean(batch_loss))
# # print(losses)
# print(i, np.mean(batch_loss))
这里我们在原先的代码上做了一点小改动。
best_loss float(inf)表示最优损失初始化 best_loss 为一个很大的值确保第一次比较不会出错。
要得到最优情况下的模型需要在训练过程中保存性能最好的模型权重。这可以通过在每次迭代结束时计算损失并将其与之前的最佳损失进行比较来实现。如果当前迭代的损失更低则保存当前模型的权重。
best_model_weights copy.deepcopy(my_nn.state_dict())执行这行代码你可以保存当前神经网络模型的参数状态以便在后续的训练过程中使用或恢复模型的状态。
最优参数如下 All keys matched successfully的运行结果表示成功地将最佳模型的权重加载到了神经网络模型中。这意味着load_state_dict()方法成功地将最佳模型的权重参数与当前神经网络模型的相应参数进行匹配并将最佳模型的权重参数加载到了当前模型中。
因此All keys matched successfully的输出表明加载权重的过程顺利完成当前模型已经成功地更新为最佳模型的状态可以继续使用这个模型进行预测或其他任务。