pytorch学习笔记(四)
一、感知机基础知识介绍
感知机是二分类的线性模型,其输入是实例的特征向量,输出的是事例的类别,分别是+1和-1,属于判别模型。
二、单层感知机
单层感知机是最简单的神经网络。它包含输入层和输出层,而输入层和输出层是直接相连的。
实现代码
import torch
import torch.nn as nn
# 单层感知机
ten1 = torch.rand(1,10) # 定义10个ten1输入结点
ten2 = torch.randn(1,10,requires_grad=True) # 初始化10个ten2
ten3 = torch.sigmoid(ten1@ten2.t()) # ten1*ten2
print(ten3)
loss = nn.functional.mse_loss(torch.full([1,1],2.0),ten3)
loss.backward(retain_graph=True) # 分别对第一个ten2到第十个ten2求导
print(ten2.grad) # 10个ten2的梯度,通过此梯度用来更新10个ten2,就可以不断优化得到最终的ten2
tensor([[0.0328, 0.6797, 0.9116, 0.0968, 0.0382, 0.1145, 0.4152, 0.6265, 0.1553,
0.7994]])
tensor([[ 0.2024, 0.6685, 0.6171, 0.2950, -0.0143, 1.9586, 2.4213, -0.0802,
0.0433, -0.0750]], requires_grad=True)
tensor([[0.8982]], grad_fn=<SigmoidBackward>)
tensor([[-0.0066, -0.1369, -0.1836, -0.0195, -0.0077, -0.0231, -0.0836, -0.1262,
-0.0313, -0.1610]])
三、多层感知机
多层感知机是最简单的网络之一。本质上,它被定义为具有一个输入层、一个输出层和几个隐藏层( 不止一个)。每一层都有多个神经元,相邻的层之间进行全连接。每个神经元都可以被看作是这些巨大网络中的一个细胞,其决定了输入信号的流动和转换。前一层的信号通过连接权值被向前推送给下一层神经元。对于每个人工神经元,其通过将信号与权值相乘并加上偏值来计算所有输入的加权和。然后,加权和将送入一个称为激活函数的函数来决定是否应该被触发,这将产生输出信号以便用于下一层。
实现代码
import torch
import torch.nn as nn
# 多层感知机
ten4 = torch.rand(1,10) # 定义10个ten4
print(ten4)
ten5 = torch.randn(1,10,requires_grad=True) # 初始化一组权值
print(ten5)
ten6 = torch.sigmoid(ten4@ten5.t()) # 10个ten3对应1组ten5,进行激活
print(ten6)
loss = nn.functional.mse_loss(torch.full([1,1],2.0),ten6)
loss.backward(retain_graph=True) # 求导
print(ten5.grad) # 得到一组梯度
输出结果
tensor([[0.9806, 0.4377, 0.1618, 0.4100, 0.6507, 0.5815, 0.1602, 0.6777, 0.5351,
0.9662]])
tensor([[-0.2432, 0.6580, 0.2898, -1.2450, -0.6569, 0.1776, 1.9353, -1.2538,
0.4816, -0.3121]], requires_grad=True)
tensor([[0.2105]], grad_fn=<SigmoidBackward>)
tensor([[-0.5833, -0.2604, -0.0962, -0.2439, -0.3871, -0.3459, -0.0953, -0.4031,
-0.3183, -0.5748]])
四、2D函数优化
实现代码
import torch
import numpy as np
import matplotlib.pyplot as plot
def himmel(x):
return (x[0]**2+x[1]-11)**2+(x[0]+x[1]**2-7)**2
# 2D函数优化
# 画出图形
x=np.arange(-6,6,0.1)
y=np.arange(-6,6,0.1) # 创建了从-6,6的步长为0.1的arange对象
print('x,y range',x.shape,y.shape)
X,Y=np.meshgrid(x,y) # 用这两个arange对象可能的取值一一映射去扩充为所有可能的取样点
print('X,Y maps:',X.shape,Y.shape)
Z=himmel([X,Y]) # 用取样点的横纵坐标去求取样点Z坐标
fig=plot.figure('himmelblau') # 画出函数图像
ax=fig.gca(projection='3d')
ax.plot_surface(X,Y,Z,color='g',shade=True,vmin=0) # 利用取样点构建曲面
ax.view_init(60,-30)
ax.set_xlabel('x')
ax.set_ylabel('y') # 给坐标轴注明
plot.show()
# 迭代优化
x = torch.tensor([2.,3.],requires_grad=True)
optimizer=torch.optim.Adam([x],lr=1e-3)
for step in range(20000):
pre = himmel(x)
optimizer.zero_grad() # 梯度清零
pre.backward() # 求梯度
optimizer.step() # 迭代
if step % 20000 == 0:
xx = x.tolist() # 转化为标量
print(xx[0],xx[1],pre.item())
输出结果
x,y range (120,) (120,)
X,Y maps: (120, 120) (120, 120)
2.000999927520752 2.999000072479248 32.0