深度学习之简单的DNN实现
·
DNN的原理:神经网络通过学习大量样本的输入与输出特征之间的关系,以拟合出输入与输出之间的方程,学习完成后,只给它输入特征,它便会可以给出输出特征。神经网络可以分为这么几步:划分数据集、训练网络、测试网络、使用网络。
如下图所示:

以下所有的代码都建议在jupyter notebook中运行
一、导入必要的python软件包
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
%matplotlib inline
#展示高清图
from matplotlib_inline import backend_inline
backend_inline.set_matplotlib_formats('svg')
二、生成均匀分布的随机数:
#生成数据集
X1 = torch.rand(10000,1)
X2 = torch.rand(10000,1)
X3 = torch.rand(10000,1)
X1.shape, X2.shape, X3.shape
显示结果:
三、创建对应的输出函数特征:
Y1 = ((X1 + X2 + X3) < 1).float()
Y2 = ((1 < (X1 + X2 + X3)) & ((X1 + X2 + X3) < 2)).float()
Y3 = ((X1 + X2 + X3) > 2).float()
Y1.shape, Y2.shape, Y3.shape
Data = torch.cat([X1,X2,X3,Y1,Y2,Y3], axis = 1) #整合数据集
Data = Data.to('cuda:0') #导入到GPU进行运算
Data.shape
输出结果:
![]()
四、划分训练集和测试集
#划分训练集与测试集
train_size = int(len(Data) * 0.7) #将训练集划分为7成
test_size = len(Data) - train_size #测试集的数量
Data = Data[torch.randperm(Data.size(0)), : ] #打乱数据集
train_Data = Data[:train_size,:]
test_Data = Data[train_size:,:]
train_Data.shape,test_Data.shape
输出结果:
![]()
五、搭建神经网络
搭建神经网络时, 以 nn.Module 作为父类, 我们自己的神经网络可直接继承父类的方法与属性, nn.Module 中包含网络各个层的定义。
class DNN(nn.Module):
def __init__(self):
super(DNN,self).__init__()
self.net = nn.Sequential( #按顺序搭建各层
nn.Linear(3,5), nn.ReLU(), #第一层,全连接层
nn.Linear(5,5), nn.ReLU(), #第二层,全连接层
nn.Linear(5,5), nn.ReLU(), #第三层,全连接层
nn.Linear(5,3) #第四层,全连接层
)
def forward(self,x):
#前向传播
y = self.net(x) #x是输入数据
return y #y是输出数据
model = DNN().to('cuda:0') #把DNN搬到GPU上运行
model
输出结果:

bias为函数的偏置
现在可以打印出前向传播执行时的内部参数:
for name, param in model.named_parameters():
print(f"参数:{name}\n形状:{param.shape}\n数值:{param}\n")
输出结果(部分截图):
六、设置网络的外部参数
#损失函数的选择
loss_fn = nn.MSELoss()
#优化算法的选择
learning_rate = 0.01 #设置学习率
optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate)
七、开始训练该网络
#训练网络
epochs = 1000
losses = [] #记录损失函数变化的列表
#给训练集划分输入与输出
X = train_Data[:, :3] #前三列为输入特征
Y = train_Data[:,-3:] #后三列为输出特征
for epoch in range(epochs):
Pred = model(X) #一次前向传播(批量)
loss = loss_fn(Pred,Y) #计算损失函数
losses.append(loss.item()) #记录损失函数的变化
optimizer.zero_grad() #清理上一轮滞留的梯度
loss.backward() #一次反向传播
optimizer.step() #优化内部参数
#绘图
Fig = plt.figure()
plt.plot(range(epochs),losses)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()
输出结果:
八、测试网络
#测试网络
#给测试集划分输入和输出
X = test_Data[:, :3] #前三列为输入特征
Y = test_Data[:, -3:] #后三列为输出特征
with torch.no_grad(): #该局部关闭梯度计算功能
Pred = model(X) #一次前向传播(批量)
Pred[:,torch.argmax(Pred,axis=1)] = 1
Pred[Pred!=1] = 0
correct = torch.sum((Pred == Y).all(1)) #预测正确的样本
total = Y.size(0) #全部的样本数量
print(f'测试集精准度:{100 * correct/total} %')
输出结果:(该测试集精准度)

九、保存网络
torch.save(model,'model.pth')
输出结果:

重新导入该模型:
new_model = torch.load('model.pth')
十、重新测试该网络
#给测试集划分输入和输出
X = test_Data[:,:3]
Y = test_Data[:,-3:]
with torch.no_grad():
Pred = new_model(X)
Pred[:,torch.argmax(Pred,axis = 1)] = 1
Pred[Pred != 1] = 0
correct = torch.sum((Pred == Y).all(1))
total = Y.size(0)
print(f'测试集精准度:{100 * correct/total} %')
可以检测出该精准度与保存前的精准度相同
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)