智能2112杨阳
一、目的
- 多层感知机的从零开始实现
- 多层感知机的简洁实现
二、环境
希冀平台
vscode
三、内容
1、多层感知机的从零开始实现
a.初始化模型参数
#为超参数的损失梯度分配内存
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
b.激活函数
#激活函数
def relu(x):
a = torch.zeros_like(x)
return torch.max(x, a)
c.定义模型
#模型
def net(x):
x = x.reshape((-1, num_inputs))
H = relu(x @ w1 + b1)#@为矩阵乘法
return (H @ w2 + b2)
d.损失函数
#损失函数
loss = nn.CrossEntropyLoss(reduction='none')
e.进行训练
num_epochs = 10
lr = 0.1
updater = torch.optim.SGD(params, lr = lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
2、多层感知机的简易实现
a.定义网络结构
#添加两个全连接层
net = nn.Sequential(nn.Flatten(),nn.Linear(784,256),nn.ReLU(),nn.Linear(256,10))
#Flatten是展平层,返回一个一维数组,来调整网络输入的形状
#第一层是隐含层,包含256个隐藏单元,并使用ReLu激活函数
#第一层后使用激活函数,然后第二层是输出层
b.定义初始化模型参数
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights);#将初始化函数apply在net中,即对每一层都经历一遍初始化函数即可完成初始化
c.损失函数及优化算法
batch_size,lr,num_epochs = 256,0.1,10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(),lr = lr)#定义优化算法为随机梯度下降
d.进行训练
train_iter,test_iter = load_data_fashion_mnist(batch_size)
train_ch3(net,train_iter,test_iter,loss,num_epochs, trainer)#训练函数
3、在 Kaggle 提交本教程的预测结果。观察一下,这个结果在 Kaggle 上能拿到什么样的分数?
Kaggle提交结果:
4、对照 𝐾 折交叉验证结果,不断修改模型(例如添加隐藏层)和调参,你能提高 Kaggle 上的分数吗?
def get_net():
net = nn.Sequential()
net.add(nn.Dense(218, activation="relu"), nn.Dense(1))
net.initialize()
return net
网络:增加一层隐藏层,该隐藏层的单元个数设置为218。
训练参数:k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64
交叉验证结果:5-fold validation: avg train rmse 0.048617, avg valid rmse 0.171843
分析:
(1)训练误差波动很大。需要采用更像的学习率。比如 lr = 0.05.
(2)train loss很小,但是 valid loss很大。说明过拟合。需要增大 weight_dacay。比如增大到100.
重新设置参数。再做一次训练。
网络:增加一层隐藏层,该隐藏层的单元个数设置为218。
训练参数:k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.05, 100, 64
交叉验证结果:5-fold validation: avg train rmse 0.081824, avg valid rmse 0.130623
在所有训练数据上的train rmse 0.083289
分析:
(1)train loss几乎没有波动。说明减小学习率有效果。
(2)valid loss 仍然大于train loss,说明存在过拟合。继续增大weight_decay后,发现train loss变大,valid loss几乎没有变化。
- 如果不使用本节中对连续数值特征的标准化处理,结果会有什么变化?
注释掉标准化处理的代码,得到结果如下:
如果不对连续数值特征进行标准化处理,可能会导致模型预测的偏差、收敛困难以及特征权重的不可解释性等问题。从而导致结果会很差。
四、总结
问题及解决方法:d2l包使用失败,下载轮子后重新pip安装成功
这次博客让我对多层感知机有了一定的了解和认识,训练多层感知机与训练线性回归模型非常相似:先读取数据,再定义模型和损失函数,然后使用优化算法训练模型。虽然学习了很多,但是仍然无法熟练运用多层感知机的相关知识,还需要加强对python的学习及相关知识的学习,总的来说收获满满。