Pytorch / FNN经典案例代码解析

 RNN实现原理可参考http://t.csdnimg.cn/ReYXS

 定义网络可参考http://t.csdnimg.cn/IZaEG

# This is a sample Python script.
import numpy as np
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.


import torch

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")


import numpy as np
import torch
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn


# Prepare the dataset
class DiabetesDateset(Dataset):
    # 加载数据集
    def __init__(self, filepath):  #构造函数进行定义和初始化,创建对象时自动调用
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32, encoding='utf-8')

        self.len = xy.shape[0]  # shape[0]是矩阵的行数,shape[1]是矩阵的列数
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])

    # 获取数据索引
    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]

    # 获得数据总量
    def __len__(self):
        return self.len


dataset = DiabetesDateset('diabetes.csv')

train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)  # num_workers为多线程
 #Dataloader是一个迭代器,当传入一个Dataset对象,它会根据参数batch_size的值生成一个batch数据,实现多线程、数据打乱等处理。

# Define the model
class FNNModel(torch.nn.Module): #定义网络;通过继承torch.nn.Module 类来实现扩展;在这种情况下,只需要重新实现__init__和forward函数就行。
    def __init__(self): #也可以在这个括号中设置参数,如input_size,hidden_size,output_size,num_layers)
        super(FNNModel, self).__init__()
        self.linear1 = nn.Linear(8, 6)  # 输入数据的特征有8个,也就是有8个维度,随后将其降维到6维
        self.linear2 = nn.Linear(6, 4)  # 6维降到4维
        self.linear3 = nn.Linear(4, 2)  # 4维降到2维
        self.linear4 = nn.Linear(2, 1)  # 2维降到1维
        self.sigmoid = nn.Sigmoid()  # 可以视其为网络的一层,而不是简单的函数使用
#nn.linear(in_features(int类型,输入的神经元个数/输入的通道数) ,out_features(输出的神经元个数/输出的通道数),bias(bool类型,是否含有偏置))
    def forward(self, x): #向前传播
        x = self.sigmoid(self.linear1(x)) #sigmoid是激活函数的一种,它会将样本值映射到0到1之间。
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        x = self.sigmoid(self.linear4(x))
        return x

#调用网络
model = FNNModel().to(device) #在这里将运行环境转为cuda

#定义标准和优化器
criterion = nn.BCELoss(reduction='mean')
# nn.BCELoss函数用来计算目标值和预测值之间的二进制交叉熵损失函数。
#reduction='none',直接返回向量形式的loss
#reduction='sum' ,返回loss之和
#reduction='mean',返回loss的平均值
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) #优化
#优化是在每个循环步骤中调整模型参数以减小模型误差的过程。优化算法定义了这个过程是如何执行的。所有优化算法都风筝在优化器对象optimizer中。
#这里使用的是SGD优化器,此外Pytorch中有许多不同的优化器,他们可以更好地使用不用类型的模型和数据。
#lr为Learning Rate学习率,表示在每个批次时间更新模型参数的程度。
# 较小的值会产生较慢的学习速度,而较大的值可能会导致训练期间出现不可预测的行为。

epoch_list = []
loss_list = []

# Training
if __name__ == '__main__':
    for epoch in range(100): #epoch为每个优化循环的迭代  #如果加大训练量loss会继续收敛
        # i是一个epoch中第几次迭代,一共756条数据,每个mini_batch为32,所以一个epoch需要迭代23次
        # data获取的数据为(x,y)
        loss_one_epoch = 0
        for i, data in enumerate(train_loader, 0): #一个batch有32行数据,这里的i表示这个epoch中第几个batch
            inputs, labels = data
            inputs = inputs.to(device)
            labels = labels.to(device)
            outputs = model(inputs) #向前传播
            loss = criterion(outputs, labels) #用求平均值的方式计算损失函数,将模型输出与真实标签lable进行比较
            loss_one_epoch += loss.item()  #统计这23个batch的损失总和,也是这次epoch里计算出的总损失

            optimizer.zero_grad() #清空上一层的梯度,如果不清空,梯度仍然和上一个batch有关
            loss.backward() #反向传播;产生新的梯度;根据损失函数,使用反向传播算法来更新网络中的权重和偏置,以最小化损失函数
            optimizer.step() #使用梯度下降等优化算法来更新网络中的参数
        loss_list.append(loss_one_epoch / 23) #计算每一个batch的平均计算损失
        epoch_list.append(epoch)
        print('Epoch[{}/{}],loss:{:.6f}'.format(epoch + 1, 100, loss_one_epoch / 23))
#
    # Drawing
    plt.plot(epoch_list, loss_list) #横轴为迭代次数,纵轴为平均损失
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.show() #展现图表
    #epoch只设置了100层,最终的loss在67%左右

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值