Pytorch -> 回归与分类

y预测 = w*x+b+eps

eps ~ N (0.01,1)

loss = Σ(y预测-y)^2

w’ = w-lr*▽loss/▽w(梯度/导数)

结果:w、b

回归问题

def compute_error(w,b,points):
    totalError = 0
    # [[x,y],[x,y],...]
    for i in range(len(points)):
        x = points[i,0]
        y = points[i,1]
        totalError += (y-w*x-b)**2
    return totalError/float(len(points))

def step_gradient(w,b,lr,points):
    w_grad = 0
    b_grad = 0
    N = float(len(points))
    for i in range(len(points)):
        x = points[i,0]
        y = points[i,1]
        w_grad += -2/N*(y-w*x-b)*x
        b_grad += -2/N*(y-w*x-b)
    w = w - lr * w_grad
    b = b - lr * b_grad
    return [w,b]

# 主函数只需要进行梯度下降,得到w,b与初始w,b对比即可
def grad_descent(w,b,lr,points,iter):
    for i in range(iter):
        w,b = step_gradient(w,b,lr,np.array(points))
    return [w,b]

分类问题

[28,28] -> [[784]]

训练:

y预测 = W3*{W2[W1*X+b1]+b2}+b3(+RELU)

loss = Σ(y预测-y_onehot)^2

测试:

net(x)

argmax(y预测)

acc = Σcorrect/total

结果:y预测,由[b,10]变成[b]的最终结果,优化后的net

import  torch
from    torch import nn
from    torch.nn import functional as F    # F提供各种函数
from    torch import optim

import  torchvision
from    matplotlib import pyplot as plt

from    utils import plot_image, plot_curve, one_hot

import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'    # 解决报错

batch_size = 512

# step1. load dataset
train_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data', train=True, download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                    # 正则化,控制在0~1
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist_data/', train=False, download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size, shuffle=False)

x, y = next(iter(train_loader))
print(x.shape, y.shape, x.min(), x.max())
plot_image(x, y, 'image sample')



class Net(nn.Module):
    # 从父类nn.Module里通过super(子类,self)调用init
    def __init__(self):
        super(Net, self).__init__()

        # xw+b
        self.fc1 = nn.Linear(28*28, 256)
        self.fc2 = nn.Linear(256, 64)
        self.fc3 = nn.Linear(64, 10)

    def forward(self, x):
        # x: [b, 1, 28, 28]
        # h1 = relu(xw1+b1)
        x = F.relu(self.fc1(x))
        # h2 = relu(h1w2+b2)
        x = F.relu(self.fc2(x))
        # 不需要relu
        # h3 = h2w3+b3
        x = self.fc3(x)

        return x



net = Net()
# [w1, b1, w2, b2, w3, b3]
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)


train_loss = []
# 迭代3次
for epoch in range(3):

    for batch_idx, (x, y) in enumerate(train_loader):

        # size(0)相当于b,总数不变,所以数为28*28
        # x: [b, 1, 28, 28], y: [512]
        # 打平:[b, 1, 28, 28] => [b, 784]
        x = x.view(x.size(0), 28*28)
        # => [b, 10]
        out = net(x)
        # [b, 10]
        y_onehot = one_hot(y)

        # loss和optimizer组合
        # loss = mse(out, y_onehot)
        loss = F.mse_loss(out, y_onehot)
        # 清零梯度
        optimizer.zero_grad()
        # 计算梯度
        loss.backward()
        # 更新梯度:w' = w - lr*grad
        optimizer.step()
        # 绘图需要,item()提取tensor的值
        train_loss.append(loss.item())

        if batch_idx % 10==0:
            print(epoch, batch_idx, loss.item())

plot_curve(train_loss)
# we get optimal [w1, b1, w2, b2, w3, b3]

# loss不是最后的衡量指标,准确度是
total_correct = 0
# 不考虑打印第几次batch
for x,y in test_loader:
    x  = x.view(x.size(0), 28*28)
    out = net(x)
    # out: [b, 10] => pred: [b]
    pred = out.argmax(dim=1)
    # y的格式:<class 'torch.Tensor'>
    # item()取值
    correct = pred.eq(y).sum().float().item()
    total_correct += correct

total_num = len(test_loader.dataset)
acc = total_correct / total_num
print('test acc:', acc)

x, y = next(iter(test_loader))
out = net(x.view(x.size(0), 28*28))
pred = out.argmax(dim=1)
plot_image(x, pred, 'test')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值