Pytorch: 완전히 연결된 간단한 네트워크를 구축하는 방법을 알려줍니다.

코드의 주석을 꼭 읽어보세요! ! ! 여기에는 몇 가지 기본 지식과 이유가 포함됩니다.

다음 코드 세그먼트를 차례로 함께 실행하거나 jupyter 노트북을 통해 배치로 실행할 수 있습니다.

첫 번째 단계: 일부 라이브러리 가져오기

import torch#深度学习的pytoch平台
import torch.nn as nn
import numpy as np
import random
import time#可以用来简单地记录时间
import matplotlib.pyplot as plt#画图
#随机种子
random.seed(1234)
np.random.seed(1234)
torch.manual_seed(1234)
torch.cuda.manual_seed(1234)
torch.cuda.manual_seed_all(1234)

2단계: 간단한 데이터 세트 구축, 여기에서는 sinx 함수를 예로 사용합니다.

x = np.linspace(-np.pi,np.pi).astype(np.float32)
y = np.sin(x)
#随机取25个点
x_train = random.sample(x.tolist(),25)    #x_train 就相当于网络的输入
y_train = np.sin(x_train)                 #y_train 就相当于输入对应的标签,每一个输入都会对应一个标签
plt.scatter(x_train,y_train,c="r")
plt.plot(x,y)

 빨간색 점은 내가 네트워크의 훈련 점으로 sinx 함수를 취한 알려진 점입니다.

3단계: pytorch로 완전히 연결된 간단한 네트워크 구축

class DNN(nn.Module):
    def __init__(self):
        super().__init__()
        layers =  [1,20,1]   #网络每一层的神经元个数,[1,10,1]说明只有一个隐含层,输入的变量是一个,也对应一个输出。如果是两个变量对应一个输出,那就是[2,10,1]
        self.layer1 = nn.Linear(layers[0],layers[1])  #用torh.nn.Linear构建线性层,本质上相当于构建了一个维度为[layers[0],layers[1]]的矩阵,这里面所有的元素都是权重
        self.layer2 = nn.Linear(layers[1],layers[2])
        self.elu = nn.ELU()       #非线性的激活函数。如果只有线性层,那么相当于输出只是输入做了了线性变换的结果,对于线性回归没有问题。但是非线性回归我们需要加入激活函数使输出的结果具有非线性的特征
    def forward(self,d):#d就是整个网络的输入
        d1 = self.layer1(d)
        d1 = self.elu(d1)#每一个线性层之后都需要加入一个激活函数使其非线性化。
        d2 = self.layer2(d1)#但是在网络的最后一层可以不用激活函数,因为有些激活函数会使得输出结果限定在一定的值域里。
        return d2

4단계: 일부 기본 매개 변수 결정 및 데이터 형식 변환

device = torch.device("cuda") #在跑深度学习的时候最好使用GPU,这样速度会很快。不要的话默认用cpu跑
epochs = 10000                #这是迭代次数,把所有的训练数据输入到网络里去就叫完成了一次epoch。
learningrate = 1e-4           #学习率,相当于优化算法里的步长,学习率越大,网络参数更新地更加激进。学习率越小,网络学习地更加稳定。
net = DNN().to(device=device) #网络的初始化
optimizer = torch.optim.Adam(net.parameters(), lr=learningrate)#优化器,不同的优化器选择的优化方式不同,这里用的是随机梯度下降SGD的一种类型,Adam自适应优化器。需要输入网络的参数以及学习率,当然还可以设置其他的参数
mseloss  = nn.MSELoss()      #损失函数,这里选用的是MSE。损失函数也就是用来计算网络输出的结果与对应的标签之间的差距,差距越大,说明网络训练不够好,还需要继续迭代。
MinTrainLoss = 1e10          
train_loss =[]               #用一个空列表来存储训练时的损失,便于画图
pt_x_train = torch.from_numpy(np.array(x_train)).to(device=device,dtype = torch.float32).reshape(-1,1)  #这里需要把我们的训练数据转换为pytorch tensor的类型,并且把它变成gpu能运算的形式。
pt_y_train = torch.from_numpy(np.array(y_train)).to(device=device,dtype = torch.float32).reshape(-1,1) #reshap的目的是把维度变成(25,1),这样25相当于是batch,我们就可以一次性把所有的点都输入到网络里去,最后网络输出的结果也不是(1,1)而是(25,1),我们就能直接计算所有点的损失
print(pt_x_train.dtype)
print(pt_x_train.shape)

5단계: 네트워크 훈련 과정

start = time.time()
start0=time.time()
for epoch in range(1,epochs+1):
    net.train()    #net.train():在这个模式下,网络的参数会得到更新。对应的还有net.eval(),这就是在验证集上的时候,我们只评价模型,并不对网络参数进行更新。
    pt_y_pred = net(pt_x_train) #将tensor放入网络中得到预测值
    loss = mseloss(pt_y_pred,pt_y_train)  #用mseloss计算预测值和对应标签的差别
    optimizer.zero_grad()      #在每一次迭代梯度反传更新网络参数时,需要把之前的梯度清0,不然上一次的梯度会累积到这一次。
    loss.backward()  # 反向传播
    optimizer.step() #优化器进行下一次迭代
    if epoch % 10 == 0:#每10个epoch保存一次loss
        end = time.time()
        print("epoch:[%5d/%5d] time:%.2fs current_loss:%.5f"
          %(epoch,epochs,(end-start),loss.item()))
        start = time.time()
    train_loss.append(loss.item())
    if train_loss[-1] < MinTrainLoss:
        torch.save(net.state_dict(),"model.pth") #保存每一次loss下降的模型
        MinTrainLoss = train_loss[-1]
end0 = time.time()
print("训练总用时: %.2fmin"%((end0-start0)/60)) 

 훈련 과정은 위와 같으며, 여기서 설정한 시간은 분을 제외하고는 비교적 간단하며, 이후 시간은 base 60 시스템에 따라 지정되지 않습니다.

6단계: 손실 감소 확인

plt.plot(range(epochs),train_loss)
plt.xlabel("epoch")
plt.ylabel("loss")

컨버전스가 여전히 비교적 양호함을 알 수 있다.

7단계: 네트워크 모델 가져오기, 검증 데이터 입력 및 결과 예측 

x_test = np.linspace(-np.pi,np.pi).astype(np.float32)
pt_x_test = torch.from_numpy(x_test).to(device=device,dtype=torch.float32).reshape(-1,1)
Dnn = DNN().to(device)
Dnn.load_state_dict(torch.load("model.pth",map_location=device))#pytoch 导入模型
Dnn.eval()#这里指评价模型,不反传,所以用eval模式
pt_y_test = Dnn(pt_x_test) 
y_test = pt_y_test.detach().cpu().numpy()#输出结果torch tensor,需要转化为numpy类型来进行可视化
plt.scatter(x_train,y_train,c="r")
plt.plot(x_test,y_test)

여기서 빨간색 점은 훈련 데이터이고 파란색 점은 우리의 예측 곡선으로 전체적인 적합도가 상대적으로 좋은 것을 알 수 있습니다.

위의 내용은 pytorch로 구축된 간단한 완전 연결 네트워크의 기본 단계입니다. 초보자에게 도움이 되었으면 합니다!

Supongo que te gusta

Origin blog.csdn.net/qq_43397591/article/details/127306662
Recomendado
Clasificación