from operator import truediv
import numpy as np
import torch
from torch.nn import CrossEntropyLoss
from torch.utils import data
from torch import nn
import d2l
import matplotlib.pyplot as plt
n_train,n_test,num_inputs=20,100,200
true_w,true_b=torch.ones((num_inputs,1))*0.01,0.5
def syntic_data(m,num_inputs,true_w,true_b):
    x=torch.normal(0,1,(m,num_inputs))
    y=torch.matmul(x,true_w)+true_b
    y+=torch.normal(0,1,(y.shape))
    return x,y
batch_size=5
train_feature,train_label=syntic_data(n_train,num_inputs,true_w,true_b)
test_feature,test_label=syntic_data(n_test,num_inputs,true_w,true_b)

train_iter=d2l.load_array((train_feature,train_label),batch_size,True)
test_iter=d2l.load_array((test_feature,test_label),batch_size,False)
def evaluate_loss(net,iter,loss):
    metric,n=0.0,0
    for x,y in iter:
        y_pred=net(x)
        l=loss(y_pred,y)
        metric+=l.sum().item()
        n+=y.numel()
    return metric/n
loss=nn.MSELoss()
def train_concise(wd):
    net=nn.Sequential(nn.Linear(num_inputs,1))
    for param in net.parameters():
        param.data.normal_()
    loss=nn.MSELoss()
    epochs=100
    lr=0.003
    trainer=torch.optim.SGD([{'params': net[0].weight,'weight_decay':wd},{'params':[net[0].bias]}],lr=lr)
    animator=d2l.Animator(xlabel='epoch',ylabel='loss',xlim=[5,epochs],yscale='log',legend=['train','test'])
    for epoch in range(epochs):
        for X,y in train_iter:
            trainer.zero_grad()
            l=loss(net(X),y)
            l.mean().backward()
            trainer.step()
        if (epoch+1) %5==0:
            animator.add(epoch+1,(evaluate_loss(net,train_iter,loss),evaluate_loss(net,test_iter,loss)))
    print('w的L2范数:', net[0].weight.norm().item())
train_concise(0)
plt.ioff()
plt.show(block=True)

Q1:之前没有加噪音,所以导致调不调权重衰退系数都不影响训练效果,这是因为如果没有噪音的话,几个点就可以学习的比较好了

Q2:调节x的方差,可以明显观察到test和train都会下降,这是因为方差大,信号强度越强,因为对于test来说,比较早的就可以掌握到规律,因此后期增加epoch也不会下降,但是对于train,可以继续学习噪声,因此loss会下降

Q3:为什么会有过拟合,所谓过拟合就是对于test来说,已经掌握了学习的规律了,不会有明显变化,但是对于train来说,还可以继续学习细节,但是对于新数据来说已经没有任何学习的意义了。

出现过拟合的原因就是,train数据比较小,但是维度大,而且x方差大,梯度下降的快,步伐大,下降的快,噪声比较大,所以后期train会学习噪音,loss会下降

说白了:模型复杂度太高,但是数据量又太小

更多推荐