<jupyter_start><jupyter_text>$MNIST$ $数据的维度$ 线性组合$pred = W_3 * \{W_2[W_1X+b_1]+b_2\}+b_3$ 问题：无法进一步拟合复杂的问题<jupyter_code># Relu

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist

%matplotlib inline
%config InlineBackend.figure_format = 'svg'

def Relu():
    x = np.linspace(-2,2,100)
    y = [max(0,i) for i in x]
    fig = plt.figure(figsize=(6, 4))
    ax = axisartist.Subplot(fig, 111)  
    fig.add_axes(ax)
    ax.axis[:].set_visible(False)
    ax.axis["x"] = ax.new_floating_axis(0,0)
    ax.axis["x"].set_axisline_style("->", size = 0.5)
    ax.axis["y"] = ax.new_floating_axis(1,0)
    ax.axis["y"].set_axisline_style("-|>", size = 0.5)
    ax.axis["x"].set_axis_direction("top")
    ax.axis["y"].set_axis_direction("right")
    plt.plot(x,y,c = 'blue',linewidth=3,label = 'Relu = max(0,1)')
    plt.legend()
Relu()<jupyter_output><empty_output><jupyter_text>解决：引入激活函数 激活函数$Relu(x) = max(0,x)$ 非线性组合$H1=Relu(XW_1+b_1)\space$ $H2=Relu(XW_2+b_2)\space$ $H3=f(XW_3+b_3)$$pred = ^{\sigma}W_3 * \{^{\sigma}W_2[^{\sigma}W_1X+b_1]+b_2\}+b_3$ 梯度下降$objective = \sum{(pred - Y)}^2$ ----  手写数字实战步骤： 1.加载图片 2.建立模型 3.训练 4.预测<jupyter_code>import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
# 辅助函数

def plot_curve(data):
    fig = plt.figure()
    plt.plot(range(len(data)),data,color = 'blue')
    plt.legend(['loss'],loc = 'upper right')
    plt.xlabel('step')
    plt.ylabel('loss')
    
def plot_image(img,label,name):
    fig = plt.figure()
    for i in range(6):
        plt.subplot(2,3,i + 1)
        plt.tight_layout()
        plt.imshow(img[i][0] * 0.3081 + 0.1307,cmap = 'gray',interpolation = 'none')
        plt.title('{}:{}'.format(name,label[i].item()))
        plt.xticks([])
        plt.yticks([])
        
def one_hot(label, depth=10):
    out = torch.zeros(label.size(0), depth)
    idx = torch.LongTensor(label).view(-1, 1)
    out.scatter_(dim=1, index=idx, value=1)
    return out
# Step1.
# 加载数据

batch_size = 64
train_loader = torch.utils.data.DataLoader(torchvision.datasets.MNIST('datasets/mnist_data',
                train=True,
                download=True,
                transform=torchvision.transforms.Compose([
                torchvision.transforms.ToTensor(),                       # 数据类型转化
                torchvision.transforms.Normalize((0.1307, ), (0.3081, )) # 数据归一化处理
    ])), batch_size=batch_size,shuffle=True)

test_loader = torch.utils.data.DataLoader(torchvision.datasets.MNIST('datasets/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)
plot_image(x,y,'image smaple')
# Step2.
# 构建网络

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.fc1 = nn.Linear(28*28,256)
        self.fc2 = nn.Linear(256,64)
        self.fc3 = nn.Linear(64,10)
    
    def forward(self,x):
        # img : [batch,1,28,28]
        # x : [batch,784]
        # h1 = relu(xw1 + b1)
        x = F.relu(self.fc1(x))
        # h2 = relu(h1w2 + b2)
        x = F.relu(self.fc2(x))
        # h3 = h2w3 + b3
        x = self.fc3(x)
        
        return x
# step3.
# 训练训练样本

net = Net()

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

train_loss = []
for epoch in range(3):
    for batch_idx,(x,y) in enumerate(train_loader):
        # x : [batch,1,28,28] y:[batch]
        # flatten [batch,1,28,28] - > [batch,feature]
        # x : [batch,784]
        x = x.view(x.size(0),28*28)
        out = net(x)
        
        # one-hot
        y_onehot = one_hot(y)
        
        # loss : mse(out,y_onehot)
        loss = F.mse_loss(out,y_onehot)
        
        # 清零梯度
        optimizer.zero_grad()
        
        # 计算梯度
        loss.backward()
        
        # 更新梯度
        # w' = w - lr * grad
        optimizer.step()
        
        train_loss.append(loss.item())
        
        if batch_idx % 10 == 0:
            print(f"epoch:{epoch} step:{batch_idx} loss:{loss.item()}")
plot_curve(train_loss)
# Step4.
# 测试集验证

total_correct = 0
for x,y in test_loader:
    x =  x.view(x.size(0),28*28)
    out = net(x)
    # out : [batch,10] - > pred : [batch]
    y_pred = out.argmax(dim=1)
    correct = y_pred.eq(y).sum().float().item()
    total_correct += correct
total_num = len(test_loader.dataset)
print(f"accuracy : {total_correct/total_num}")
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')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1702039117769455, 'fraction_numerical': 0.03870162297128589, 'mean_word_length': 2.71483771251932, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '309868', 'license': 'MIT', 'n_tokens_mistral': 2070, 'n_tokens_neox': 2040, 'n_words': 291, 'path': 'Pytorch/Pytorch_learn_by_dragen1860/lesson04-手写数字问题.ipynb', 'repo_name': 'tsuirak/skills', 'size': '4806'}