ShuviDoura
发表于 2024-9-3 09:51:56
对于一下模型的保存和加载的功能,我要怎么补充:
class NN():
def __init__(self, layers, data):
L = len(layers)# 这个layers是个包含了输入层到输出层的各层神经元个数的列表
# 设置神经元权重参数和偏置参数
self.W = {}
self.b = {}
for l in range(1, L):
# print(layers)
self.W["W" + str(l)] = np.mat(np.random.randn(layers, layers) * 0.1)
self.b["b" + str(l)] = np.mat(np.random.randn(layers, 1) * 0.1)
self.A = {}# 这个字典里存储了输入,和后面各个层的激活值;输出层的激活值在这个字典的最后一个
self.Z = {}# 这个字典里存储了从第二层到输出层的没被激活的值
self.cache = {}# 这个字典里存储了https://www.cnblogs.com/pinard/p/6422831.html里面各个层δl的值,第一个是输出层的δ
# 将数据写入类中
self.data = data
def forward_activation_02(self, L, flag):# 这个L是和上面的L一样的,包含了总共层数
# 初始化输入
self.A["A0"] = self.inputs
for l in range(1, L):
if flag == 0 or l == 1 or l == L - 1:
self.Z["Z" + str(l)] = self.W["W" + str(l)] * self.A["A" + str(l - 1)] + self.b["b" + str(l)]
self.A["A" + str(l)] = sigmoid(self.Z["Z" + str(l)])
else:
# 启用dropout正则化
self.d = np.random.rand(self.A["A" + str(l - 1)].shape, self.A["A" + str(l - 1)].shape)
self.d = self.d < keep_prob
self.A["A" + str(l - 1)] = np.multiply(self.A["A" + str(l - 1)], self.d)
self.A["A" + str(l - 1)] /= keep_prob
self.Z["Z" + str(l)] = self.W["W" + str(l)] * self.A["A" + str(l - 1)] + self.b["b" + str(l)]
self.A["A" + str(l)] = sigmoid(self.Z["Z" + str(l)])
# 更新cache
for l in reversed(range(1, L)):
if l == L - 1:
self.cache["C" + str(l)] = np.multiply(self.A["A" + str(l)] - self.output,
dsigmoid(self.Z["Z" + str(l)]))
else:
self.cache["C" + str(l)] = np.multiply(self.W["W" + str(l + 1)].T * self.cache["C" + str(l + 1)],
dsigmoid(self.Z["Z" + str(l)]))
err = np.abs(self.A["A" + str(L - 1)] - self.output)
return err
def backPropagate_02(self, learning_rate, L):# 反向传播
alpha = learning_rate
m = self.inputs.shape# 这是样本数
for i in range(L):
l = L - i - 1
if l > 0:
self.b['b' + str(l)] = self.b['b' + str(l)] - alpha * 1.0 / m * (
self.cache["C" + str(l)] * np.ones((m, 1)))
self.W['W' + str(l)] = self.W['W' + str(l)] - alpha * 1.0 / m * (
self.cache["C" + str(l)] * self.A["A" + str(l - 1)].T)
def init_prameter(self, batch_size):
# 每次批量训练batch_size幅图像
train_dataloader = DataLoader(self.data, batch_size=batch_size, drop_last=False, shuffle=True)
for train_data in train_dataloader:
imgs = train_data.numpy()
batch_xs, batch_ys = imgs[:, :feature_num], imgs[:, feature_num]
self.inputs = np.mat(batch_xs).transpose()
self.output = np.mat(sigmoid(batch_ys))
def train(self, iterations, learning_rate, L, batch_size, train_shape):
# 批处理训练
for i in range(iterations):
if (train_shape % batch_size) != 0:
print("batch没选对,要能够被train除进")
for j in range(int(train_shape / batch_size)):
self.init_prameter(batch_size)
err = self.forward_activation_02(L, 1)
self.backPropagate_02(learning_rate, L)
#############################每训练一轮就在测试集上进行测试
asdf, aswe = test_data[:, :feature_num], test_data[:, feature_num]
self.inputs = np.mat(asdf).transpose()
self.output = np.mat(sigmoid(aswe))
test_num = self.output.shape
test_loss = self.forward_activation_02(L, 0)
print("在训练集上,第", i, "轮迭代误差为", np.sum(err) / batch_size, "在测试集上,第", i, "轮迭代误差为",
np.sum(test_loss) / test_num)
if np.sum(test_loss) / test_num < 0.02 or i == (iterations - 1):
true_ = self.output.transpose()
pred_ = self.A["A" + str(L - 1)].transpose()
print("测试样本的实际结果:", true_)
print("测试样本的预测结果:", pred_)
plt.plot(pred_, label="pred")# 绘制预测关系图
plt.legend()
plt.plot(true_, label="true")# 绘制预测关系图
plt.legend()
plt.show()
break
return true_, pred_
FishC
发表于 2024-9-3 09:51:59
ShuviDoura 发表于 2024-09-03 09:51
对于一下模型的保存和加载的功能,我要怎么补充:
cl ...
要给你的神经网络类`NN`添加保存和加载模型的功能,可以考虑使用Python的`pickle`模块来序列化和反序列化对象。这样,你可以将模型的权重和偏置保存到
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-9-3 09:52:28
FishC 发表于 2024-9-3 09:51
要给你的神经网络类`NN`添加保存和加载模型的功能,可以考虑使用Python的`pickle`模块来序列化和反序列 ...
具体怎么写
FishC
发表于 2024-9-3 09:52:30
ShuviDoura 发表于 2024-09-03 09:52
具体怎么写
为了在你的神经网络类中加入模型的保存和加载功能,你可以使用Python的`pickle`模块。这个模块可以帮助你将对象序列化(保存到文件)或者反序列化(从文件加载)。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-9-3 09:57:00
我保存的模型里是以字典的形式保存得到的w和b的权重数据吗
FishC
发表于 2024-9-3 09:57:03
ShuviDoura 发表于 2024-09-03 09:57
我保存的模型里是以字典的形式保存得到的w和b的权重数 ...
是的,保存模型时通常会将模型的参数(如权重`W`和偏置`b`)存储在一个字典中,这样可以方便地序列化和反序列化。以下是如何
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-9-3 09:58:50
那我的字典里有w1,w2,w3以及b1,b2,b3,是代表什么意思
FishC
发表于 2024-9-3 09:58:58
ShuviDoura 发表于 2024-09-03 09:58
那我的字典里有w1,w2,w3以及b1,b2,b3,是代表什么 ...
字典中的键 `w1`,`w2`,`w3` 以及 `b1`,`b2`,`b3` 通常代表神经网络模型中不同层的权重和偏置。具体来说:
- `w1`, `w2`, `w3`: 这些是网络中各层的权重矩阵。每个`wi`(如`w1`)对应一个特定层的权重。
- `b1`, `b2`, `b3`: 这些是网络中各层的偏置向量。每个`bi`(如`b1`)对应一个特定层的偏置。
对于一个简单的多层感知器(MLP)模型:
- `w1` 和 `b1` 可能对应输入层到第一个隐藏层的权重和偏置。
- `w2` 和 `b2` 对应第一个隐藏层到第二个隐藏层。
- `w3` 和 `b3` 则可能对应从最后一个隐藏层到输出层。
具体有多少个这样的`w`和`b`,以及每个的维度,取决于你的网络结构(例如,层数、每层的神经元数量等)。通过保存这些参数,你可以在训练后恢复网络的状态,或者与其他数据集进行测试。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-9-3 10:09:11
创建神经网络,21个输入节点,13个隐藏层节点,21个输出层节点,这是有几个输入层几个隐藏层几个输出层
ShuviDoura
发表于 2024-9-3 10:10:13
创建神经网络,21个输入节点,13个隐藏层节点,21个输出层节点,这是有几个输入层几个隐藏层几个输出层
FishC
发表于 2024-9-3 10:13:38
ShuviDoura 发表于 2024-09-03 10:09
创建神经网络,21个输入节点,13个隐藏层节点,21个输 ...
你提到的神经网络结构有:
- **1个输入层**:包含21个输入节点。
- **1个隐藏层**:包含13个隐藏层节点。
- **1个输出层**:包含21个输出层节点。
所以,整个网络结构是一层输入层,一层隐藏层和一层输出层。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-12-10 21:27:08
我要进行多分类,那么sigmoid和dsigmoid函数可以将以下换成什么
def sigmoid(x):
return math.tanh(x)
def dsigmoid(y):
return (1.0 - y**2)
FishC
发表于 2024-12-10 21:27:18
ShuviDoura 发表于 2024-12-10 21:27
我要进行多分类,那么sigmoid和dsigmoid函数可以将以 ...
在多分类问题中,常常使用Softmax函数代替Sigmoid函数,因为Softmax函数可以将输出转化为概率分布。对于Softmax的导数(dsigmoid的替代),通常在误差反向传播过程中结合Cross-Entropy损失一起考虑。
以下是Softmax函数的Python实现:
import numpy as np
def softmax(x):
e_x = np.exp(x - np.max(x))# 减去最大值来提高数值稳定性
return e_x / e_x.sum(axis=0)
# Softmax函数通常在反向传播时结合损失函数进行求导,因此不需要单独实现 dsigmoid
请注意,Softmax 函数及其导数计算是在特定上下文中与交叉熵损失进行结合使用的。在使用框架(如 TensorFlow 或 PyTorch)时,它们通常会自动处理这些计算。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-12-10 21:28:39
FishC 发表于 2024-12-10 21:27
在多分类问题中,常常使用Softmax函数代替Sigmoid函数,因为Softmax函数可以将输出转化为概率分布。对 ...
那我的bp神经网络种本来就存在sigmoid和dsigmoid这部分,我要怎么改
FishC
发表于 2024-12-10 21:28:54
ShuviDoura 发表于 2024-12-10 21:28
那我的bp神经网络种本来就存在sigmoid和dsigmoid这部 ...
在BP神经网络中,如果要使用Softmax用于多分类任务,我们不需要定义一个类似于Sigmoid和dSigmoid的反向函数。Softmax本身在网络输出层使用,损失常与交叉熵结合。若需要实现Softmax输出,Sigmoid替换可如下:
import numpy as np
def softmax(x):
e_x = np.exp(x - np.max(x))# 稳定性处理,防止指数爆炸
return e_x / e_x.sum(axis=0)
# 损失函数如交叉熵在配合进行训练时,自动求梯度
# 示例用法,适用于输出层
output = np.array()
probabilities = softmax(output)
print(probabilities)
注意, Softmax 用于网络的输出层,本质与 Sigmoid 不同,逐层的激活函数可以仍然使用例如 ReLU 或 Sigmoid(具体视情况选择),而 Softmax 负责将整个层的输出归一化为概率分布的方式。例如,若需要 Sigmoid 可保持层间非线性:
# 为隐层仍然可以使用 Sigmoid 或 ReLU,这在 Softmax 前的网络层依旧适用
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def dsigmoid(y):
return y * (1 - y)# 作为逐点函数,适用于隐藏层
确保损失函数与Softmax兼容,以交叉熵损失计算即可。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-12-10 21:30:41
FishC 发表于 2024-12-10 21:28
在BP神经网络中,如果要使用Softmax用于多分类任务,我们不需要定义一个类似于Sigmoid和dSigmoid的反向 ...
C:\Users\shiro\Desktop\01\conda\envs\skyzero\python.exe C:\Users\shiro\Desktop\bpnn-master\11111.py
C:\Users\shiro\Desktop\bpnn-master\bpnn.py:26: RuntimeWarning: overflow encountered in exp
return 1 / (1 + np.exp(-x))
这是什么意思
FishC
发表于 2024-12-10 21:30:54
ShuviDoura 发表于 2024-12-10 21:30
C:\Users\shiro\Desktop\01\conda\envs\skyzero\pytho ...
该警告信息表明在运行Python代码时,程序在调用`np.exp`函数时遇到了数值溢出的问题。这通常是由于传递给`np.exp`的负数值过大,导致指数函数的计算结果超出了浮点数的表示范围。
要解决这个问题,你可以尝试以下几种方法:
1. **检查输入数据**:确保输入给`np.exp`的值没有过大或过小。如果数据异常,可能需要对输入数据进行归一化或标准化处理。
2. **调整权重初始化**:你可能需要重新考虑神经网络中权重的初始化方式,较大的初始权重可能导致较大的输入值。
3. **使用其他激活函数**:如果问题严重,可以考虑使用其他数值表现更加稳定的激活函数,例如`np.tanh`或使用Keras、PyTorch等深度学习框架提供的激活函数,这些函数一般会有更好的数值稳定性。
4. **处理数值限制**:在使用`np.exp`之前,可以先将输入值裁剪到一定范围,例如:
def stable_sigmoid(x):
return 1 / (1 + np.exp(-np.clip(x, -500, 500)))
通过`np.clip`限制输入的最大和最小值,可以有效防止溢出。
你可以检查在哪里使用了`sigmoid`函数,并考虑应用以上建议进行调整。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-12-11 10:09:04
bp神经网络是不是在正向传播的时候用sigmoid激活函数,在反向传播计算残差的时候用sigmoid的导数作为“激活函数”计算残差
FishC
发表于 2024-12-11 10:09:14
ShuviDoura 发表于 2024-12-11 10:09
bp神经网络是不是在正向传播的时候用sigmoid激活函数 ...
是的,在BP神经网络中:
1. **正向传播**:神经网络使用激活函数(比如Sigmoid函数)将输入映射到输出。这有助于引入非线性,使神经网络能够学习复杂模式。
2. **反向传播**:在计算误差的梯度时,你需要用到激活函数的导数。对于Sigmoid函数,其导数会用来计算每个神经元的误差梯度,从而帮助调整权重。
Sigmoid函数的导数公式是:
\[ f'(x) = f(x) \times (1 - f(x)) \]
其中,\( f(x) \) 是Sigmoid函数的输出。这确保了在反向传播过程中,我们正确地计算权重更新的梯度。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
ShuviDoura
发表于 2024-12-11 10:12:09
FishC 发表于 2024-12-11 10:09
是的,在BP神经网络中:
1. **正向传播**:神经网络使用激活函数(比如Sigmoid函数)将输入映射到输 ...
为什么反向传播计算误差梯度用的是sigmoid的导数,如果此时用sigmoid会怎么样