鱼C论坛

 找回密码
 立即注册
查看: 863|回复: 17

[技术交流] 关于bp神经网络的问题

[复制链接]
发表于 2024-9-3 10:18:14 | 显示全部楼层 |阅读模式
60鱼币
我从网上抄了一个代码,但是其中不包含保存模型与加载模型的步骤,那么在这个代码中,我是应该保存W和b的值,还是A和Z的值作为训练模型之后后的保存数据,wb和az各自都是什么,cache又是什么
还有一个问题
# 各层网络神经元的参数
layers = [feature_num, 20, 15, 1]
L = len(layers)
我在定义这个[feature_num, 20, 15, 1]的时候,这四个数据是不是表示我有一个输入层两个含隐藏以及一个输出层吗


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_

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:18:26 | 显示全部楼层
关于您的问题,我来逐一回答:

### 1. 保存模型的内容

在BP神经网络中,您需要保存的是模型的**参数**,即权重(W)和偏置(b)。这是因为这些参数定义了您的网络在训练后的状态。激活值(A)和未激活值(Z)是动态的,它们在每次输入新的数据进行前向传播时都会变化,因此不需要保存。以下是一些解释:

- **W(权重):** 网络中连接两个神经元层之间的权重,这些是你需要训练的内容。
- **b(偏置):** 每个神经元附加的一个固定偏移量,也是需要训练的参数。

### 2. cache 的作用

`cache` 通常用来存储在前向传播过程中计算的中间值(如 `Z` 和 `A`),以便在进行反向传播时可以高效地计算梯度。它不需要保存,因为它只是在一次前向和后向传播中使用。

### 3. 定义网络层次的问题

您提到的 `layers` 列表定义了每一层的神经元数量:
layers = [输入层神经元数, 第一个隐藏层神经元数, …, 输出层神经元数]
L = len(layers)  # 表示层数,总共 L 层

如果 `layers` 包含4个元素,例如 `[3, 5, 5, 1]`,这表示一个输入层、两个隐藏层和一个输出层。输入层有3个神经元,第一个隐藏层有5个神经元,第二个隐藏层也有5个神经元,输出层有1个神经元。

### 关于代码中的错误

看起来在您的代码中,有一些地方的写法可能不对,比如:
self.W = np.mat(np.random.randn(layers, layers) * 0.1)
self.b = np.mat(np.random.randn(layers, 1) * 0.1)

`layers` 应该是一个列表,你在定义权重和偏置时应使用 `layers[l-1]` 和 `layers[l]`,例如:
self.W[l] = np.random.randn(layers[l], layers[l-1]) * 0.1
self.b[l] = np.random.randn(layers[l], 1) * 0.1

这样做才能创建正确维度的矩阵。

希望这些解释能够帮助您理解代码和BP神经网络。如果还有其他问题,请随时问!

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

使用道具 举报

 楼主| 发表于 2024-9-3 10:29:21 | 显示全部楼层
那么我的保存模型是这样写的吗
    def save_model(self, file_path):
        model_data = {
            "weights": self.W,
            "bias": self.b,
        }
        with open(file_path, 'wb') as f:
            pickle.dump(model_data, f)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:29:30 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 10:29
那么我的保存模型是这样写的吗
    def save_model(s ...


是的,您编写的 `save_model` 方法大致是正确的,不过有一点需要注意:在初始化中,`self.W` 和 `self.b` 在定义时使用的是单个矩阵,而不是字典。因此

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

使用道具 举报

 楼主| 发表于 2024-9-3 10:30:31 | 显示全部楼层
那么我要如何读取模型并预测新的输入数据值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:30:37 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 10:30
那么我要如何读取模型并预测新的输入数据值


在你的神经网络实现中,要保存和加载模型,关键是要保存和恢复模型的权重 `W` 和偏置 `b`。这些参数定义了模型在每层中的连接和激活函数的偏移

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

使用道具 举报

 楼主| 发表于 2024-9-3 10:31:41 | 显示全部楼层
FishC 发表于 2024-9-3 10:30
在你的神经网络实现中,要保存和加载模型,关键是要保存和恢复模型的权重 `W` 和偏置 `b`。这些参数定 ...

我加载模型之后,要怎么处理新的输入值,达到预测新的数据的目的
这一部分代码要怎么写
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:31:44 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 10:31
我加载模型之后,要怎么处理新的输入值,达到预测新的 ...


关于您的问题:

### 保存和加载模型

在神经网络中,你一般需要保存和加载权重 (`W`) 和偏置 (`b`) 参数。`A` 和 `Z` 是激活值和未激活的

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

使用道具 举报

 楼主| 发表于 2024-9-3 10:42:06 | 显示全部楼层
我保存得到的W1和W2和 W3的数量为什么不一样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 10:48:51 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 10:42
我保存得到的W1和W2和 W3的数量为什么不一样


在您的代码中,`W1`、`W2` 和 `W3` 分别代表不同层之间的权重矩阵。不同层之间的神经元个数不同,因此权重矩阵的尺寸也会

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

使用道具 举报

 楼主| 发表于 2024-9-3 15:03:05 | 显示全部楼层
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:03:10 | 显示全部楼层
ShuviDoura 发表于 2024-09-03 15:03
Traceback (most recent call last):
  File "C:\Use ...


根据错误信息,`ValueError: shapes (20,3) and (500,4) not aligned: 3 (dim 1) != 500 (dim 0)`,出现这个问题的原因是矩阵相乘时

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

使用道具 举报

 楼主| 发表于 2024-10-23 17:16:12 | 显示全部楼层
import pandas as pd

df = pd.read_csv('111111.csv')
报错
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-10-23 17:17:06 | 显示全部楼层

C:\Users\shiro\Desktop\01\conda\envs\sky01\lib\site-packages\numpy\__init__.py:142: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
  from . import _distributor_init
Traceback (most recent call last):
  File "C:\Users\shiro\Desktop\01\liubian shiyan shujvchuli\date.py", line 1, in <module>
    import pandas as pd
  File "C:\Users\shiro\Desktop\01\conda\envs\sky01\lib\site-packages\pandas\__init__.py", line 16, in <module>
    raise ImportError(
ImportError: Unable to import required dependencies:
numpy:

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.8 from "C:\Users\shiro\Desktop\01\conda\envs\sky01\python.exe"
  * The NumPy version is: "1.22.3"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: No module named 'numpy.core._multiarray_umath'

ERROR conda.cli.main_run:execute(49): `conda run python C:\Users\shiro\Desktop\01\liubian shiyan shujvchuli\date.py` failed. (See above for error)
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-10-23 17:18:17 | 显示全部楼层
ShuviDoura 发表于 2024-10-23 17:17
C:\Users\shiro\Desktop\01\conda\envs\sky01\lib\sit ...


这个问题通常是由于 NumPy 安装不完整或版本不兼容导致的。以下是一些解决方案:

1. **重新安装 NumPy**:
   打开命令提示符或终端,激活 `sky01` 环境,然后运行:
conda install numpy

2. **安装 mkl-service**:
   在同样的环境中运行:
conda install mkl-service

3. **检查兼容性**:
   确认你正在使用的 Python、NumPy 和 Pandas 的版本是兼容的。你可以尝试更新或降级这些包以确保兼容性。

4. **清除并重建环境**:
   如果问题仍然存在,你可以考虑删除并重新创建 conda 环境:
conda remove --name sky01 --all
   conda create --name sky01 python=3.8
   conda activate sky01
   conda install numpy pandas

按照以上步骤操作,问题应该能得到解决。如仍有问题,请检查 NumPy 官方提供的 [故障排除文档](https://numpy.org/devdocs/user/troubleshooting-importerror.html)。

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

使用道具 举报

发表于 2024-10-23 17:21:35 | 显示全部楼层
ShuviDoura 发表于 2024-10-23 17:16
import pandas as pd

df = pd.read_csv('111111.cs ...


如果读取CSV文件时出错,可以尝试以下步骤:

1. **检查文件路径**:确保文件路径正确。如果 `111111.csv` 不在当前目录,请提供完整路径。

df = pd.read_csv('完整路径/111111.csv')

2. **文件是否存在**:确保文件名和路径正确,文件确实存在。

3. **文件格式**:确保文件是有效的CSV格式,可以尝试用文本编辑器查看内容是否正常。

4. **编码问题**:可能是编码问题,尝试指定编码,例如 `utf-8` 或 `gbk`。

df = pd.read_csv('111111.csv', encoding='utf-8')

5. **权限问题**:确保有读取该文件的权限。

如果问题仍然存在,请提供更具体的错误信息以便进一步帮助。

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

使用道具 举报

 楼主| 发表于 2024-11-6 15:19:36 | 显示全部楼层
FishC 发表于 2024-10-23 17:21
如果读取CSV文件时出错,可以尝试以下步骤:

1. **检查文件路径**:确保文件路径正确。如果 `111111 ...

传统的图像识别(选择特征,然后使用分类器分类)和现在流行的卷积神经网络、bp神经网络、深度学习这些有什么本质上的区别
@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-11-6 15:45:06 | 显示全部楼层
ShuviDoura 发表于 2024-11-06 15:19
传统的图像识别(选择特征,然后使用分类器分类)和现 ...


传统的图像识别和现代的深度学习方法在处理图像的方式上有几点关键区别:

1. **特征提取**:
   - 传统方法:需要人工设计和选择特征。例如边缘、颜色、形状等。特征提取往往依赖于专家的经验。
   - 深度学习(如卷积神经网络,CNN):自动地从数据中学习特征,能够从低级别到高级别自动提取特征,不需要人工干预。

2. **特征的层次结构**:
   - 传统方法:通常特征提取和分类是分开的两步,不具备层次性。
   - 深度学习:使用多层神经元网络自动构建复杂的特征层次结构,特征提取与分类过程合为一体。

3. **处理能力和表现**:
   - 传统方法:在简单或特定的任务上表现良好,但面对复杂的任务效果有限。
   - 深度学习:由于层次化特征学习和庞大的参数量,能在复杂的高维数据上取得优异表现,尤其在大样本、大数据下表现突出。

4. **训练过程**:
   - 传统方法:通常使用预定义的分类器,例如支持向量机(SVM)、决策树等进行分类。
   - 深度学习:使用梯度下降等方法,通过反向传播(例如BP神经网络)来训练多层网络,不断优化参数。

5. **需求的计算资源**:
   - 传统方法:通常计算量较小,能够在普通计算机上运行。
   - 深度学习:由于模型的复杂性和数据量大,往往需要强大的计算能力(如GPU)和大量数据。

综上,深度学习的方法提供了一种强大而灵活的端到端学习方式,能够自动提取特征并进行分类,大大提升图像识别的效率和准确性。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 14:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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