1_1-全连接神经网络做线性回归

本文通过numpy实现全连接层的前向与反向传播过程,并使用线性回归进行验证。包含损失函数定义、数据初始化及使用SGD进行训练。

numpy实现神经网络系列

工程地址:https://github.com/yizt/numpy_neuron_network

基础知识

0_1-全连接层、损失函数的反向传播

0_2_1-卷积层的反向传播-单通道、无padding、步长1

0_2_2-卷积层的反向传播-多通道、无padding、步长1

0_2_3-卷积层的反向传播-多通道、无padding、步长不为1

0_2_4-卷积层的反向传播-多通道、有padding、步长不为1

0_2_5-池化层的反向传播-MaxPooling、AveragePooling、GlobalAveragePooling、GlobalMaxPooling

0_3-激活函数的反向传播-ReLU、LeakyReLU、PReLU、ELU、SELU

0_4-优化方法-SGD、AdaGrad、RMSProp、Adadelta、Adam

DNN练习

1_1_1-全连接神经网络做线性回归

1_1_2-全连接神经网络做mnist手写数字识别

CNN练习

2_1-numpy卷积层实现

2_2-numpy池化层实现

2_3-numpy-cnn-mnist手写数字识别

本文目录

如果对神经网络的反向传播过程还有不清楚的,可以查阅0_1-全连接层、损失函数的反向传播

本文下载地址:1_1-全连接神经网络做线性回归

一、定义前向、后向传播

本文将用numpy实现全连接层的前向过程和反向过程,并使用一个线性回归作为例子进行测试;

如果对神经网络的反向传播过程还有不清楚的,可以0_1-全连接层、损失函数的反向传播

import numpy as np

def fc_forword(z, W, b):
    """
    全连接层的前向传播
    :param z: 当前层的输出
    :param W: 当前层的权重
    :param b: 当前层的偏置
    :return: 下一层的输出
    """
    return np.dot(z, W) + b


def fc_backword(next_dz, W, z):
    """
    全连接层的反向传播
    :param next_dz: 下一层的梯度
    :param W: 当前层的权重
    :param z: 当前层的输出
    :return:
    """
    N = z.shape[0]
    dz = np.dot(next_dz, W.T)  # 当前层的梯度
    dw = np.dot(z.T, next_dz)  # 当前层权重的梯度
    db = np.sum(next_dz,axis=0)  # 当前层偏置的梯度, N个样本的梯度求和
    return dw/N, db/N, dz

二、定义损失函数

def mean_squared_loss(y_predict,y_true):
    """
    均方误差损失函数
    :param y_predict: 预测值,shape (N,d),N为批量样本数
    :param y_true: 真实值
    :return:
    """
    loss = np.mean(np.sum(np.square(y_predict-y_true),axis=-1))  # 损失函数值
    dy = y_predict - y_true  # 损失函数关于网络输出的梯度
    return loss, dy

三、初始化数据

# 实际的权重和偏置
W = np.array([[3,7,4],
              [5,2,6]])
b = np.array([2,9,3])

# 产生训练样本
x_data = np.random.randint(0,10,1000).reshape(500,2)
y_data = np.dot(x_data,W)+b

def next_sample(batch_size=1):
    idx=np.random.randint(500)
    return x_data[idx:idx+batch_size],y_data[idx:idx+batch_size]

print("x.shape:{},y.shape:{}".format(x_data.shape,y_data.shape))
x.shape:(500, 2),y.shape:(500, 3)

四、定义网络、使用SGD训练

# 随机初始化参数
W1 = np.random.randn(2,3)
b1 = np.zeros([3])
loss = 100.0
lr = 0.01
i = 0 

while loss > 1e-15:
    x,y_true=next_sample(2)  # 获取当前样本
    # 前向传播
    y = fc_forword(x,W1,b1)
    # 反向传播更新梯度
    loss,dy=mean_squared_loss(y,y_true)
    dw,db,_ = fc_backword(dy,W,x)

    # 在一个batch中梯度取均值
    #print(dw)

    # 更新梯度
    W1 -= lr*dw
    b1 -= lr*db

    # 更新迭代次数
    i += 1
    if i % 1000 == 0:
        print("\n迭代{}次,当前loss:{}, 当前权重:{},当前偏置{}".format(i,loss,W1,b1))   

# 打印最终结果
print("\n迭代{}次,当前loss:{}, 当前权重:{},当前偏置{}".format(i,loss,W1,b1))
迭代1000次,当前loss:0.43387298848896233, 当前权重:[[3.01734672 7.12785625 4.02756123]
 [5.0221794  2.16347613 6.0352396 ]],当前偏置[1.81757802 7.65543542 2.71016   ]

迭代2000次,当前loss:0.024775748245913158, 当前权重:[[3.00242166 7.01784918 4.00384764]
 [5.00295757 2.02179914 6.00469912]],当前偏置[1.96775495 8.76233376 2.94876766]

迭代3000次,当前loss:0.00014564406568725818, 当前权重:[[3.00082136 7.00605396 4.00130502]
 [5.00061563 2.00453758 6.00097814]],当前偏置[1.99381124 8.95438495 2.99016703]

迭代4000次,当前loss:2.6237167410353415e-05, 当前权重:[[3.0001119  7.00082475 4.00017779]
 [5.00008191 2.0006037  6.00013014]],当前偏置[1.99885749 8.99157899 2.99818473]

迭代5000次,当前loss:3.713805657221762e-07, 当前权重:[[3.00002322 7.00017112 4.00003689]
 [5.00001109 2.00008176 6.00001763]],当前偏置[1.99979785 8.99851001 2.99967881]

迭代6000次,当前loss:8.807646869757514e-09, 当前权重:[[3.0000031  7.00002283 4.00000492]
 [5.00000397 2.00002927 6.00000631]],当前偏置[1.99996212 8.9997208  2.99993981]

迭代7000次,当前loss:1.536245925844849e-10, 当前权重:[[3.00000073 7.00000539 4.00000116]
 [5.00000067 2.00000494 6.00000106]],当前偏置[1.99999324 8.99995017 2.99998926]

迭代7398次,当前loss:3.3297294256090265e-16, 当前权重:[[3.00000043 7.00000318 4.00000069]
 [5.0000004  2.00000294 6.00000063]],当前偏置[1.99999655 8.99997456 2.99999452]
print("W1==W: {} \nb1==b:  {}".format(np.allclose(W1,W),np.allclose(b1,b)))
W1==W: True 
b1==b:  True
使用 PyTorch 构建多元线性回归全连接神经网络,可按以下步骤进行: ### 1. 导入依赖库 需要导入必要的库,如 `numpy` 用于数据处理,`matplotlib.pyplot` 用于数据可视化,`torch` 及其子模块用于构建和训练神经网络。 ```python import numpy as np import matplotlib.pyplot as plt import torch from torch import nn, optim ``` 这里 `numpy` 用来构建数据,`matplotlib.pyplot` 可将构建好的数据可视化,`torch.nn` 包含了 torch 已经准备好的层、激活函数、全连接层等,`torch.optim` 提供了神经网络的一系列优化算法,如 SGD、Adam 等 [^3]。 ### 2. 构建数据 准备多元线性回归所需的数据,通常包括输入特征和对应的目标值。 ```python # 示例:生成一些随机的多元数据 n_samples = 100 n_features = 3 x = np.random.randn(n_samples, n_features) # 真实的权重和偏置 true_weights = np.array([2, -3, 1]) true_bias = 0.5 # 生成目标值 y = np.dot(x, true_weights) + true_bias + 0.1 * np.random.randn(n_samples) # 将数据转换为 PyTorch 张量 x_tensor = torch.tensor(x, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1) ``` ### 3. 编写神经网络 构建一个简单的全连接神经网络,对于多元线性回归,只需要一个线性层。 ```python class MultipleLinearRegression(nn.Module): def __init__(self, input_size): super(MultipleLinearRegression, self).__init__() self.linear = nn.Linear(input_size, 1) def forward(self, x): return self.linear(x) # 初始化模型 model = MultipleLinearRegression(n_features) ``` ### 4. 定义损失函数和优化器 选择合适的损失函数和优化器。对于线性回归,通常使用均方误差(MSE)作为损失函数,优化器可选择随机梯度下降(SGD)或 Adam 等。 ```python criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) ``` ### 5. 训练神经网络 通过多次迭代训练模型,更新模型的参数。 ```python num_epochs = 1000 for epoch in range(num_epochs): # 前向传播 outputs = model(x_tensor) loss = criterion(outputs, y_tensor) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() if (epoch + 1) % 100 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') ``` ### 6. 可视化结果(可选) 可以使用 `matplotlib` 可视化训练结果,观察模型的拟合情况。 ```python # 预测结果 with torch.no_grad(): predicted = model(x_tensor).numpy() plt.scatter(y, predicted) plt.xlabel('True Values') plt.ylabel('Predictions') plt.show() ``` ### 完整代码示例 ```python import numpy as np import matplotlib.pyplot as plt import torch from torch import nn, optim # 生成数据 n_samples = 100 n_features = 3 x = np.random.randn(n_samples, n_features) true_weights = np.array([2, -3, 1]) true_bias = 0.5 y = np.dot(x, true_weights) + true_bias + 0.1 * np.random.randn(n_samples) x_tensor = torch.tensor(x, dtype=torch.float32) y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1) # 定义模型 class MultipleLinearRegression(nn.Module): def __init__(self, input_size): super(MultipleLinearRegression, self).__init__() self.linear = nn.Linear(input_size, 1) def forward(self, x): return self.linear(x) model = MultipleLinearRegression(n_features) # 定义损失函数和优化器 criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) # 训练模型 num_epochs = 1000 for epoch in range(num_epochs): outputs = model(x_tensor) loss = criterion(outputs, y_tensor) optimizer.zero_grad() loss.backward() optimizer.step() if (epoch + 1) % 100 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') # 可视化结果 with torch.no_grad(): predicted = model(x_tensor).numpy() plt.scatter(y, predicted) plt.xlabel('True Values') plt.ylabel('Predictions') plt.show() ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值