分别用numpy,pytorch实现两层前向神经网络

分别用numpy,pytorch实现两层神经网络

在人工智能领域,深度学习,神经网络异军突起,成为了现在的主流研究对象。那么如果想从最基本的原理入手,我们可以先用numpy实现一个简单的两层神经网络,即只有一个中间层。
一个神经网络包括输入层,中间层,和输出层。

numpy

这一实现完全使用numpy来计算前向神经网络,损失函数,和反向传播。
首先导入numpy

import numpy as np

实现步骤:
1.创建输入、输出:

N, D_in, H, D_out = 64, 1000, 100, 10
#N表示输入数据个数,D_in表示输入神经元个数,H表示中间层个数,D_out表示输出神经元个数。
x = np.random.randn(N, D_in)#随机生成一个输入矩阵x
y = np.random.randn(N, D_out)#随机生成一个输出矩阵y

2.在创建好输入,输出后,进行神经网络的搭建:
设定学习率

learning_rate = 1e-6

在这里插入图片描述
由图可知,y=wX+b。
w为各个信号的权重参数,b叫做偏置,用于控制神经元被激活的容易程度。
说到这里,我们就不得不提到激活函数的概念:
若激活函数为h(x),则y可表示为h(wX+b)。常用激活函数有sigmoid函数,如图所示
在这里插入图片描述
激活函数的作用就是激活神经元:输出y达到某个阙值后,神经元激活。
根据公式搭建神经网络:

 h = x.dot(w1) #dot为矩阵乘法
 h_relu = np.maximum(h, 0)  #激活函数relu
 y_pred = h_relu.dot(w2)    #输出

计算损失函数:
神经网络的学习通过某个指标表示现在的状态,然后,以这个指标为基准,寻找最优权重参数。这个指标成为损失函数。常用的损失函数有均方误差,和交叉熵误差。
设定损失函数为均方误差计算

 loss = np.square(y_pred - y).sum()

反向计算误差,更新权重:

 # loss = (y_pred - y) ** 2
grad_y_pred = 2.0 * (y_pred - y) #求y_pred的梯度
grad_w2 = h_relu.T.dot(grad_y_pred)  #求第二层权重梯度
grad_h_relu = grad_y_pred.dot(w2.T)  
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0
grad_w1 = x.T.dot(grad_h)

更新权重:

w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2

3.打印损失函数:

  print(t, loss)

将以上流程循环500次,得到损失函数为:6.742494858156187e-06

附整体代码:

import numpy as np


N, D_in, H, D_out = 64, 1000, 100, 10


x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)


w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)

learning_rate = 1e-6
for t in range(500):
   
    h = x.dot(w1)
    h_relu = np.maximum(h, 0)
    y_pred = h_relu.dot(w2)

   
    loss = np.square(y_pred - y).sum()
    print(t, loss)

  
    grad_y_pred = 2.0 * (y_pred - y) 
    grad_w2 = h_relu.T.dot(grad_y_pred)
    grad_h_relu = grad_y_pred.dot(w2.T)
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = 0
    grad_w1 = x.T.dot(grad_h)

    
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

pytorch

如果要用pytorch,首先要导入torch,没有的可以在官网上用pip install 下载

import torch

dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") # Uncomment this to run on GPU

# N 是 batch size; D_in 是 input dimension;
# H 是 hidden dimension; D_out 是 output dimension.
N, D_in, H, D_out = 64, 1000, 100, 10

# 创建随机的Tensor来保存输入和输出
# 设定requires_grad=False表示在反向传播的时候我们不需要计算gradient
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

# 创建随机的Tensor和权重。
# 设置requires_grad=True表示我们希望反向传播的时候计算Tensor的gradient
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    # 前向传播:通过Tensor预测y;这个和普通的神经网络的前向传播没有任何不同,
    # 但是我们不需要保存网络的中间运算结果,因为我们不需要手动计算反向传播。
    y_pred = x.mm(w1).clamp(min=0).mm(w2)

    # 通过前向传播计算loss
    # loss是一个形状为(1,)的Tensor
    # loss.item()可以给我们返回一个loss的scalar
    loss = (y_pred - y).pow(2).sum()
    print(t, loss.item())

    # PyTorch给我们提供了autograd的方法做反向传播。如果一个Tensor的requires_grad=True,
    # backward会自动计算loss相对于每个Tensor的gradient。在backward之后,
    # w1.grad和w2.grad会包含两个loss相对于两个Tensor的gradient信息。
    loss.backward()

    # 我们可以手动做gradient descent(后面我们会介绍自动的方法)。
    # 用torch.no_grad()包含以下statements,因为w1和w2都是requires_grad=True,
    # 但是在更新weights之后我们并不需要再做autograd。
    # 另一种方法是在weight.data和weight.grad.data上做操作,这样就不会对grad产生影响。
    # tensor.data会我们一个tensor,这个tensor和原来的tensor指向相同的内存空间,
    # 但是不会记录计算图的历史。
    with torch.no_grad():
        w1 -= learning_rate * w1.grad
        w2 -= learning_rate * w2.grad

        # Manually zero the gradients after updating weights
        w1.grad.zero_()
        w2.grad.zero_()

在此基础上,使用pytorch的nn和optim库可以帮助我们更方便地构建神经网络和更新参数:

import torch


N, D_in, H, D_out = 64, 1000, 100, 10


x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

# 使用nn来定义前向神经网络以及损失函数
model = torch.nn.Sequential(
    torch.nn.Linear(D_in, H),
    torch.nn.ReLU(),
    torch.nn.Linear(H, D_out),
)
loss_fn = torch.nn.MSELoss(reduction='sum')

# 使用optim来定义可以更新权重的optimizer,这里使用了Adam算法
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for t in range(500):
    # 通过神经网络预测y
    y_pred = model(x)

    # 计算并输出损失函数
    loss = loss_fn(y_pred, y)
    print(t, loss.item())

  #此步骤为清除累计的梯度
    optimizer.zero_grad()

    # Backward pass: compute gradient of the loss with respect to model
    # parameters
    loss.backward()

    # Calling the step function on an Optimizer makes an update to its
    # parameters
    optimizer.step()
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现神经网络用于计算两个图的相似度,可以按照以下步骤进行: 1. 定义图的数据结构。可以使用networkx库来定义无向图或有向图,并将节点和边的特征储存在节点和边的属性中。 2. 定义图神经网络模型。可以使用PyTorch Geometric库中提供的图神经网络层,如GCN、GAT、ChebNet等来搭建模型。 3. 定义相似度度量方法。可以使用余弦相似度、欧几里得距离等方法来计算两个图的相似度。 4. 训练模型。使用两个相似的图作为正样本,两个不相似的图作为负样本,使用交叉熵损失函数进行训练。 5. 预测相似度。将两个图输入训练好的模型中,通过计算输出结果来预测两个图的相似度。 以下是一个简单的示例代码,其中使用GCN作为图神经网络层,余弦相似度作为相似度度量方法: ``` python import torch from torch_geometric.nn import GCNConv import torch.nn.functional as F from sklearn.metrics.pairwise import cosine_similarity import networkx as nx # 定义图数据结构 G1 = nx.Graph() G1.add_nodes_from([1, 2, 3]) G1.add_edges_from([(1, 2), (2, 3)]) nx.set_node_attributes(G1, {1: [0.1, 0.2], 2: [0.3, 0.4], 3: [0.5, 0.6]}, 'feat') nx.set_edge_attributes(G1, {(1, 2): [0.7], (2, 3): [0.8]}, 'feat') G2 = nx.Graph() G2.add_nodes_from([1, 2, 3]) G2.add_edges_from([(1, 3), (2, 3)]) nx.set_node_attributes(G2, {1: [0.1, 0.2], 2: [0.3, 0.4], 3: [0.5, 0.6]}, 'feat') nx.set_edge_attributes(G2, {(1, 3): [0.9], (2, 3): [0.8]}, 'feat') # 定义图神经网络模型 class GCN(torch.nn.Module): def __init__(self): super(GCN, self).__init__() self.conv1 = GCNConv(2, 16) self.conv2 = GCNConv(16, 32) def forward(self, x, edge_index): x = F.relu(self.conv1(x, edge_index)) x = self.conv2(x, edge_index) return x # 计算余弦相似度 def cosine_sim(a, b): return cosine_similarity(a.reshape(1, -1), b.reshape(1, -1))[0][0] # 计算两个图的相似度 def graph_similarity(G1, G2): # 转换为PyTorch Geometric中的数据格式 G1 = nx.convert_node_labels_to_integers(G1) G2 = nx.convert_node_labels_to_integers(G2) x1 = torch.tensor([G1.nodes[n]['feat'] for n in G1.nodes()]) x2 = torch.tensor([G2.nodes[n]['feat'] for n in G2.nodes()]) edge_index1 = torch.tensor([e for e in G1.edges()], dtype=torch.long).t().contiguous() edge_index2 = torch.tensor([e for e in G2.edges()], dtype=torch.long).t().contiguous() # 构建模型并计算图嵌入 model = GCN() h1 = model(x1.float(), edge_index1) h2 = model(x2.float(), edge_index2) # 计算相似度 return cosine_sim(h1.detach().numpy(), h2.detach().numpy()) # 训练模型(略) # 预测相似度 similarity = graph_similarity(G1, G2) print(similarity) ``` 需要注意的是,以上代码只是一个简单的示例,实际应用中需要根据具体情况进行修改和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值