单层神经网络,可以用线性回归来理解
单层:一般输入层不算,算后面的
其中 w 相关的字母来控制特征的权重(比如w1 = 0.5,x1 = 10),那么经过w1的映射,x1最后给到的只有5。所以说每个特征的权重大小关系到该特征对结果的影响大小。
最简单的实现:
import torch
# z = wx + b
X = torch.tensor([[1.,0,0],[1,1,0],[1,0,1],[1,1,1]]) # 这里要生成浮点型(为了和w类型保持一致
w = torch.tensor([-0.2,0.15,0.15])
z = torch.tensor([[-0.2],[-0.05],[-0.05],[0.1]],dtype=torch.float32)
# 为了避免在计算中torch需要先判断计算的类型,增大计算量,我们在一开始的定义tensor的时候就规定好数据类型,
# 一些函数不接受一维的张量,保险起见,直接定义二维
def LinearR(w,X):
zhat = torch.mv(X,w) # mv是矩阵乘向量,矩阵需要是第一个参数
return zhat
if __name__ == '__main__':
# print(LinearR(w, X))
z_ = z.view([4])
print(z_ == LinearR(w, X))
"""
这里会出现不等的情况,是由于精度的差异
1 float32 只保留32位,精确度会有问题
2 torch.mv 计算时内部会出现很微小的计算问题(会导致我们输入的真实值都有变化
一般来说这种微小的精度可以忽略不计
换成float64会更精确(除非有精度要求,不然太占内存了
"""
然后现在,我们得到了一推回归的固定的数值(称为z),每一个z代表一个结果,如果想把这些不一样的结果进行分类?这里我们可以把这些z经过一个数学函数(sigmoid函数),这个函数能把回归值映射到【0,1】之间,然后我们从中取一个阈值(一般是0.5),映射之后的数和阈值做比较,大于阈值归为“1"类,小于阈值归为‘0’类。
import torch
from torch.nn.modules import Linear
from torch.nn.functional import sigmoid
X = torch.tensor([[1,0,0],[1,1,0],[1,0,1],[1,1,1]],dtype=torch.float32)
Y = torch.tensor([[1,0],[1,1],[0,0],[0,1]],dtype=torch.float32)
andgate = torch.tensor([[0],[0],[0],[1]])
w = torch.tensor([-0.2,0.15,0.15],dtype=torch.float32)
def LogistiC(X,w):
zhat = torch.mv(X,w)
sigma = 1/(1+torch.exp(-zhat))
sighat = torch.tensor([int(i) for i in sigma >= 0.5],dtype=torch.float32)
return zhat,sigma,sighat
def Liear(X):
torch.random.manual_seed(22)
dense = Linear(2,1)
zhat = dense(X)
sigma = sigmoid(zhat)
sighat = torch.tensor([int(i) for i in sigma >= 0.5],dtype=torch.float32)
return sighat
if __name__ == '__main__':
sighat_liear = Liear(Y)
print(sighat_liear)
zhat,sigma,sighat = LogistiC(X,w)
print(zhat)
print(sigma)
print(sighat)