纯Python和PyTorch对比实现softmax及其反向传播

摘要
本文使用纯 Python 和 PyTorch 对比实现softmax函数及其反向传播.

相关
原理和详细解释, 请参考文章 :

softmax函数详解及反向传播中的梯度求导

系列文章索引 :
https://blog.csdn.net/oBrightLamp/article/details/85067981

正文

import numpy as np
import torch


class Solfmax:
    def __init__(self):
        self.softmax = None
        self.grad = None
        self.dnx = None

    def __call__(self, nx):
        shifted_x = nx - np.max(nx)
        ex = np.exp(shifted_x)
        sum_ex = np.sum(ex)
        self.solfmax = ex / sum_ex
        return self.solfmax

    def get_grad(self):
        self.grad = self.solfmax[:, np.newaxis] * self.solfmax[np.newaxis, :]
        for i in range(len(self.grad)):
            self.grad[i, i] -= self.solfmax[i]
        self.grad = - self.grad
        return self.grad

    def backward(self, dl):
        self.get_grad()
        self.dnx = np.sum(self.grad * dl, axis=1)
        return self.dnx


np.random.seed(123)
np.set_printoptions(precision=8, suppress=True, linewidth=120)

d_loss = np.array([11, 12, 13, 14, 15, 16, 17, 18, 19], dtype=float)
d_loss_tensor = torch.tensor(d_loss, requires_grad=True)

softmax_numpy = Solfmax()
x_numpy = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=float)
soft_numpy = softmax_numpy(x_numpy)
x_grad_numpy = softmax_numpy.backward(d_loss)

x_tensor = torch.tensor(x_numpy, requires_grad=True)
soft_tensor = torch.nn.functional.softmax(x_tensor, dim=0)
soft_tensor.backward(d_loss_tensor)
x_grad_tensor = x_tensor.grad

print(soft_numpy)
print(soft_tensor.data.numpy())
print()
print(x_grad_numpy)
print(x_grad_tensor.data.numpy())

"""
代码输出 :
[ 0.00021208  0.00057649  0.00156706  0.00425972  0.01157912  0.03147531  0.08555877  0.23257286  0.63219858]
[ 0.00021208  0.00057649  0.00156706  0.00425972  0.01157912  0.03147531  0.08555877  0.23257286  0.63219858]

[-0.00157344 -0.00370057 -0.00849213 -0.01882428 -0.03959057 -0.07614301 -0.12141937 -0.09747922  0.36722258]
[-0.00157344 -0.00370057 -0.00849213 -0.01882428 -0.03959057 -0.07614301 -0.12141937 -0.09747922  0.36722258]
"""

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用PyTorch实现softmax二分类,可以按照以下步骤进行操作: 1. 导入所需的库: ```python import torch import torch.nn as nn import torch.optim as optim ``` 2. 准备数据集,包括特征和标签。假设你已经有了训练集`train_features`和对应的标签`train_labels`。 3. 定义模型: ```python class SoftmaxClassifier(nn.Module): def __init__(self, input_size, num_classes): super(SoftmaxClassifier, self).__init__() self.linear = nn.Linear(input_size, num_classes) def forward(self, x): out = self.linear(x) return out ``` 这里使用了一个线性层`nn.Linear`作为模型的输出层。 4. 初始化模型并定义损失函数和优化器: ```python input_size = train_features.shape[1] # 特征的维度 num_classes = 2 # 二分类问题,输出类别数为2 model = SoftmaxClassifier(input_size, num_classes) criterion = nn.CrossEntropyLoss() # 使用交叉熵损失函数 optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用随机梯度下降优化器 ``` 5. 进行模型训练: ```python num_epochs = 10 # 迭代次数 for epoch in range(num_epochs): # 前向传播 outputs = model(train_features) loss = criterion(outputs, train_labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 打印训练信息 if (epoch+1) % 1 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') ``` 在每个迭代周期中,模型进行前向传播计算损失,然后通过反向传播和优化器更新模型参数。 6. 使用模型进行预测: ```python # 假设你有测试集test_features with torch.no_grad(): outputs = model(test_features) _, predicted = torch.max(outputs.data, 1) # 输出预测结果 for i in range(len(test_features)): print(f'Test Sample {i+1}: Predicted={predicted[i]}, True={test_labels[i]}') ``` 这里使用了`torch.max`函数找到最大的类别概率,并将其作为预测结果。 这就是使用PyTorch实现softmax二分类的基本步骤。可以根据实际问题进行适当的修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值