鱼C论坛

 找回密码
 立即注册
查看: 153|回复: 18

[已解决]关于bp神经网络

[复制链接]
发表于 2024-9-3 10:44:55 | 显示全部楼层 |阅读模式
10鱼币
我从网上抄了一个代码,但是其中不包含保存模型与加载模型的步骤,那么在这个代码中,我是应该保存W和b的值,还是A和Z的值作为训练模型之后后的保存数据,wb和az各自都是什么,cache又是什么
保存模型以及调用模型预测新的数据这一部分要怎么写


class NN():
    def __init__(self, layers, data):

        L = len(layers)  # 这个layers是个包含了输入层到输出层的各层神经元个数的列表
        # 设置神经元权重参数和偏置参数
        self.W = {}
        self.b = {}
        for l in range(1, L):
            # print(layers[l])
            self.W["W" + str(l)] = np.mat(np.random.randn(layers[l], layers[l - 1]) * 0.1)
            self.b["b" + str(l)] = np.mat(np.random.randn(layers[l], 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[0], self.A["A" + str(l - 1)].shape[1])
                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[1]  # 这是样本数
        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[1]

            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_
最佳答案
2024-9-3 10:44:56
在BP神经网络中,保存和加载模型的关键在于保存和恢复模型的参数,因为这些参数决定了模型的具体行为。对于该代码中的BP神经网络,实现保存和加载模型的步骤可以遵循以下方法:

### 参数解释:

1. **W(权重)** 和 **b(偏置)**:这些是需要保存的参数。在训练过程中,权重和偏置会被优化以最小化损失函数。这些参数定义了神经网络的功能。

2. **A(激活值)** 和 **Z(未激活线性输出)**:这些不需要保存,因为它们是在给定输入时计算的中间结果,当你再次使用模型进行预测时,它们会被重新计算。

3. **Cache**:通常用来存储反向传播阶段临时变量,如误差项。也不需要长期保存。

### 保存模型:

为了保存模型的权重和偏置,可以使用Python的`pickle`库来序列化数据或使用`NumPy`来保存为文件。这里是一个简单的方法:
import pickle

def save_model(nn, filename):
    with open(filename, 'wb') as file:
        model_parameters = {
            'W': nn.W,
            'b': nn.b
        }
        pickle.dump(model_parameters, file)

### 加载模型:

加载模型时,我们需要从文件中恢复权重和偏置:
def load_model(filename):
    with open(filename, 'rb') as file:
        model_parameters = pickle.load(file)
    nn = NN()  # 假设有适当的构造函数
    nn.W = model_parameters['W']
    nn.b = model_parameters['b']
    return nn

### 调用模型进行预测:

一旦模型加载完毕,你可以使用神经网络的前馈方法进行预测:
def predict(nn, input_data):
    nn.inputs = input_data
    nn.forward_activation_02(L=len(nn.W), flag=0)  # 假设flag控制是否应用dropout
    return nn.A  # 返回最终的预测结果

### 注意事项:

- 确保`NN`类提供了合适的接口来设置`inputs`和其它相关参数。
- `pickle`文件保存的是序列化的Python对象,这对于跨平台兼容性可能不太好,生产环境更推荐使用通用格式如HDF5(通过`h5py`库)或Tensorflow/Keras等框架本身的保存机制。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

最佳答案

查看完整内容

在BP神经网络中,保存和加载模型的关键在于保存和恢复模型的参数,因为这些参数决定了模型的具体行为。对于该代码中的BP神经网络,实现保存和加载模型的步骤可以遵循以下方法: ### 参数解释: 1. **W(权重)** 和 **b(偏置)**:这些是需要保存的参数。在训练过程中,权重和偏置会被优化以最小化损失函数。这些参数定义了神经网络的功能。 2. **A(激活值)** 和 **Z(未激活线性输出)**:这些不需要保存,因为它们是 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:44:56 | 显示全部楼层    本楼为最佳答案   
在BP神经网络中,保存和加载模型的关键在于保存和恢复模型的参数,因为这些参数决定了模型的具体行为。对于该代码中的BP神经网络,实现保存和加载模型的步骤可以遵循以下方法:

### 参数解释:

1. **W(权重)** 和 **b(偏置)**:这些是需要保存的参数。在训练过程中,权重和偏置会被优化以最小化损失函数。这些参数定义了神经网络的功能。

2. **A(激活值)** 和 **Z(未激活线性输出)**:这些不需要保存,因为它们是在给定输入时计算的中间结果,当你再次使用模型进行预测时,它们会被重新计算。

3. **Cache**:通常用来存储反向传播阶段临时变量,如误差项。也不需要长期保存。

### 保存模型:

为了保存模型的权重和偏置,可以使用Python的`pickle`库来序列化数据或使用`NumPy`来保存为文件。这里是一个简单的方法:
import pickle

def save_model(nn, filename):
    with open(filename, 'wb') as file:
        model_parameters = {
            'W': nn.W,
            'b': nn.b
        }
        pickle.dump(model_parameters, file)

### 加载模型:

加载模型时,我们需要从文件中恢复权重和偏置:
def load_model(filename):
    with open(filename, 'rb') as file:
        model_parameters = pickle.load(file)
    nn = NN()  # 假设有适当的构造函数
    nn.W = model_parameters['W']
    nn.b = model_parameters['b']
    return nn

### 调用模型进行预测:

一旦模型加载完毕,你可以使用神经网络的前馈方法进行预测:
def predict(nn, input_data):
    nn.inputs = input_data
    nn.forward_activation_02(L=len(nn.W), flag=0)  # 假设flag控制是否应用dropout
    return nn.A  # 返回最终的预测结果

### 注意事项:

- 确保`NN`类提供了合适的接口来设置`inputs`和其它相关参数。
- `pickle`文件保存的是序列化的Python对象,这对于跨平台兼容性可能不太好,生产环境更推荐使用通用格式如HDF5(通过`h5py`库)或Tensorflow/Keras等框架本身的保存机制。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-3 10:51:16 | 显示全部楼层
FishC 发表于 2024-9-3 10:46
在BP神经网络中,保存和加载模型的关键在于保存和恢复模型的参数,因为这些参数决定了模型的具体行为。对于 ...

我要怎么使用这个def呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 11:10:11 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 10:51
我要怎么使用这个def呢


在处理保存和加载模型的任务时,你可以创建两个新的方法:一个用于保存模型参数,另一个用于加载这些参数。以下是如何实现这两个功能的简化版本:

```python
import numpy as np

class

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-3 15:06:59 | 显示全部楼层
Traceback (most recent call last):
  File "C:\Users\shiro\Desktop\digital image\PKLlook.py", line 200, in <module>
    pred = predict(nn,data) # 前两个是迭代次数和学习率,需要调整这两个参数寻找最优拟合
  File "C:\Users\shiro\Desktop\digital image\PKLlook.py", line 189, in predict
    nn.forward_activation_02(L=len(nn.W), flag=0)  # 假设flag控制是否应用dropout
  File "C:\Users\shiro\Desktop\digital image\PKLlook.py", line 87, in forward_activation_02
    self.Z["Z" + str(l)] = self.W["W" + str(l)] * self.A["A" + str(l - 1)] + self.b["b" + str(l)]
  File "C:\Users\shiro\Desktop\01\python\lib\site-packages\numpy\matrixlib\defmatrix.py", line 218, in __mul__
    return N.dot(self, asmatrix(other))
  File "<__array_function__ internals>", line 200, in dot
ValueError: shapes (20,3) and (500,4) not aligned: 3 (dim 1) != 500 (dim 0)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 15:07:02 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 15:06
Traceback (most recent call last):
  File "C:\Use ...


从错误信息可以看出,问题出在执行矩阵乘法 `self.W * self.A` 时,因为矩阵的维度不匹配。 具体而言,`self.W` 的维度是 (20, 3

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-3 15:14:16 | 显示全部楼层
预测数据是不是让数据进行一次前向传播得到对应的值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 15:14:20 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 15:14
预测数据是不是让数据进行一次前向传播得到对应的值


是的,预测新数据时,你需要将数据输入神经网络,并进行一次前向传播来得到网络的输出。这个输出就是对新数据的预测结果。

关于保存和加载模型的问题:

1. **保存模型:

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-3 15:15:55 | 显示全部楼层
前向传播包括哪些部分
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 15:16:02 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 15:15
前向传播包括哪些部分


前向传播是神经网络训练过程中的第一步,用于计算输入到输出之间的变换,包括以下几个主要部分:

1. **输入层处理**:获取输入数据并将其传递给网络。通常在此

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-5 15:28:47 | 显示全部楼层
ImportError: Missing optional dependency 'xlrd'. Install xlrd >= 2.0.1 for xls Excel support Use pip or conda to install xlrd.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-5 15:39:14 | 显示全部楼层
ImportError: Missing optional dependency 'xlrd'. Install xlrd >= 2.0.1 for xls Excel support Use pip or conda to install xlrd.
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-5 15:44:44 | 显示全部楼层
FishC 发表于 2024-9-3 15:16
前向传播是神经网络训练过程中的第一步,用于计算输入到输出之间的变换,包括以下几个主要部分:

1. ...

ImportError: Missing optional dependency 'xlrd'. Install xlrd >= 2.0.1 for xls Excel support Use pip or conda to install xlrd.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-5 16:34:56 | 显示全部楼层
ShuviDoura 发表于 2024-09-05 15:44
ImportError: Missing optional dependency 'xlrd'. I ...


这是一个常见的问题,它表明你试图读取Excel文件,但缺少必要的依赖库`xlrd`。以下是解决这一问题的简单步骤:

## 安装 `xlrd` 库

你可以使用`pip`或`conda`来安装`xlrd`库:

### 使用 `pip`

打开你的命令行或者终端,然后输入以下命令:
pip install xlrd==2.0.1

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-5 16:44:54 | 显示全部楼层
ShuviDoura 发表于 2024-09-05 15:39
ImportError: Missing optional dependency 'xlrd'. I ...


鱼油,你好!

这个错误提示表示你在使用 Pandas 读取 Excel 文件时缺少 `xlrd` 这个库。解决方法如下:

### 使用 pip 安装 `xlrd`:
pip install xlrd>=2.0.1

### 使用 conda 安装 `xlrd`:
conda install -c anaconda xlrd

安装完成后,应当就能正常读取 Excel 文件了。如果问题依旧,记得检查一下你的代码和文件路径是否正确。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-5 17:23:02 | 显示全部楼层
FishC 发表于 2024-9-5 16:44
鱼油,你好!

这个错误提示表示你在使用 Pandas 读取 Excel 文件时缺少 `xlrd` 这个库。解决方法如 ...

没有用,还是错误
ImportError: Missing optional dependency 'xlrd'. Install xlrd >= 2.0.1 for xls Excel support Use pip or conda to install xlrd.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-5 17:23:11 | 显示全部楼层
ShuviDoura 发表于 2024-09-05 17:23
没有用,还是错误
ImportError: Missing optional de ...


鱼油,你好!

解决这个 `ImportError` 的问题,你可以按照以下步骤操作:

### 方法1:安装 `xlrd` 库

如果你需要读取 `.xls` 文件,可以通过 pip 安装 `xlrd`:
pip install xlrd==1.2.0

然而,请注意,`xlrd` 1.2.0 及以后版本不再支持 `.xlsx` 文件。如果你处理的是 `.xlsx` 文件,请参考方法2。

### 方法2:改用 `openpyxl` 库

Pandas 目前推荐使用 `openpyxl` 作为 `.xlsx` 文件的读取库:

1. 安装 `openpyxl`:
pip install openpyxl

2. 在你的代码中指定 `engine='openpyxl'`:
import pandas as pd

df = pd.read_excel('your_file.xlsx', engine='openpyxl')

### 方法3:重新安装 `xlrd` 2.0.1 及以上版本

再次尝试安装:
pip install xlrd --upgrade

你可以确保安装最新版本,符合错误提示中的版本要求。

### 检查安装状态

你可以通过以下方式检查是否安装成功:
pip show xlrd
pip show openpyxl

这会显示安装的版本信息,确保正确安装。

如果还有疑问,请告诉我错误信息以及你正在执行的具体代码片段,这样我可以为你提供更有针对性的帮助。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-9-5 19:48:19 | 显示全部楼层
FishC 发表于 2024-9-5 17:23
鱼油,你好!

解决这个 `ImportError` 的问题,你可以按照以下步骤操作:

ImportError: Missing optional dependency 'xlrd'.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-5 19:54:37 | 显示全部楼层
ShuviDoura 发表于 2024-09-05 19:48
ImportError: Missing optional dependency 'xlrd'.


好的,回到你的原始问题关于保存和加载神经网络模型的信息。为了保证你能够成功保存和恢复训练好的模型,我们接下来会添加代码保存权重(W)和偏置(b)的值,并提供如何加载它们的步骤。

### 保存模型

你应该保存 `W` 和 `b`。可以把它们存储为一个字典,然后使用 `pickle` 库保存到文件中。
import pickle

def save_model(model, filename):
    # 保存权重和偏置值
    model_data = {
        'W': model.W,
        'b': model.b,
    }
    with open(filename, 'wb') as f:
        pickle.dump(model_data, f)

# 假设你的模型实例化为 nn
save_model(nn, 'model_weights.pkl')

### 加载模型

从文件中加载权重和偏置,然后设置到你的模型中。
def load_model(model, filename):
    # 加载权重和偏置值
    with open(filename, 'rb') as f:
        model_data = pickle.load(f)
    model.W = model_data['W']
    model.b = model_data['b']

# 假设你的模型实例化为 nn
load_model(nn, 'model_weights.pkl')

### 示例

下面我会给你一个完整的示例,包括训练、保存模型和加载模型并在新数据上进行预测:

```python
import numpy as np
import pickle

class NN:
    def __init__(self, layers, data):
        L = len(layers)
        self.W = {}
        self.b = {}
        for

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-17 03:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表