【机器学习】PyTorch搭建线性网络结构示例

简单线性回归问题

import torch

# 数据集:(1, 2), (2, 4), (3, 6)
x_data = torch.Tensor([[1.0], [2.0], [3.0]]) # 3×1列矩阵
y_data = torch.Tensor([[2.0], [4.0], [6.0]])

# 定义线性网络结构
class LinearModel(torch.nn.Module):
    # 构造函数
    def __init__(self):
        # 调用父类的构造函数,形式固定,记住就行
        super(LinearModel, self).__init__()
        # torch.nn.Linear(每一个输入样本的维数, 每一个输入样本的维数, bias=True)。继承自Module,也可以进行反向传播
        self.linear = torch.nn.Linear(1, 1)
    # 前向传播时执行的计算
    # 用Module构造的对象会自动构建计算图,不需要写backward
    def forward(self, x):
        # 运算符()重载
        y_pred = self.linear(x)
        return y_pred

model = LinearModel()

# MSELoss同样继承于Module
# reduction='sum'表示不求1/N
# reduction='mean'表示求1/N
criterion = torch.nn.MSELoss(reduction='sum')

# parameters()会自动寻找modules所有成员中的权重(已标记require_grad的变量)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

#【train】
for epoch in range(100):
    # 预测过程
    y_pred = model(x_data)
    # 构造好loss层后,就会自动生成计算图,可以自动求导
    loss = criterion(y_pred, y_data)
    # 需要加item(),否则输出的是Tensor格式
    print(epoch, loss.item())
    
    # 在反向传播之前,需要先梯度归零
    optimizer.zero_grad()
    # 反向传播
    loss.backward()
    # 更新
    optimizer.step()

print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())

# 【test】
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)

加载数据集模板:

# Dataset是抽象类,不能实例化。由Dataset继承出的类可以实例化。
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
# Dataset是抽象类,不能实例化。由Dataset继承出的类可以实例化。
class DiabetesDataset(Dataset):
    # 初始化
    def __init__(self):
        pass
    # 目标:通过dataset[index]可以实现索引
    def __getitem__(self, index):
        pass
    # 目标:通过len(dataset)可以返回长度
    def __len__(self):
        pass
# 实例化
dataset = DiabetesDataset()
# 初始化loader
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)

回归示例(加载自己数据集):

import torch
import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

# xy = np.loadtxt('./diabetes.csv.gz', delimiter=',', dtype=np.float32)
# x_data = torch.from_numpy(xy[:, :-1])
# y_data = torch.from_numpy(xy[:, [-1]])

# Dataset是抽象类,不能实例化。由Dataset继承出的类可以实例化。
class DiabetesDataset(Dataset):
    # 初始化
    def __init__(self, filepath):
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])
    # 目标:通过dataset[index]可以实现索引
    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]
    # 目标:通过len(dataset)可以返回长度
    def __len__(self):
        return self.len

dataset = DiabetesDataset('./diabetes.csv.gz')
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)

# 定义模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(8, 20)
        self.linear2 = torch.nn.Linear(20, 1)
        self.sigmoid = torch.nn.Sigmoid()
    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        return x

model = Model()

# BCE: Binary Cross Entrophy
# reduction='sum'表示不求1/N
# reduction='mean'表示求1/N
criterion = torch.nn.BCELoss(reduction='mean')

# parameters()会自动寻找modules所有成员中的权重(已标记require_grad的变量)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

# 在Windows编译需要将使用loader的地方封装在函数内,否则会报错。Ubuntu没有这个问题。
# 记住把epoch循环放在main函数内即可
if __name__ == '__main__':
#【train】
    for epoch in range(100):
        # 0表示从train_loader的指定索引0开始
        for i, data in enumerate(train_loader, 0):
            # 1. 准备数据
            inputs, labels = data
            # 2. 前向传播
            y_pred = model(inputs)
            # 构造好loss层后,就会自动生成计算图,可以自动求导
            loss = criterion(y_pred, labels)
            # 需要加item(),否则输出的是Tensor格式
            print(epoch, loss.item())
            # 3. 反向传播
            # 在反向传播之前,需要先梯度归零
            optimizer.zero_grad()
            loss.backward()
            # 4. 更新
            optimizer.step()

softmax回归示例(MNIST数据集)

import torch
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader

transform = transforms.Compose([
    # 将PIL图像H*W*C转为torch的C*H*W格式
    transforms.ToTensor(),
    # 归一化,均值和标准差(这里的数值是根据数据集算出来的)
    transforms.Normalize((0.1307, ), (0.3081, ))
])

# 下载MNIST数据集
train_set = torchvision.datasets.MNIST(root='./dataset/mnist', train=True, transform=transform, download=True)
test_set  = torchvision.datasets.MNIST(root='./dataset/mnist', train=False, transform=transform, download=True)

train_loader = DataLoader(dataset=train_set, batch_size=64, shuffle=True, num_workers=2)
test_loader =  DataLoader(dataset=test_set, batch_size=64, shuffle=True, num_workers=2)

# 定义模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(784, 512)
        self.linear2 = torch.nn.Linear(512, 256)
        self.linear3 = torch.nn.Linear(256, 128)
        self.linear4 = torch.nn.Linear(128, 64)
        self.linear5 = torch.nn.Linear(64, 10)
        self.activate = torch.nn.ReLU()
    def forward(self, x):
        # x.view(x.shape[0], -1)表示将batch_size*1*28*28格式转为batch_size*784格式
        x = self.activate(self.linear1(x.view(x.shape[0], -1)))
        x = self.activate(self.linear2(x))
        x = self.activate(self.linear3(x))
        x = self.activate(self.linear4(x))
        x = self.activate(self.linear5(x))
        return x

model = Model()

# reduction='sum'表示不求1/N
# reduction='mean'表示求1/N
criterion = torch.nn.CrossEntropyLoss(reduction='mean')

# parameters()会自动寻找modules所有成员中的权重(已标记require_grad的变量)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.5)

# 在Windows编译需要将使用loader的地方封装在函数内,否则会报错。Ubuntu没有这个问题。
# 记住把epoch循环放在main函数内即可
if __name__ == '__main__':
    #【train】
    for epoch in range(1):
        running_loss = 0.0
        # 0表示从train_loader的指定索引0开始
        for i, data in enumerate(train_loader, 0):
            # 1. 准备数据
            inputs, labels = data
            # 2. 前向传播
            y_pred = model(inputs)
            # 构造好loss层后,就会自动生成计算图,可以自动求导
            loss = criterion(y_pred, labels)
            # 3. 反向传播
            # 在反向传播之前,需要先梯度归零
            optimizer.zero_grad()
            loss.backward()
            # 4. 更新
            optimizer.step()
            
            # 每300个batch输出一次loss
            running_loss += loss.item()
            if i % 300 == 299:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 300))
                running_loss = 0.0
    # 【test】
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            inputs, labels = data
            y_pred = model(inputs)
            # 沿着第1个维度(行是第0,列是第1)找最大值
            _, predicted = torch.max(y_pred, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set: %d %%' % (100 * correct / total))

卷积层和池化层使用方法:

import torch

in_channels, out_channels = 5, 10
width, height = 100, 100
kernel_size = 3
batch_size = 1

input = torch.randn(batch_size, in_channels, width, height)

conv_layer = torch.nn.Conv2d(in_channels, out_channels, padding=1, stride=2, kernel_size=kernel_size, bias=False)
output = conv_layer(input)
print(input.size())
print(output.size())
print(conv_layer.weight.size())

maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2)
output = maxpooling_layer(input)
print(input.size())
print(output.size())

定义CNN示例:

# 定义模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
        self.pooling = torch.nn.MaxPool2d(2)
        self.fc = torch.nn.Linear(320, 10)
        self.activate = torch.nn.ReLU()
    def forward(self, x):
        # x.size()表示batch_size*C*H*W格式,x.size(0)表示batch_size
        batch_size = x.size(0)
        x = self.conv1(x)
        x = self.pooling(x) # ReLU和pooling先后顺序都行
        x = self.activate(x)
        x = self.conv2(x)
        x = self.pooling(x)
        x = self.activate(x)
        x = x.view(batch_size, -1) # 把2维数据展平
        x = self.fc(x)
        return x

用cuda的方法:

# 1. 把模型放入gpu
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
#2. 把数据放入gpu
for epoch in range(20):
    for i, data in enumerate(train_loader, 0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quentin_HIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值