能完成二分类问题
问题:
模型训练采用X*W + b训练出模型,对数据只进行了一层处理,也就是说训练出来的模型仅是个线性模型,它无法解决XOR问题,所以模型在训练效果上,识别的正确率会低一些
实现:
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(
num_inputs, num_outputs, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1]
def net(X):
X = X.reshape((-1, num_inputs))
H = X@W1 + b1 # 这里“@”代表矩阵乘法
return H # (H@W2 + b2)
loss = nn.CrossEntropyLoss() # 多类别分类问题的损失函数
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
if __name__ == '__main__':
num_epochs = 10
cnt = 1
for i in range(num_epochs):
X, Y = d2l.train_epoch_ch3(net, train_iter, loss, updater)
print("训练次数: " + str(cnt))
cnt += 1
print("训练损失: {:.4f}".format(X)) #训练损失是用训练数据集测得
print("训练精度: {:.4f}".format(d2l.evaluate_accuracy(net, test_iter))) # 训练精度是用测试数据集测得
print(".................................")
效果:
可以看出线性模型的识别损失和正确率还有待提升
功能:
能利用隐藏层,实现非线性模型
主要利用激活函数,将上一层输出,转入下一层输入,以完成模型的去线性
激活函数必须用非线性,否则最后模型W1 * W2仍是一个线性模型
常用的激活函数:
激活函数不用做指数函数,所以会很快
实现:
import torch
from torch import nn
from d2l import torch as d2l
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) # 获取训练集,检测集
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]
def relu(X): # 激活函数
a = torch.zeros_like(X)
return torch.max(X, a)
def net(X):
X = X.reshape((-1, num_inputs)) # 将28 * 28图片拉成一维度784
H = relu(X @ W1 + b1)
return (H @ W2 + b2)
loss = nn.CrossEntropyLoss()
num_ecophs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr = lr)
if __name__ == '__main__':
num_epochs = 10
cnt = 1
for i in range(num_epochs):
X, Y = d2l.train_epoch_ch3(net, train_iter, loss, updater)
print("训练次数: " + str(cnt))
cnt += 1
print("训练损失: {:.4f}".format(X)) #训练损失是用训练数据集测得
print("训练精度: {:.4f}".format(d2l.evaluate_accuracy(net, test_iter))) # 训练精度是用测试数据集测得
print(".................................")
效果:
简介实现:
import torch
from torch import nn
from d2l import torch as d2l
# 数据降维度,第一层,隐藏层用RELU,后面是第二个层
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 10))
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std = 0.01)
net.apply(init_weights)
batch_size, lr, num_epochs = 256, 0.01, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr = lr)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
if __name__ == '__main__':
num_epochs = 10
cnt = 1
for i in range(num_epochs):
X, Y = d2l.train_epoch_ch3(net, train_iter, loss, trainer)
print("训练次数: " + str(cnt))
cnt += 1
print("训练损失: {:.4f}".format(X)) #训练损失是用训练数据集测得
print("训练精度: {:.4f}".format(d2l.evaluate_accuracy(net, test_iter))) # 训练精度是用测试数据集测得
print(".................................")
多层感知机,突破了单层感知机用线性模型去识别事物的瓶颈
为什么非线性模型要比非线性模型好:
非线性模型相对于线性模型的优势主要在于其更强大的表达能力和适应性:
能够处理更复杂的关系:
非线性模型能够表示更复杂的特征和模式,因为它们具有更灵活的函数形式。在现实世界的数据中,很多问题并不是简单的线性关系,而是包含了各种复杂的非线性关系。非线性模型可以更好地拟合这些非线性数据,并提供更准确的预测能力。更好地适应复杂任务:
在面对复杂任务时,非线性模型能够更好地捕捉数据中的高阶特征和交互作用。例如,图像识别、语音识别、自然语言处理等领域常常需要处理复杂的数据结构,而这些数据结构往往包含了大量的非线性信息。非线性模型能够更好地理解这些数据并进行有效的建模。更好地处理特征的组合效应:
非线性模型能够捕获特征之间的复杂组合效应。线性模型只能表示特征的线性组合,而非线性模型可以处理特征之间的乘积、平方、高次幂等非线性组合,从而更全面地考虑特征之间的关系。虽然非线性模型在很多情况下具有更强大的建模能力,但也需要注意过拟合的问题。过于复杂的模型可能会在训练数据上表现得很好,但在未见过的数据上泛化能力可能较差。因此,在选择模型时需要平衡模型的复杂度和泛化能力。
多层感知机与softmax回归的区别:
softmax回归本质上对模型的线性输出进行了处理,将其转换成正太概率分布形式,便于交叉函数的预测,本质上其模型仍是线性模型