第一步--了解深度神经网络

一、神经网络原理

1.神经元模型

本质上就是线性模型模拟神经元的功能, y=f(∑wx+b)

2.神经网络结构

2.1神经元的串联

是 通过类似于线性代数求和形式传递

不能只原封不动串联,那样没有任何意义,故而会有一个新的东西!

2.2激活函数!!

激活函数是非线性函数,有个很重要的特性:能求导

每一次传递会检测是否需要激活,如果没有达到要求不会传递到下一层

如果没有激活函数,就算层数再深,也变成了纯线性组合的输出,不能解决更加复杂的问题
经过激活函数,会对每一层的结果进行一个处理

有以下两个常见的激活函数

  1. sigmoid函数

S(x)=11+e−x=exex+1 S(x) = \frac{1}{1 + e^{-x}} = \frac{e^x}{e^x + 1} S(x)=1+e−x1=ex+1ex

  1. relu函数
    f(x) = max(0,x)

激活函数就夹在这些 Layer 中间,故而激活函数一定要能求导

你可能会看到一个叫 ReLU 的激活函数,它长这样:f(x)=max⁡(0,x)f(x) = \max(0, x)f(x)=max(0,x)作为程序员,你一眼就会发现:"等等!这个函数在 x=0 的那个折角处,也是不可导的啊!"没错,你的数学直觉很准。在 x=0x=0x=0 点,左导数是 0,右导数是 1,导数不连续。但是在深度学习的工程实践中,我们"作弊"了:我们在代码里强行规定:如果正好遇到 x=0x=0x=0,我们就把导数直接设为 0 或者 1(通常设为 0)。

2.3加入激活函数的效果展示

整体图形化表示

在这里插入图片描述

这时候我们再看看整体的模型结构(加上拟合和激活函数)

这样就可以让预测值不断地去接近实际值

3.神经网络就是黑盒子

可能人为会去考虑如何生成的,但是在调参训练中,不断的降低loss的时候,实际上就是不断的计算梯度,不断的让w - 偏导的过程

这就是一个黑盒子,因为在我们看来整体就是在不断的求导,做减法

每一层都是全连接的网络

4.正式运行一个程序,理解激活函数的作用

python 复制代码
import random
import os
from torch.utils.data import DataLoader, Dataset
from torch.utils.data import TensorDataset
import torch.nn as nn
import numpy as np
import torch
import matplotlib.pyplot as plt

scatter = True


def seed_everything(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True
    random.seed(seed)
    np.random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)

seed_everything(0)     # 固定随机种子, 让我们每次运行都得到相同的结果。
#模型net
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.net=nn.Sequential(
            nn.Linear(in_features=1,out_features=100),    #  Linear model
            # nn.Sigmoid(),
            # nn.Linear(100,100),
            # nn.Sigmoid(),
            # nn.Linear(100, 100),
            # nn.ReLU(),
            # nn.ReLU(),
            nn.Linear(100, 10),
            nn.Linear(10, 100),
            #nn.ReLU(),
            nn.Sigmoid(),
            # nn.Linear(100, 100),
            # nn.ReLU(),
            nn.Linear(100, 1)
        )
        #
        #layer1 = nn.Linear(4,3)
        #layer2 = nn.Linear(3,2)
    def forward(self, input):
        return self.net(input)

class mydataset(Dataset):
    def __init__(self,x ,y):
        super(mydataset, self).__init__()
        self.x = torch.tensor(x,dtype=torch.float)
        self.y = torch.tensor(y,dtype=torch.float)

    def __getitem__(self, item):
        return self.x[item], self.y[item]

    def __len__(self):
        return len(self.x)


data_num = 100
# 准备数据
train_s = -5
train_e = 5
x=np.linspace(train_s,train_e, data_num)
# y=np.sin(x)

# y = 20*x+4
#创建数据

y = x**3 + 2*x**2 #模拟的函数


# 在输入上加入噪声。
mu = 0
sigma = 1
y += np.random.normal(mu, sigma, y.shape)
# for i in range(data_num):
#     y[i] += random.gauss(mu, sigma)

# 将数据做成数据集的模样
X=np.expand_dims(x,axis=1)
Y=y.reshape(data_num,-1)


# 使用批训练方式
# dataset=TensorDataset(torch.tensor(X,dtype=torch.float),torch.tensor(Y,dtype=torch.float))
dataset = mydataset(X, Y)
dataloader=DataLoader(dataset,batch_size=100,shuffle=True)


# 神经网络主要结构,这里就是一个简单的线性结构


net = Net()
# 定义优化器和损失函数
optim=torch.optim.Adam(net.parameters(net),lr=0.001)
# optim = torch.optim.SGD(net.parameters(), lr=0.01, momentum=0.09)
Loss = nn.MSELoss()



# 下面开始训练:
# 一共训练1000次
for epoch in range(1000):
    loss = None
    for batch_x,batch_y in dataloader:
        y_predict=net(batch_x)
        loss=Loss(y_predict,batch_y)
        optim.zero_grad()
        loss.backward()
        optim.step()

    # 每100次 的时候打印一次日志
    if (epoch+1)%100==0:
        print("step: {0} , loss: {1}".format(epoch+1,loss.item()))
        # 使用训练好的模型进行预测
        predict=net(torch.tensor(X,dtype=torch.float))
        # 绘图展示预测的和真实数据之间的差异
        if scatter:
            plt.scatter(x, y, 1)
        else:
            plt.plot(x,y,color="coral",label="fact")
        plt.plot(x,predict.detach().numpy(), color="coral",label="predict")
        plt.title("function")
        plt.xlabel("x")
        plt.ylabel("f(x)")
        plt.legend()
        # plt.savefig(fname="result.png",figsize=[10,10])
        plt.show()



# # 做一个测试集,解除注释可查看测试集结果
# if scatter:
#     plt.scatter(x,y,1)
# else:
#     plt.plot(x, y, label="fact")
#
# test_s = train_e
# test_e = test_s+5
# test_x = np.linspace(test_s, test_e, data_num)
# # y=np.sin(x)
# # y = 20*x+4
# test_y = test_x ** 3 + 2 * test_x ** 2

# # 将数据做成数据集的模样
# test_X = np.expand_dims(test_x, axis=1)
# test_Y = test_y.reshape(data_num, -1)
# # 使用批训练方式
# # test_dataset = TensorDataset(torch.tensor(test_X, dtype=torch.float), torch.tensor(test_Y, dtype=torch.float))
# # test_dataloader = DataLoader(test_dataset, batch_size=100, shuffle=True)
#
# pre = net(torch.tensor(test_X,dtype=torch.float))
#
#
#
# x = np.concatenate((x, test_x), axis=0)
# y = np.concatenate((y, test_y), axis=0)
#
# pre_y = np.concatenate((predict.detach().numpy(), pre.detach().numpy()), axis=0)
# plt.plot(x, pre_y, color="coral", label="predict")
#
# if scatter:
#     plt.scatter(x, y, 1,color="blue", label="fact")
# else:
#     plt.plot(x, y, label="fact",color="blue")
#
#
#
#
# # plt.title("sin function")
# plt.xlabel("x")
# plt.legend()
# # plt.savefig(fname="result.png",figsize=[10,10])
# plt.show()


当把这里的sigmoid()换成ReLU()

5.过拟合(overfit)和欠拟合(underfit)

上文中已经尝试了自己去调试模型的数据,输出的图像和训练集,看

看离真正的数据图像差距多远,在这个过程中,有两种状态,

如果模型够深的话,极有可能会变成过拟合

6.神经网络透析

  1. 函数的结构 = 模型的架构,神经网络本质上是架构设计。
  2. 神经网络在训练集上展现好没有用,在验证集上效果好才有用,偏偏神经网络在图片生成,人脸识别上,实现很不错,但是回归到原始的简单问题上,表现可能没有那么好,比如(模拟函数,判断一个数字是否偶数,发现数字规律)
相关推荐
IvanCodes3 小时前
RAG 实战教程(一):RAG 工作原理与完整流程——分片、索引、召回、重排和生成
人工智能·后端·agent
今天AI了吗3 小时前
合规场景下的 AI 推理可解释性:Attention 可视化与推理路径追踪的工程实践
人工智能
周末程序猿4 小时前
浅析大模型推理十二篇之KV Cache
人工智能
鱼樱前端4 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
Dawson Zhu4 小时前
基于Palantir Foundry构建半导体制造AI友好型数据中台:从良率分析场景谈起
人工智能·语言模型·架构·制造·agi
fthux5 小时前
装闭 RenoPit 源码解析(04):装修图纸和合同文件上传处理流程
人工智能·ai·开源·github·open source·renopit
weixin_446260856 小时前
从被动镜像到主动智能体:面向网络物理人工智能的整体论数字孪生(HDT-Net)
网络·人工智能
秋枫要学习6 小时前
你的鼠标,正在被 AI 抢走
人工智能·计算机外设
满怀冰雪7 小时前
19-图像数据处理:PaddleVision Transform 实战
人工智能·深度学习·计算机视觉·paddle