python3+TensorFlow 2.x(四)反向传播

目录

反向传播算法

反向传播算法基本步骤:

反向中的参数变化

总结


反向传播算法

反向传播算法(Backpropagation)是训练人工神经网络时使用的一个重要算法,它是通过计算梯度并优化神经网络的权重来最小化误差。反向传播算法的核心是基于链式法则的梯度下降优化方法,通过计算误差对每个权重的偏导数来更新网络中的参数。

反向传播算法基本步骤:

前向传播:将输入数据传递通过神经网络的各层,计算每一层的输出。
计算损失:根据输出和实际标签计算损失(通常使用均方误差或交叉熵等作为损失函数)。
反向传播:根据损失函数对每个参数(如权重、偏置)计算梯度。梯度的计算通过链式法则进行反向传播,直到达到输入层。
更新权重:使用梯度下降算法来更新每一层的权重和偏置,使得损失函数最小化。

链式推到:https://blog.csdn.net/dingyahui123/category_6945552.html?spm=1001.2014.3001.5482

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.datasets import mnist
# 加载 MNIST 数据集
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 归一化数据并将其形状调整为 (N, 784),因为每张图片是 28x28 像素
train_images = train_images.reshape(-1, 28*28) / 255.0
test_images = test_images.reshape(-1, 28*28) / 255.0

# 转换标签为 one-hot 编码
train_labels = np.eye(10)[train_labels]
test_labels = np.eye(10)[test_labels]
# 定义激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 定义激活函数的导数
def sigmoid_derivative(x):
    return x * (1 - x)

# 网络架构参数
input_size = 28 * 28  # 输入层的大小
hidden_size = 128     # 隐藏层的大小
output_size = 10      # 输出层的大小

# 初始化权重和偏置
W1 = np.random.randn(input_size, hidden_size)  # 输入层到隐藏层的权重
b1 = np.zeros((1, hidden_size))  # 隐藏层的偏置
W2 = np.random.randn(hidden_size, output_size)  # 隐藏层到输出层的权重
b2 = np.zeros((1, output_size))  # 输出层的偏置
# 设置超参数
epochs = 20
learning_rate = 0.1
batch_size = 64

# 训练过程
for epoch in range(epochs):
    for i in range(0, len(train_images), batch_size):
        # 选择当前batch的数据
        X_batch = train_images[i:i+batch_size]
        y_batch = train_labels[i:i+batch_size]
        
        # 前向传播
        z1 = np.dot(X_batch, W1) + b1
        a1 = sigmoid(z1)
        z2 = np.dot(a1, W2) + b2
        a2 = sigmoid(z2)
        
        # 计算损失的梯度
        output_error = a2 - y_batch  # 损失函数的梯度
        output_delta = output_error * sigmoid_derivative(a2)
        
        hidden_error = output_delta.dot(W2.T)
        hidden_delta = hidden_error * sigmoid_derivative(a1)
        
        # 更新权重和偏置
        W2 -= learning_rate * a1.T.dot(output_delta)
        b2 -= learning_rate * np.sum(output_delta, axis=0, keepdims=True)
        W1 -= learning_rate * X_batch.T.dot(hidden_delta)
        b1 -= learning_rate * np.sum(hidden_delta, axis=0, keepdims=True)
    
    # 每10轮输出一次损失
    if epoch % 10 == 0:
        loss = np.mean(np.square(a2 - y_batch))
        print(f"Epoch {epoch}, Loss: {loss}")
# 测试模型
z1 = np.dot(test_images, W1) + b1
a1 = sigmoid(z1)
z2 = np.dot(a1, W2) + b2
a2 = sigmoid(z2)

# 计算准确率
predictions = np.argmax(a2, axis=1)
true_labels = np.argmax(test_labels, axis=1)
accuracy = np.mean(predictions == true_labels)

print(f"Test Accuracy: {accuracy * 100:.2f}%")
# 可视化前5个测试图像及其预测结果
for i in range(5):
    plt.imshow(test_images[i].reshape(28, 28), cmap='gray')
    plt.title(f"Predicted: {predictions[i]}, Actual: {true_labels[i]}")
    plt.show()

 

反向中的参数变化

import numpy as np
import matplotlib.pyplot as plt
import imageio

# 激活函数和其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

# 生成一些示例数据
np.random.seed(0)
X = np.array([[0, 0],
              [0, 1],
              [1, 0],
              [1, 1]])
y = np.array([[0], [1], [1], [0]])  # XOR 问题

# 初始化参数
input_layer_neurons = 2
hidden_layer_neurons = 2
output_neurons = 1
learning_rate = 0.5
epochs = 10000

# 初始化权重
weights_input_hidden = np.random.uniform(size=(input_layer_neurons, hidden_layer_neurons))
weights_hidden_output = np.random.uniform(size=(hidden_layer_neurons, output_neurons))

# 存储权重和图像
weights_history = []
losses = []
images = []

# 训练过程
for epoch in range(epochs):
    # 前向传播
    hidden_layer_input = np.dot(X, weights_input_hidden)
    hidden_layer_output = sigmoid(hidden_layer_input)
    
    output_layer_input = np.dot(hidden_layer_output, weights_hidden_output)
    predicted_output = sigmoid(output_layer_input)
    
    loss = np.mean((y - predicted_output) ** 2)
    losses.append(loss)

    # 反向传播
    error = y - predicted_output
    d_predicted_output = error * sigmoid_derivative(predicted_output)
    
    error_hidden_layer = d_predicted_output.dot(weights_hidden_output.T)
    d_hidden_layer = error_hidden_layer * sigmoid_derivative(hidden_layer_output)
    
    # 更新权重
    weights_hidden_output += hidden_layer_output.T.dot(d_predicted_output) * learning_rate
    weights_input_hidden += X.T.dot(d_hidden_layer) * learning_rate
    
    # 保存权重
    weights_history.append((weights_input_hidden.copy(), weights_hidden_output.copy()))
    
    # 每1000次迭代保存一次图像
    if epoch % 1000 == 0:
        plt.figure(figsize=(8, 6))
        plt.subplot(1, 2, 1)
        plt.title('Weights Input-Hidden')
        plt.imshow(weights_input_hidden, cmap='viridis', aspect='auto')
        plt.colorbar()
        
        plt.subplot(1, 2, 2)
        plt.title('Weights Hidden-Output')
        plt.imshow(weights_hidden_output, cmap='viridis', aspect='auto')
        plt.colorbar()
        
        # 保存图像
        plt.savefig(f'weights_epoch_{epoch}.png')
        plt.close()
    if epoch % 1000 == 0:
        plt.figure(figsize=(8, 6))
        plt.plot(losses, label='Loss')
        plt.title('Loss over epochs')
        plt.xlabel('Epochs')
        plt.ylabel('Loss')
        plt.xlim(0, epochs)
        plt.ylim(0, np.max(losses))
        plt.grid()
        plt.legend()
        
        # 保存图像
        plt.savefig(f'loss_epoch_{epoch}.png')
        plt.close()
# 创建 GIF
with imageio.get_writer('weights_update.gif', mode='I', duration=0.5) as writer:
    for epoch in range(0, epochs, 1000):
        image = imageio.imread(f'weights_epoch_{epoch}.png')
        writer.append_data(image)
# 创建 GIF
with imageio.get_writer('training_loss.gif', mode='I', duration=0.5) as writer:
    for epoch in range(0, epochs, 1000):
        image = imageio.imread(f'loss_epoch_{epoch}.png')
        writer.append_data(image)
# 清理生成的图像文件
import os
for epoch in range(0, epochs, 1000):
    os.remove(f'weights_epoch_{epoch}.png')
    os.remove(f'loss_epoch_{epoch}.png')

print("GIF 已生成:training_loss.gif")
print("GIF 已生成:weights_update.gif")

 

总结

反向传播算法是神经网络训练中的核心技术,它通过计算损失函数相对于每个权重和偏置的梯度,利用梯度下降算法优化网络的参数。理解了反向传播的基本过程,可以进一步扩展到更复杂的网络结构,如卷积神经网络(CNN)和循环神经网络(RNN)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959577.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习 Pytorch 单层神经网络

神经网络是模仿人类大脑结构所构建的算法,在人脑里,我们有轴突连接神经元,在算法中,我们用圆表示神经元,用线表示神经元之间的连接,数据从神经网络的左侧输入,让神经元处理之后,从右…

使用vscode + Roo Code (prev. Roo Cline)+DeepSeek-R1使用一句话需求做了个实验

摘要 使用vscode、Roo Code和deepseek-reasoner进行了一个实验,尝试使用一句话需求来生成小红书封面图片。工具根据需求提供了详细的架构方案,包括技术栈选择、核心模块划分、目录结构建议等。然后,工具自动化地完成了开发和测试,…

微服务搭建----springboot接入Nacos2.x

springboot接入Nacos2.x nacos之前用的版本是1.0的,现在重新搭建一个2.0版本的,学如逆水行舟,不进则退,废话不多说,开搞 1、 nacos2.x搭建 1,首先第一步查询下项目之间的版本对照,不然后期会…

TDengine 与上海电气工业互联网平台完成兼容性认证

在工业数字化转型和智能化升级的浪潮中,企业对高效、可靠的数据管理解决方案的需求日益增长。特别是在风电智能运维、火电远程运维、机床售后服务等复杂多样的工业场景下,如何实现海量设备和时序数据的高效管理,已经成为推动行业升级的关键。…

“大模型横扫千军”背后的大数据挖掘--浅谈MapReduce

文章目录 O 背景知识1 数据挖掘2 邦费罗尼原则3 TF.IDF4 哈希函数5 分布式文件系统 一、MapReduce基本介绍1. Map 任务2. 按键分组3. Reduce 任务4. 节点失效处理5.小测验:在一个大型语料库上有100个map任务和若干reduce任务: 二、基于MapReduce的基本运…

25美赛ABCDEF题详细建模过程+可视化图表+参考论文+写作模版+数据预处理

详情见该链接!!!!!! 25美国大学生数学建模如何准备!!!!!-CSDN博客文章浏览阅读791次,点赞13次,收藏7次。通过了解比赛基本…

Python:元组构造式和字典推导式

(Python 元组构造式和字典推导式整理笔记) 1. 元组构造式 1.1 创建元组 使用圆括号: tuple1 (1, 2.5, (three, four), [True, 5], False) print(tuple1) # 输出: (1, 2.5, (three, four), [True, 5], False) 省略圆括号: tup…

appium自动化环境搭建

一、appium介绍 appium介绍 appium是一个开源工具、支持跨平台、用于自动化ios、安卓手机和windows桌面平台上面的原生、移动web和混合应用,支持多种编程语言(python,java,Ruby,Javascript、PHP等) 原生应用和混合应用&#xf…

vue3组件el-table报错

传给table标签的data不是数组就会报错, 摁着商品管理代码找了半天也没发现哪里错了,而且关闭报错表格数据能正常显示, 。。。 最后发现我还有个订单管理页面,这里面的data初始化成ref( )了,把这个组件注释掉&#xf…

基于SpringBoot+WebSocket的前后端连接,并接入文心一言大模型API

前言: 本片博客只讲述了操作的大致流程,具体实现步骤并不标准,请以参考为准。 本文前提:熟悉使用webSocket 如果大家还不了解什么是WebSocket,可以参考我的这篇博客: rWebSocket 详解:全双工…

《边界感知的分而治之方法:基于扩散模型的无监督阴影去除解决方案》学习笔记

paper:Boundary-Aware Divide and Conquer: A Diffusion-Based Solution for Unsupervised Shadow Removal 目录 摘要 1、介绍 2、相关工作 2.1 阴影去除 2.2 去噪扩散概率模型(Denoising Diffusion Probabilistic Models, DDPM) 3、方…

linux-mysql在centos7安装和基础配置

1.安装mysql数据库 1.使用官网安装 1.检查是否存在mysql的分支mariadb [rootlocalhost ~]# rpm -qa |grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 [rootlocalhost ~]# 2.卸载这个分支包 [rootlocalhost ~]# rpm -qa | grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 …

Python!从0开始学爬虫:(一)HTTP协议 及 请求与响应

前言 爬虫需要基础知识,HTTP协议只是个开始,除此之外还有很多,我们慢慢来记录。 今天的HTTP协议,会有助于我们更好的了解网络。 一、什么是HTTP协议 (1)定义 HTTP(超文本传输协议&#xff…

MySQL数据库笔记——最左前缀原则原理及其注意事项

大家好,这里是Good Note,关注 公主号:Goodnote,专栏文章私信限时Free。本文详细介绍MySQL索引的关键潜规则——最左前缀原则。 文章目录 图示单值索引和联合索引单值索引联合索引 最左前缀原则示例分析1. 全值匹配查询时2. 匹配左…

Java数据结构 (链表反转(LinkedList----Leetcode206))

1. 链表的当前结构 每个方框代表一个节点,每个节点包含两个部分: 左侧的数字:节点存储的值,例如 45、34 等。右侧的地址(如 0x90):表示该节点 next 指针指向的下一个节点的内存地址。 例子中&a…

IMX6ull项目环境配置

文件解压缩: .tar.gz 格式解压为 tar -zxvf .tar.bz2 格式解压为 tar -jxvf 2.4版本后的U-boot.bin移植进SD卡后,通过串口启动配置开发板和虚拟机网络。 setenv ipaddr 192.168.2.230 setenv ethaddr 00:04:9f:…

git基础指令大全

版本控制 git管理文件夹 进入要管理的文件夹 — 进入 初始化(提名) git init 管理文件夹 生成版本 .git ---- git在管理文件夹时,版本控制的信息 生成版本 git status 检测当前文件夹下的文件状态 (检测,检测之后就要管理了…

[高等数学学习记录]函数的极值与最大值最小值

1 知识点 1.1 函数的极值及其求法 定义 设函数 f ( x ) f(x) f(x) 在点 x 0 x_0 x0​ 的某邻域 U ˚ ( x 0 ) \mathring{U}(x_0) U˚(x0​) 内有定义&#xff0c;如果对于去心邻域 U ˚ ( x 0 ) \mathring{U}(x_0) U˚(x0​) 内的任一 x x x&#xff0c;有 f ( x ) <…

docker 简要笔记

文章目录 一、前提内容1、docker 环境准备2、docker-compose 环境准备3、流程说明 二、打包 docker 镜像1、基础镜像2、国内镜像源3、基础的dockerfile4、打包镜像 四、构建运行1、docker 部分2、docker-compose 部分2.1、构建docker-compose.yml2.1.1、同目录构建2.1.2、利用镜…

JVM常见知识点

在《深入理解Java虚拟机》一书中&#xff0c;介绍了JVM的相关特性。 1、JVM的内存区域划分 在真实的操作系统中&#xff0c;对于地址空间进行了分区域的设计&#xff0c;由于JVM是仿照真实的机器进行设计的&#xff0c;那么也进行了分区域的设计。核心区域有四个&#xff0c;…