softmax,softmax-loss,BP的解释

本文转载自:http://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/ ,看完这个博客让我对softmax,softmax-loss以及BP算法有了更深的理解,以前BP只是知道链式求导,知道梯度回传,但是具体到哪些变量和哪些变量求导就有些模糊了,现在我特整理了下思路,以下大部分是链接的原文,附带自己的一些理解(用红色标出)


联想逻辑回归的重要公式就是,得到预测结果,然后再经过sigmoid转换成0到1的概率值,而在softmax中则通过取exponential的方式并进行归一化得到某个样本属于某类的概率。非负的意义不用说,就是避免正负值抵消。


逻辑回归的推导可以用最大似然或最小损失函数,本质是一样的,可以简单理解成加了一个负号,这里的y指的是真实类别。注意下softmax-loss可以看做是softmax和multinomial logistic loss两步,正如上述所写公式,把变量展开即softmax-loss。


原博客的重点在于介绍softmax-loss是分成两步还是一步到位比较好,而我这则重点说下BP。上面这个神经网络的图应该不陌生,这个公式也是在逻辑回归的核心(通过迭代得到w,然后在测试时按照上面这个公式计算类别概率)


这里第一个公式是损失函数对权重w求导,其实就是梯度,红色那部分可以看前面O是怎么算出来的,就知道其导数的形式非常简单,就是输入I。蓝色部分就是BP的核心,回传就是通过这个达到的,回传的东西就是损失函数对该层输出的导数,只有把这个往前回传,才能计算前面的梯度。所以回传的不是对权重的求导,对每层权重的求导的结果会保留在该层,等待权重更新时候使用。具体看上面最后一个公式。


这部分的求导:l(y,z)函数是log函数,log(x)函数求导是取1/x,后面的那个数是zy对zk的导数,当k=y时,那就是1,k不等于y时就是两个不同的常数求导,就是0。


这一部分就是把softmax-loss分成两步来做,第一个求导可以先找到最前面l(y,o)的公式,也是log函数,所以求导比较简单。第二个求导也是查看前面Oi的公式,分母取平方的那种求导。最后链式相乘的结果和原来合并算的结果一样。

  • 17
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
PSO-BP算法是一种常用的神经网络训练算法,结合了粒子群优化算法和反向传播算法,可以用于多分类预测问题。 以下是使用Python实现PSO-BP多分类预测的基本步骤: 1. 导入所需的库和数据集 ``` python import numpy as np from sklearn.datasets import load_iris from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split ``` 2. 数据预处理 ``` python # 加载数据集 iris = load_iris() X = iris.data y = iris.target.reshape(-1, 1) # 对标签进行One-hot编码 enc = OneHotEncoder() y = enc.fit_transform(y).toarray() # 将数据集分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) ``` 3. 定义PSO-BP算法 ``` python # 定义PSO-BP算法类 class PSO_BP(): def __init__(self, n_input, n_hidden, n_output): self.n_input = n_input self.n_hidden = n_hidden self.n_output = n_output self.w1 = np.random.randn(n_input, n_hidden) self.b1 = np.random.randn(n_hidden) self.w2 = np.random.randn(n_hidden, n_output) self.b2 = np.random.randn(n_output) self.v_w1 = np.random.randn(n_input, n_hidden) self.v_b1 = np.random.randn(n_hidden) self.v_w2 = np.random.randn(n_hidden, n_output) self.v_b2 = np.random.randn(n_output) def sigmoid(self, x): return 1 / (1 + np.exp(-x)) def softmax(self, x): exp_x = np.exp(x) return exp_x / np.sum(exp_x, axis=1, keepdims=True) def forward(self, X): self.z1 = np.dot(X, self.w1) + self.b1 self.a1 = self.sigmoid(self.z1) self.z2 = np.dot(self.a1, self.w2) + self.b2 self.a2 = self.softmax(self.z2) return self.a2 def loss(self, X, y): y_pred = self.forward(X) loss = -np.sum(y * np.log(y_pred)) return loss def accuracy(self, X, y): y_pred = self.predict(X) acc = np.sum(y_pred == np.argmax(y, axis=1)) / len(y) return acc def predict(self, X): y_pred = self.forward(X) return np.argmax(y_pred, axis=1) def backward(self, X, y): y_pred = self.forward(X) delta3 = y_pred - y delta2 = np.dot(delta3, self.w2.T) * self.a1 * (1 - self.a1) grad_w2 = np.dot(self.a1.T, delta3) grad_b2 = np.sum(delta3, axis=0) grad_w1 = np.dot(X.T, delta2) grad_b1 = np.sum(delta2, axis=0) return grad_w1, grad_b1, grad_w2, grad_b2 def update(self, grad_w1, grad_b1, grad_w2, grad_b2, lr, w_decay, v_decay, v_scale): self.v_w1 = v_decay * self.v_w1 - lr * (grad_w1 + w_decay * self.w1) self.v_b1 = v_decay * self.v_b1 - lr * grad_b1 self.v_w2 = v_decay * self.v_w2 - lr * (grad_w2 + w_decay * self.w2) self.v_b2 = v_decay * self.v_b2 - lr * grad_b2 self.w1 += v_scale * self.v_w1 self.b1 += v_scale * self.v_b1 self.w2 += v_scale * self.v_w2 self.b2 += v_scale * self.v_b2 def train(self, X, y, lr=0.01, w_decay=0.0, v_decay=0.99, v_scale=0.1, n_epoch=1000): for i in range(n_epoch): grad_w1, grad_b1, grad_w2, grad_b2 = self.backward(X, y) self.update(grad_w1, grad_b1, grad_w2, grad_b2, lr, w_decay, v_decay, v_scale) if i % 100 == 0: loss = self.loss(X, y) acc = self.accuracy(X, y) print('Epoch {}: loss={}, accuracy={}'.format(i, loss, acc)) ``` 4. 训练模型并测试 ``` python # 初始化模型 model = PSO_BP(n_input=4, n_hidden=10, n_output=3) # 训练模型 model.train(X_train, y_train, lr=0.01, w_decay=0.0, v_decay=0.99, v_scale=0.1, n_epoch=1000) # 测试模型 acc = model.accuracy(X_test, y_test) print('Test accuracy:', acc) ``` 通过以上步骤,即可使用PSO-BP算法进行多分类预测。需要注意的是,不同的数据集和模型可能需要不同的参数设置,需要进行适当的调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值