多层感知机[从0实现]

1.个人理解

        对于无限多的模型,显然不可能所有模型均为线性关系,多层感知机正是为了克服线性回归的局限性而引入的,同时多层感知机引入了隐藏层,也可以称作中间层,对隐藏层使用激活函数来破坏线性关系。激活函数一定用在隐藏层,输入数据和输出数据均不使用激活函数。

        激活函数目前遇到三种:

        (1).ReLU激活函数:  ReLU(x)=max(0,x)

        (2).sigmoid激活函数:  sigmoid(x)=\frac{1}{1+e^{-x}}

        (3).tanh激活函数:  tanh(x)=\frac{1-e^{-2x}}{1+e^{-2x}}

        本多层感知机的实现和上一个softmax regression的实现过程基本一致,最大的区别体现在net中加入了隐藏层,并且对隐藏层使用了激活函数进行处理。

2.数字标签转换为文本标签

#导出文本标签
def get_labels(labels):
    #返回文本标签
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[i] for i in labels]

3.定义激活函数

#激活函数
def relu(X):
    a = torch.zeros_like(X)
    return torch.max(a,X)

         torch.zeros_like(x),返回与x的shape一致的全0张量

4.定义softmax函数

#softmax函数
def softmax(X):
    X_exp = torch.exp(X)
    X_exp_sum = X_exp.sum(axis=1,keepdims=True)
    return X_exp/X_exp_sum

5.定义网络

#net
def net(X,W1,W2,b1,b2):
    X = X.reshape(-1,W1.shape[0])
    H = relu(X@W1+b1) #hidden
    return softmax(H@W2+b2) #输出

        对x进行reshape,一行表示一个数据。

        隐藏层使用激活函数,最终输出需经过softmax函数处理

6.交叉熵损失

#交叉熵损失
def cross(y_hat,y):
    loss = -torch.log(y_hat[range(len(y_hat)),y])
    return loss

        y_hat [ range ( len ( y_hat ) ) , y ]:二维索引检索真实标签的预测概率

7.批量梯度下降

#批量梯度下降
def bgd(W1,W2,b1,b2,lr,batch_size):
    with torch.no_grad():
        W1 -= lr * W1.grad/batch_size
        W2 -= lr * W2.grad/batch_size
        b1 -= lr * b1.grad/batch_size
        b2 -= lr * b2.grad/batch_size
        W1.grad.zero_()
        W2.grad.zero_()
        b1.grad.zero_()
        b2.grad.zero_()
    return W1,W2,b1,b2

8.正确率函数

#准确率评价accuracy
def accuracy(y_hat,y):
    y_hat = y_hat.argmax(axis=1) #获取每行最大元素的索引
    test = (y_hat == y)
    return test.sum()/len(y)

9.训练

#训练
def train(train_pic,epoch,lr,batch_size,train_W1,train_W2,train_b1,train_b2):
    for i in range(epoch):
        for X,y in train_pic:
            y_hat = net(X,train_W1,train_W2,train_b1,train_b2)
            loss = cross(y_hat,y)
            loss.sum().backward()
            train_W1,train_W2,train_b1,train_b2 = bgd(train_W1,train_W2,train_b1,train_b2,lr,batch_size) #批量梯度下降
            acc = accuracy(y_hat,y)
        print('epoch '+str(i+1)+', accuracy is :',acc)
        print('loss sum is :',loss.sum())
    return train_W1,train_W2,train_b1,train_b2

10.预测

#预测
def predict(test_pic,final_W1,final_W2,final_b1,final_b2):
    for X,y in test_pic:
        y_hat = net(X,final_W1,final_W2,final_b1,final_b2)
        pre = y_hat.argmax(axis=1) #确定每行最大元素的index
        print('\n')
        print('predict labels :',get_labels(pre))
        print('true labels  :',get_labels(y))
        print('accuracy is :',accuracy(y_hat,y))

11.封装

#MLP
def MLP():
    batch_size = 256
    train_pic, test_pic = d2l.load_data_fashion_mnist(batch_size)
    input_size = 784
    output_size = 10  # 输出10个类别
    hidden_size = 128
    W1 = torch.normal(0,0.1,size=(input_size,hidden_size),requires_grad=True)
    W2 = torch.normal(0,0.1,size=(hidden_size,output_size),requires_grad=True)
    b1 = torch.normal(0,0.1,size=(1,hidden_size),requires_grad=True)
    b2 = torch.normal(0,0.1,size=(1,output_size),requires_grad=True)
    epoch = 50
    lr = 0.1
    final_W1,final_W2,final_b1,final_b2 = train(train_pic,epoch,lr,batch_size,W1,W2,b1,b2)
    predict(test_pic,final_W1,final_W2,final_b1,final_b2)
    return

12.拟合并预测

#拟合
MLP()

13.运行结果

 

        经过10个epoch的训练,训练集上的正确率可以保持在0.9左右

        在测试集上的表现也较为理想 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值