pytorch入门(九):处理异或问题

10 篇文章 1 订阅
3 篇文章 0 订阅

1、什么是异或?

异或是一种二元运算&。
一位二进制数的&运算规则为:
    0 ^ 1 = 1
    1 ^ 0 = 1
    1 ^ 1 = 0
    0 ^ 0 = 0
提问:11&22 等于多少?
先把11化为5位二进制数,得到 ( 01011 ) 2 (01011)_2 (01011)2
再把22化为5位二进制数,得到 ( 10110 ) 2 (10110)_2 (10110)2
分别对5个二进制位进行^运算。
由于只有右边第二位有相同的1,其他各位都各不相同,
所以结果为, ( 11101 ) 2 (11101)_2 (11101)2,化为十进制得到29。

print('bin(11) =',bin(11))
print('bin(11) =',bin(22))
print('11^22 =', 11^22)

回答:结果为

bin(11) = 0b1011
bin(11) = 0b10110
11^22 = 29

2、异或是线性不可分的

把上面运算规则中等式左边的数字作为点的坐标,等式右边的数字作为点的类型,就有了两种类型的四个点,把它画到平面直角坐标系中如下图,
在这里插入图片描述
红色和蓝色代表点的类型。显然,无法找出一条直线将两类点分开,这就是说,这些点不是线性可分的。

3、用逻辑回归建模

用这四个点训练逻辑回归模型,看看能不能正确分类。

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score 

x = np.array([[0,1], [0,0], [1,0], [1,1]])
y = np.array([1, 0, 1, 0])

mm = LogisticRegression()
mm.fit(x,y)
y_hat = mm.predict(x)
acc = accuracy_score(y_hat, y)
print(acc)

运行结果如下,准确率只有0.5。

0.5

4、用简单神经网络处理异或

如何用pytorch建立神经网络?
对于训练数据(x, y),先确定神经网络的结构,然后迭代执行下列操作,
(1)由正向传播forward(x)计算预测结果y_hat;
(2)用损失函数loss_function(y_hat, y)计算偏差;
(3)由反向传播backward()计算模型参数的导数
(4)用优化函数step()来更新模型参数。
每一步都力求减小偏差。最后评估模型的性能。
下面准备代码。
(1)先确定网络结构如下,

(2)生成500个数据点,line 8;
(3)计算这些点的类型,使之成为异或(交叉)形状,line 9;
(4)设计类mm_cls,定义神经网络。这个类要继承自Module,以便于提取模型参数调用mm.parameters()即可。__init__定义模型结构,其中l2可放置Sigmoid函数,这里用一个平方函数也能起到类似作用。forward用于计算预测结果,line 11-26;
(5)定义损失函数。分类问题可用交叉熵,这里使用了更容易理解的均方差,line 28;
(6)定义优化函数,调用Adam,它是最为常用的优化算法之一,line 29;
(7)开始训练模型,训练过程主要由5个函数,forward、loss_fun、backward、step、zero_grad组成,line 31-41;
(8)取得真实结果和预测结果,把结果变为50个0或者1,line 43-44;
(9)计算准确率,line 46-47;
(10)绘制真实结果和预测结果。

代码如下,

import torch
import torch.nn as nn
from sklearn.metrics import accuracy_score 

torch.manual_seed(1234)

n = 500
x = torch.rand(n, 2)*2 - 1
y = torch.Tensor([[1,0] if k[0]*k[1]>0 else [0, 1] for k in x])

class mm_cls(torch.nn.Module):
    def __init__(self):
        super(mm_cls, self).__init__()
        self.l1 = torch.nn.Linear(2, 5)
        self.l2 = lambda x: x**2
        self.l3 = torch.nn.Linear(5, 2)
        self.l4 = nn.Softmax(dim=1)
        
    def forward(self, x):
        x1 = self.l1(x)
        x2 = self.l2(x1)
        x3 = self.l3(x2)
        x4 = self.l4(x3)
        return x4
    
mm = mm_cls()

loss_fun = torch.nn.MSELoss()
optimizer = torch.optim.Adam(mm.parameters(),lr=0.001)

epochs = 2000
for i in range(epochs):
    y_hat = mm.forward(x)

    loss = loss_fun(y_hat, y)
    loss.backward()
    optimizer.step()
    if i % 100 == 0:
        print('step = %4d'%i, 'loss = %.4e'%loss.item())

    optimizer.zero_grad

y_hat = y_hat[:,0] < y_hat[:,1]
y = y[:,0] < y[:,1]

acc = accuracy_score(y_hat, y)
print('acc = %f' % acc)

import matplotlib.pyplot as plt

plt.subplot(121)
plt.plot(x[y==1, 0], x[y==1, 1], 'om')
plt.plot(x[y==0, 0], x[y==0, 1], 'ob')
plt.title('original')

plt.subplot(122)
plt.lot(x[y_hat==1, 0], x[y_hat==1, 1], 'om')
plt.plot(x[y_hat==0, 0], x[y_hat==0, 1], 'ob')
plt.title('predicted')

运行结果

step =    0 loss = 3.0564e-01
step =  100 loss = 2.5732e-01
step =  200 loss = 2.0864e-01
step =  300 loss = 1.4089e-01
step =  400 loss = 9.5052e-02
step =  500 loss = 6.8628e-02
step =  600 loss = 5.5190e-02
step =  700 loss = 4.3967e-02
step =  800 loss = 3.8397e-02
step =  900 loss = 3.3949e-02
step = 1000 loss = 2.3727e-02
step = 1100 loss = 3.0124e-02
step = 1200 loss = 1.7051e-02
step = 1300 loss = 3.3124e-02
step = 1400 loss = 1.5228e-02
step = 1500 loss = 2.5390e-02
step = 1600 loss = 2.5443e-02
step = 1700 loss = 1.6697e-02
step = 1800 loss = 2.9582e-02
step = 1900 loss = 2.5630e-02
acc = 0.990000

在这里插入图片描述
总结,通过一个经典的问题,介绍了在pytorch中建立简单模型的基本方法。
【上一篇:梯度下降】
【下一篇:repeat】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值