鱼C论坛

 找回密码
 立即注册
查看: 6451|回复: 177

[已解决]关于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`来保存为文件。这里是一个简单的方法:

  1. import pickle

  2. def save_model(nn, filename):
  3.     with open(filename, 'wb') as file:
  4.         model_parameters = {
  5.             'W': nn.W,
  6.             'b': nn.b
  7.         }
  8.         pickle.dump(model_parameters, file)
复制代码


### 加载模型:

加载模型时,我们需要从文件中恢复权重和偏置:

  1. def load_model(filename):
  2.     with open(filename, 'rb') as file:
  3.         model_parameters = pickle.load(file)
  4.     nn = NN()  # 假设有适当的构造函数
  5.     nn.W = model_parameters['W']
  6.     nn.b = model_parameters['b']
  7.     return nn
复制代码


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

一旦模型加载完毕,你可以使用神经网络的前馈方法进行预测:

  1. def predict(nn, input_data):
  2.     nn.inputs = input_data
  3.     nn.forward_activation_02(L=len(nn.W), flag=0)  # 假设flag控制是否应用dropout
  4.     return nn.A  # 返回最终的预测结果
复制代码


### 注意事项:

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2025-2-3 19:39:00 | 显示全部楼层

打包exe时报错

Syntax error in C:\Users\shiro\AppData\Local\Temp\pyyuan.py4715089335117228588\.idea\pyyuan.py4715089335117228588.iml
  File "C:\Users\shiro\AppData\Local\Temp\pyyuan.py4715089335117228588\.idea\pyyuan.py4715089335117228588.iml", line 1
     <?xml version="1.0" encoding="UTF-8"?>
     ^
SyntaxError: invalid syntax
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-12-12 16:01:21 | 显示全部楼层
如果我在bp神经网络种采用relu函数作为激活函数,那么我的fackbeed的残差应该怎么算
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-12-11 10:01:54 | 显示全部楼层
bp神经网络种,这一部分是什么意思     
def calc(self, sample):
        self.sample = sample[:]
        partsum = sum([i * j for i, j in zip(self.sample, self.weight)]) - self.threshold
        self.output = sigmoid(partsum)
        return self.output
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-12-10 21:26:37 | 显示全部楼层
我要进行多分类,那么sigmoid和dsigmoid函数可以将一下换成什么
def sigmoid(x):
    return math.tanh(x)

def dsigmoid(y):
    return (1.0 - y**2)
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-12-10 20:08:40 | 显示全部楼层
读取csv转化为列表
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-28 15:27:51 | 显示全部楼层
FishC 发表于 2024-11-27 22:45
要整体替换 NumPy 数组中的数字,可以使用布尔索引或条件赋值。以下是一些常见的方法:

1. **整体替 ...

读取excel并把所有的数变成一列
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 22:45:33 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 22:37
怎么整体替换np矩阵中的数字


要整体替换 NumPy 数组中的数字,可以使用布尔索引或条件赋值。以下是一些常见的方法:

1. **整体替换所有符合条件的元素:**

假设你有一个 NumPy 数组 `arr`,你可以将其中小于某个值的元素替换为另一个值:

  1. import numpy as np

  2. # 示例 NumPy 数组
  3. arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

  4. # 将所有小于 5 的数替换为 0
  5. arr[arr < 5] = 0

  6. print(arr)
复制代码


2. **把某特定值替换为另一值:**

如果你知道要替换的特定值,可以使用 `np.where`:

  1. # 将数组中的所有 5 替换为 50
  2. arr = np.where(arr == 5, 50, arr)

  3. print(arr)
复制代码


这两种方法都允许你对 NumPy 数组进行元素级别的替换,具体取决于条件。根据你的需要选择适合的方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 22:44:20 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 22:43
怎么整体替换np矩阵中的数字
@FishC


要整体替换 NumPy 矩阵中的数字,可以使用 NumPy 的数组操作功能。以下是一个简单的示例,假设我们要将矩阵中的某个数字替换成另一个数字:

  1. import numpy as np

  2. # 创建一个 NumPy 矩阵
  3. matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

  4. # 使用 np.where 替换数字
  5. # 例如:将矩阵中的数字 5 替换为 0
  6. matrix = np.where(matrix == 5, 0, matrix)

  7. print(matrix)
复制代码


解释:
- `np.where(condition, x, y)` 函数用于根据条件选择数组的元素。
- 在本例中,`matrix == 5` 生成一个布尔矩阵,标识出等于 5 的位置。
- `np.where` 将在条件为 `True` 的位置使用 `x`(这里是 0)替换原来的值。

这样你就可以替换整个矩阵中的某个数字了。如果需要替换其他数字或者多个数字,可以调整条件和替换的值。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 22:43:37 | 显示全部楼层
FishC 发表于 2024-11-27 21:32
要使用 OpenCV 的 `cv2.resize()` 函数来缩放图像,你需要指定目标尺寸(宽度和高度)。以下是如何使用 ...

怎么整体替换np矩阵中的数字
@FishC
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 22:37:58 | 显示全部楼层
FishC 发表于 2024-11-27 21:31
`cv2.resize()` 函数用于缩放图像。要指定目标尺寸为 160x160 像素,可以通过设定 `dsize` 参数。以下 ...

怎么整体替换np矩阵中的数字
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 21:32:00 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 21:30
# 设定缩放后的尺寸resize怎么用


要使用 OpenCV 的 `cv2.resize()` 函数来缩放图像,你需要指定目标尺寸(宽度和高度)。以下是如何使用 `resize` 方法来将图像缩放到 160x160 像素的步骤:

  1. import cv2

  2. # 读取图像
  3. image_path = 'path_to_your_image.jpg'
  4. image = cv2.imread(image_path)

  5. # 设定缩放后的尺寸
  6. target_size = (160, 160)  # 第一个参数是宽度,第二个是高度

  7. # 使用 cv2.resize() 函数进行缩放
  8. resized_image = cv2.resize(image, target_size, interpolation=cv2.INTER_LINEAR)

  9. # 显示缩放后的图片(可选)
  10. cv2.imshow('Resized Image', resized_image)
  11. cv2.waitKey(0)
  12. cv2.destroyAllWindows()

  13. # 保存缩放后的图片(可选)
  14. cv2.imwrite('resized_image.jpg', resized_image)
复制代码


在 `cv2.resize()` 中,`interpolation=cv2.INTER_LINEAR` 是用于插值的方法,你可以根据需要选择不同的插值方式,如 `cv2.INTER_NEAREST`、`cv2.INTER_CUBIC` 等。希望这个方法对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 21:31:25 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 21:30
# 设定缩放后的尺寸resize怎么用


`cv2.resize()` 函数用于缩放图像。要指定目标尺寸为 160x160 像素,可以通过设定 `dsize` 参数。以下是一个具体的例子:

  1. import cv2

  2. # 读取图像
  3. image_path = 'path/to/your/image.jpg'
  4. image = cv2.imread(image_path)

  5. # 设定缩放后的尺寸
  6. resize_dims = (160, 160)

  7. # 缩放图像
  8. resized_image = cv2.resize(image, resize_dims)

  9. # 保存缩放后的图像
  10. cv2.imwrite('resized_image.jpg', resized_image)

  11. # 或者显示缩放后的图像
  12. cv2.imshow('Resized Image', resized_image)
  13. cv2.waitKey(0)
  14. cv2.destroyAllWindows()
复制代码


在这个例子中,`resize_dims` 是目标尺寸 `(160, 160)`,传递给 `cv2.resize()` 函数以调整图像大小。这样,你可以将任何图像调整为所需的目标大小。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 21:31:22 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 21:31
设定缩放后的尺寸resize怎么用


要使用OpenCV将图像缩放到指定的尺寸(例如160x160像素),可以通过`cv2.resize()`函数实现。下面是一个简单的代码示例:

  1. import cv2

  2. # 读取图像
  3. image_path = 'your_image.jpg'  # 将 'your_image.jpg' 替换为你的图像文件名
  4. image = cv2.imread(image_path)

  5. # 设定缩放后的尺寸
  6. resize_dimensions = (160, 160)

  7. # 调用cv2.resize()进行缩放
  8. resized_image = cv2.resize(image, resize_dimensions)

  9. # 保存或显示缩放后的图像
  10. cv2.imwrite('resized_image.jpg', resized_image)  # 保存到文件
  11. cv2.imshow('Resized Image', resized_image)  # 显示图像
  12. cv2.waitKey(0)  # 等待按键
  13. cv2.destroyAllWindows()
复制代码


### 说明:
- `cv2.imread(image_path)`: 读取图像文件。
- `resize_dimensions = (160, 160)`: 指定目标尺寸为160x160像素。
- `cv2.resize(image, resize_dimensions)`: 将图像缩放到指定尺寸。
- `cv2.imwrite()` 和 `cv2.imshow()`: 分别用于保存和显示缩放后的图像。

请根据需要替换文件路径和文件名。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 21:31:12 | 显示全部楼层
FishC 发表于 2024-11-27 21:29
要使用OpenCV将图片缩放到160x160像素,可以使用 `cv2.resize()` 方法。以下是一个简单的示例:

imp ...

设定缩放后的尺寸resize怎么用
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 21:30:02 | 显示全部楼层
FishC 发表于 2024-11-27 21:29
要使用OpenCV将图片缩放到160x160像素,可以使用 `cv2.resize()` 方法。以下是一个简单的示例:

imp ...

# 设定缩放后的尺寸resize怎么用
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 21:29:07 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 21:28
我想用opencv将图片压缩为160×160像素,怎么写


要使用OpenCV将图片缩放到160x160像素,可以使用 `cv2.resize()` 方法。以下是一个简单的示例:

import cv2

# 读取图像
image_path =
image = cv2.imread(image_path)

# 设定缩放后的尺寸
resize

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 21:28:50 | 显示全部楼层
FishC 发表于 2024-11-27 21:15
@鱼油

看起来你指的是在一个值不大于4的矩阵中,将其每个元素乘以100的情况。出现44的情况可能是因 ...

我想用opencv将图片压缩为160×160像素,怎么写
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-27 21:15:24 | 显示全部楼层
ShuviDoura 发表于 2024-11-27 21:14
我意思是在一个矩阵bnp中,每个数的值都不大于4,但为 ...


@鱼油

看起来你指的是在一个值不大于4的矩阵中,将其每个元素乘以100的情况。出现44的情况可能是因为矩阵`bnp`中的某个值实际上是0.44而不是整数。这种情况可能是由于浮点数或者矩阵初始化时引入的误差导致的。

建议检查以下几点:
1. **检查矩阵数据类型**:确认`bnp`中的数据类型是否为整数,如`int`,以避免浮点运算的问题。
2. **输出具体数值**:打印输出`bnp`矩阵的具体值,核实是否有类似0.44或其他非整数的小数存在。
3. **浮点误差**:若数据类型确实为浮点数,需要考虑浮点数计算中可能出现的误差。

通过这些检查,应该可以找到问题的根源。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 21:14:13 | 显示全部楼层
FishC 发表于 2024-11-27 21:08
看到输出中包含 `[ ]` 表示整个数组,而闭合符号 `...` 表示省略了一部分数据,因为数组过大时,Python ...

我意思是在一个矩阵bnp中,每个数的值都不大于4,但为什么bnp*100的值中却出现了44,而不是0,100,200,300这三个数
@FishC
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-11-27 21:10:53 | 显示全部楼层
FishC 发表于 2024-11-27 21:08
看到输出中包含 `[ ]` 表示整个数组,而闭合符号 `...` 表示省略了一部分数据,因为数组过大时,Python ...

我意思是在一个矩阵bnp中,每个数的值都不大于4,但为什么bnp*100的值中却出现了44
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-28 04:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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