深度学习笔记1:神经网络与模型训练过程

参考博客:PyTorch深度学习实战(1)------神经网络与模型训练过程详解_pytorch 实战-CSDN博客

人工神经网络

ANN:张量及数学运算的集合,排列方式近似于松散的人脑神经元排列

组成

1)输入层

2)隐藏层(中间层):连接输入层和输出层,在输入数据上执行转换,此外隐藏层利用神经元将输入值修改为更高、更低维的值,通过修改中间结点的激活函数可以实现复杂表示函数

3)输出层

训练

本质就是通过重复前向传播和后向传播两个关键步骤来调整神经网络的参数

前向传播--》输入经过隐藏层的到输出结果,第一次正向传播 权重初始化 计算预测值

后向传播--》根据误差相应调整权重来减小误差 修正参数

神经网络重复正向传播与反向传播以预测输出,指导获得令误差较小的权重为止

前向传播

1)输入值乘以权重计算隐藏层值

2)计算激活值

3)在每个神经元上重复前两个步骤,直到输出层

4)计算loss

封装为函数

python 复制代码
def forward(inputs,outputs,weights):#如果是首次迭代,随机初始化
    pre_hidden = np.dot(inputs,weights[0]) + weights[1]#向量点积
    hidden = 1/(1+np.exp(-pre_hidden))#sigmoid激活函数
    pred_out = np.dot(hidden,weights[2]) + weights[3]#计算输出
    mse = np.mean(np.square(pred_out - outputs))#loss
    return mse

反向传播

与前向传播相反,利用从前向传播中计算的损失值,以最小化损失值为目标更新网络权重

1)每次对神经网络中的每个权重进行少量修改

2)测量权重变化时的损失变化 ---》损失值关于权重的梯度

3)计算-α δL/δW 更新权重 α为学习率

如果改变权重损失变化大那么就大幅更新权重

否则 小幅跟新权重

在整个数据集上执行n次前向传播以及后向传播,表示模型进行了n个epoch的训练 ,执行一次算一个epoch

学习率

有助于构建更稳定的算法

梯度下降

更新权重以减小误差值的整个过程

SGD是将误差最小化的一种方法:随计算则数据中的训练数据样本,并根据该样本做出决策

实现梯度下降算法

1)定义前馈神经网络并计算均方误差值

2)为每个权重和偏执项增加一个非常小的量0.001,并针对每个权重和偏差的更新计算一个mse

python 复制代码
from copy import deepcopy 
import numpy as np
#创建update_weights函数,执行梯度下降来更新权重
def update_weights(inputs, outputs, weights, lr):
    #使用deepcopy可以确保处理多个权重副本,不会影响实际权重
    original_weights = deepcopy(weights)
    temp_weights  = deepcopy(weights)
    updated_weights = deepcopy(weights)
    original_loss = forward(inputs, outputs, original_weigts)
    #遍历网络的所有层
    for i, layer in enumerate(orignial_weights):
    #循环遍历每个参数列表的所有参数 共四个参数列表,前两个表示输入连接到隐藏层的权重和偏置项参数
    #另外两个表示链接隐藏层和输出层的偏置参数
        for index, weight in np.ndenumerate(layer):
            temp_weights = deepcopy(weights)#原始权重集
            temp_weights[i][index] += 0.0001#增加很小的值权重更新
            _loss_plus = forward(inputs, outputs, temp_weights)#更新损失
            grad = (_loss_plus - original_loss)/0.0001
            updated_weights[i][index] -= grad * lr #利用损失变化更新权重,使用学习率领权重变化更稳定
    return updated_weights, original_loss#返回更新后的权重

合并前向传播和反向传播

构建一个带有隐藏层的简单神经网络,

1)输入连接到具有三个神经元的隐藏层

2)隐藏层连接到具有一个神经元的输出层

python 复制代码
#导入相关库
import numpy as np
import matplotlib.pyplot as plt
from copy import deepcopy
x = np.array([[1,1]])
y = np.array(([[0]]))
#随机初始化权重和偏置值
W = [
    np.array([[-0.05, 0.3793],
              [-0.5820, -0.5204],
              [-0.2723, 0.1896]], dtype=np.float32).T, 
    np.array([-0.0140, 0.5607, -0.0628], dtype=np.float32), #隐藏层两个偏置值
    np.array([[ 0.1528, -0.1745, -0.1135]], dtype=np.float32).T, 
    np.array([-0.5516], dtype=np.float32)#输出层一个偏置值
]

#在一百个epoch内执行前向传播和反向传播,使用之前定义的forward和
def forward(inputs,outputs,weights):#如果是首次迭代,随机初始化
    pre_hidden = np.dot(inputs,weights[0]) + weights[1]#向量点积
    hidden = 1/(1+np.exp(-pre_hidden))#sigmoid激活函数
    pred_out = np.dot(hidden,weights[2]) + weights[3]#计算输出
    mse = np.mean(np.square(pred_out - outputs))#loss
    return mse
    
def update_weights(inputs, outputs, weights, lr):
    #使用deepcopy可以确保处理多个权重副本,不会影响实际权重
    original_weights = deepcopy(weights)
    temp_weights  = deepcopy(weights)
    updated_weights = deepcopy(weights)
    original_loss = forward(inputs, outputs, original_weights)
    #遍历网络的所有层
    for i, layer in enumerate(original_weights):
    #循环遍历每个参数列表的所有参数 共四个参数列表,前两个表示输入连接到隐藏层的权重和偏置项参数
    #另外两个表示链接隐藏层和输出层的偏置参数
        for index, weight in np.ndenumerate(layer):
            temp_weights = deepcopy(weights)#原始权重集
            temp_weights[i][index] += 0.0001#增加很小的值权重更新
            _loss_plus = forward(inputs, outputs, temp_weights)#更新损失
            grad = (_loss_plus - original_loss)/0.0001
            updated_weights[i][index] -= grad * lr #利用损失变化更新权重,使用学习率领权重变化更稳定
    return updated_weights, original_loss#返回更新后的权重

#绘制损失值
losses = []
for  epoch in range(100):
    W, loss = update_weights(x, y, W, 0.01)
    losses.append(loss)
plt.plot(losses)
plt.title('loss over increasing number of  epochs')
plt.xlabel('epochs')
plt.ylabel('loss value')
plt.show()
print(W)
#获取更新后的权值之后通过将输出传递给网络对输入进行预测计算输出值
pre_hidden = np.dot(x, W[0]) + W[1]
hidden = 1/(1+np.exp(-pre_hidden))
pre_out = np.dot(hidden, W[2]) + W[3]
print(pre_out)
    

注:在服务器上运行时im.show()无法展示图片

总结

训练神经网络主要是通过重复两个关键步骤,及用给定的学习率进行前向传播和反向传播,最终得到最佳权重

相关推荐
宁渡AI大模型4 分钟前
河南宁渡科技有限公司|宁渡课堂 AI 全栈面试分享,AI 应用开发高频考点汇总
java·c++·人工智能·python·深度学习·神经网络·rag
薛定e的猫咪1 小时前
(ICML2024)QSM:基于 Q 函数梯度对齐分数场的扩散模型离策略强化学习
人工智能·深度学习·算法
Persistent的粽子!1 小时前
C++的内存管理
c++·经验分享·笔记
kkkkkkkkkk_Z1 小时前
学嵌入式和Linux应用编程|学习日记:UDP协议与Wireshark抓包学习笔记
linux·笔记·学习
桃西西呀1 小时前
提前一天预报雾霾:手搓神经网络,讲清学习率、初始化、正则化
人工智能·深度学习·llm
这张生成的图像能检测吗1 小时前
(论文速读)FiDeSR:高保真保细节一步扩散超分辨率
图像处理·人工智能·深度学习·计算机视觉·扩散模型·图像超分
志尊宝1 小时前
Vue3 零基础每日笔记(018):按键与鼠标修饰符——回车搜索、Ctrl+S 保存这样写
javascript·vue.js·笔记
一隅论数智2 小时前
数据消费主体变了:智能时代如何重构业务管理逻辑
大数据·人工智能·经验分享·笔记·学习·行业数字化
zihan5182 小时前
男性自我成长
笔记
志尊宝3 小时前
Vue3 零基础每日笔记(021):class 与 style 动态绑定——对象、数组、三元表达式写法汇总
前端·vue.js·笔记·前端框架·html5