2024年深度学习(三)—— 神经元与神经网络_神经网络神经元,2024年最新46道面试题带你了解中高级大数据开发面试

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

)

b

1

1

y = (w_{1-11}w_{2-1}+\cdots)x_1+(w_{1-21}w_{2-1}+\cdots)x_2 + (w_{2-1}+\cdots)b_{1-1}

y=(w1−11​w2−1​+⋯)x1​+(w1−21​w2−1​+⋯)x2​+(w2−1​+⋯)b1−1​
上式括号中的都为w参数,和公式

y

=

w

1

x

1

w

2

x

2

b

y = w_1x_1 + w_2x_2 +b

y=w1​x1​+w2​x2​+b完全相同,依然只能够绘制出直线。但是可以发现,即使是多层神经网络,相比于前面的感知机,没有任何的改进

但是如果此时,我们在前面感知机的基础上加上非线性的激活函数之后,输出的结果就不在是一条直线

在这里插入图片描述
如上图,右边是 sigmoid 函数,对感知机的结果,通过 sigmoid 函数进行处理

如果给定合适的参数 w 和 b,就可以得到合适的曲线,能够完成对最开始问题的非线性分割

所以激活函数很重要的一个作用就是增加模型的非线性分割能力

在神经元中引入了 激活函数 ,它的本质是向神经网络中引入 非线性因素的,通过激活函数,神经网络就可以拟合各种曲线。如果不用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,引入非线性函数作为激活函数,那输出不再是输入的线性组合,可以逼近任意函数。

激活函数的种类

(1)Sigmoid / logistics 函数

数学表达式:

在这里插入图片描述
曲线图像:
在这里插入图片描述

sigmoid 在定义域内处处可导,且两侧导数逐渐趋近于0。如果X的值很大或者很小的时候,那么函数的梯度(函数的斜率)会非常小,在反向传播的过程中,导致了向低层传递的梯度也变得非常小。此时,网络参数很难得到有效训练。这种现象被称为 梯度消失

一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象。而且,该激活函数并不是以 0 为中心的(是以 0.5 为中心的),所以在实践中这种激活函数使用的很少。

sigmoid函数一般只用于 二分类 的输出层。

实现方法:

# 导入相应的工具包
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
import numpy as np
# 定义x的取值范围
x = np.linspace(-10, 10, 100)
# 直接使用tensorflow实现
y = tf.nn.sigmoid(x)
# 绘图
plt.plot(x,y)
plt.grid()

(2)tanh(双曲正切曲线)

数学表达式:

在这里插入图片描述
曲线图像:

在这里插入图片描述

tanh 也是一种非常常见的激活函数。与 sigmoid 相比,它是以 0 为中心的,使得其收敛速度要比 sigmoid 快(相比之下,tanh 曲线更为陡峭一些),减少迭代次数。然而,从图中可以看出,tanh 两侧的导数也为 0,同样会造成梯度消失。

若使用时可在隐藏层使用 tanh 函数,在输出层使用 sigmoid 函数。

实现方法:

# 导入相应的工具包
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
import numpy as np
# 定义x的取值范围
x = np.linspace(-10, 10, 100)
# 直接使用tensorflow实现
y = tf.nn.tanh(x)
# 绘图
plt.plot(x,y)
plt.grid()

(3)RELU

数学表达式为:

在这里插入图片描述
曲线如下图所示:

在这里插入图片描述

ReLU是目前最常用的激活函数。 从图中可以看到,当x<0时,ReLU导数为0,而当x>0时,则不存在饱和问题。所以,ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。然而,随着训练的推进,部分输入会落入小于0区域,导致对应权重无法更新。这种现象被称为“神经元死亡”。

Relu是输入只能大于0,如果你输入含有负数,Relu就不适合,如果你的输入是图片格式,Relu就挺常用的,因为图片的像素值作为输入时取值为[0,255]。

与sigmoid相比,RELU的优势是:

  • 采用sigmoid函数,计算量大(指数运算),反向传播求误差梯度时,求导涉及除法,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。
  • sigmoid函数反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。
  • Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。

实现方法为:

# 导入相应的工具包
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
import numpy as np
# 定义x的取值范围
x = np.linspace(-10, 10, 100)
# 直接使用tensorflow实现
y = tf.nn.relu(x)
# 绘图
plt.plot(x,y)
plt.grid()

(4)LeakyReLu

该激活函数是对RELU的改进,数学表达式为:

在这里插入图片描述
曲线如下所示:

在这里插入图片描述
实现方法为:

# 导入相应的工具包
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
import numpy as np
# 定义x的取值范围
x = np.linspace(-10, 10, 100)
# 直接使用tensorflow实现
y = tf.nn.leaky_relu(x)
# 绘图
plt.plot(x,y)
plt.grid()

(5)SoftMax

softmax用于多分类过程中,它是二分类函数 sigmoid 在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。

数学表达式为:

在这里插入图片描述
使用方法:

在这里插入图片描述
softmax 直白来说就是将网络输出的 logits 通过softmax函数,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)接点,作为我们的预测目标类别。

实现方法:

# 导入相应的工具包
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
import numpy as np
# 数字中的score
x = tf.constant([0.2,0.02,0.15,0.15,1.3,0.5,0.06,1.1,0.05,3.75])
# 将其送入到softmax中计算分类结果
y = tf.nn.softmax(x) 
# 将结果进行打印
print(y)

分类结果为:

tf.Tensor(
[0.0212338  0.01773596 0.02019821 0.02019821 0.06378984 0.02866262
 0.01845977 0.0522267  0.0182761  0.73921883], shape=(10,), dtype=float32)

(6)其他激活函数

在这里插入图片描述

如何选择激活函数?

  • 隐藏层
    • 优先选择RELU激活函数
    • 如果ReLu效果不好,那么尝试其他激活,如Leaky ReLu等。
    • 如果你使用了Relu, 需要注意一下Dead Relu问题, 避免出现大的梯度从而导致过多的神经元死亡。
    • 不要使用sigmoid激活函数,可以尝试使用tanh激活函数
  • 输出层
    • 二分类问题选择sigmoid激活函数
    • 多分类问题选择softmax激活函数
    • 回归问题选择identity激活函数

激活函数的作用除了前面说的增加模型的非线性分割能力外,还有

  • 提高模型鲁棒性
  • 缓解梯度消失问题
  • 加速模型收敛等

3.2 参数初始化

对于某一个神经元来说,需要初始化的参数有两类:一类是权重W,还有一类是偏置b,偏置b初始化为0即可。而权重W的初始化比较重要,我们着重来介绍常见的初始化方式。

(1)随机初始化

随机初始化从均值为 0,标准差是 1 的高斯分布(也叫正态分布)中取样,使用一些很小的值对参数 W 进行初始化。

(2)标准初始化

权重参数初始化从区间均匀随机取值。即在(-1/√d,1/√d)均匀分布中生成当前神经元的权重,其中 d 为每个神经元的输入数量。

(3)Xavier 初始化(在 tf.keras 中 默认 使用)

该方法的基本思想是各层的激活值和梯度的方差在传播过程中保持一致,也叫做 Glorot 初始化。在tf.keras中实现的方法有两种:

① 正态化的 Xavier 初始化

Glorot 正态分布初始化器,也称为 Xavier 正态分布初始化器。它从以 0 为中心,标准差为 stddev = sqrt(2 / (fan_in + fan_out)) 的正态分布中抽取样本, 其中 fan_in 是输入神经元的个数, fan_out 是输出的神经元个数。

实现方法为:

# 导入工具包
import tensorflow as tf
# 进行实例化
initializer = tf.keras.initializers.glorot_normal()
# 采样得到权重值
values = initializer(shape=(9, 1))
# 打印结果
print(values)

输出的结果为:

tf.Tensor(
[[ 0.71967787]
 [ 0.56188506]
 [-0.7327265 ]
 [-0.05581591]
 [-0.05519835]
 [ 0.11283273]
 [ 0.8377778 ]
 [ 0.5832906 ]
 [ 0.10221979]], shape=(9, 1), dtype=float32)

② 标准化的 Xavier 初始化

Glorot 均匀分布初始化器,也称为 Xavier 均匀分布初始化器。它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limitsqrt(6 / (fan_in + fan_out)), 其中 fan_in 是输入神经元的个数, fan_out 是输出的神经元个数。

# 导入工具包
import tensorflow as tf
# 进行实例化
initializer = tf.keras.initializers.glorot_uniform()
# 采样得到权重值
values = initializer(shape=(9, 1))
# 打印结果
print(values)

输出结果为:

tf.Tensor(
[[-0.59119344]
 [ 0.06239486]
 [ 0.65161395]
 [-0.30347362]
 [-0.5407096 ]
 [ 0.35138106]
 [ 0.41150713]
 [ 0.32143414]
 [-0.57354397]], shape=(9, 1), dtype=float32)

(4)He 初始化

he初始化,也称为Kaiming初始化,出自大神何恺明之手,它的基本思想是正向传播时,激活值的方差保持不变;反向传播时,关于状态值的梯度的方差保持不变。在tf.keras中也有两种:

① 正态化的 He 初始化

He 正态分布初始化是以 0 为中心,标准差为 stddev = sqrt(2 / fan_in) 的截断正态分布中抽取样本, 其中 fan_in 是输入神经元的个数,在tf.keras中的实现方法为:

# 导入工具包
import tensorflow as tf
# 进行实例化
initializer = tf.keras.initializers.he_normal()
# 采样得到权重值
values = initializer(shape=(9, 1))
# 打印结果
print(values)

输出结果为:

tf.Tensor(
[[-0.1488019 ]
 [-0.12102155]
 [-0.0163257 ]
 [-0.36920077]
 [-0.89464396]
 [-0.28749225]
 [-0.5467023 ]
 [ 0.27031776]
 [-0.1831588 ]], shape=(9, 1), dtype=float32)

② 标准化的 He 初始化

He 均匀方差缩放初始化器。它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limitsqrt(6 / fan_in), 其中 fan_in 输入神经元的个数。实现为:

# 导入工具包
import tensorflow as tf
# 进行实例化
initializer = tf.keras.initializers.he_uniform()
# 采样得到权重值
values = initializer(shape=(9, 1))
# 打印结果
print(values)

输出结果为:

tf.Tensor(
[[ 0.80033934]
 [-0.18773115]
 [ 0.6726284 ]
 [-0.23672342]
 [-0.6323329 ]
 [ 0.6048162 ]
 [ 0.1637358 ]
 [ 0.60797024]
 [-0.46316862]], shape=(9, 1), dtype=float32)

4 神经网络的搭建

接下来我们来构建如下图所示的神经网络模型:

在这里插入图片描述
tf.Keras 中构建模有两种方式,一种是通过 Sequential 构建,一种是通过 Model 类构建。前者是按一定的顺序对层进行堆叠,而后者可以用来构建较复杂的网络模型。首先我们介绍下用来构建网络的全连接层:

tf.keras.layers.Dense(
    units, activation=None, use_bias=True, kernel_initializer='glorot\_uniform',
    bias_initializer='zeros')

主要参数:

  • units: 当前层中包含的神经元个数
  • Activation: 激活函数,relu,sigmoid等
  • use_bias: 是否使用偏置,默认使用偏置
  • Kernel_initializer: 权重的初始化方式,默认是Xavier初始化
  • bias_initializer: 偏置的初始化方式,默认为0

4.1 通过Sequential构建

Sequential() 提供一个层的列表,就能快速地建立一个神经网络模型,实现方法如下所示:

# 导入相关的工具包
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# 定义一个Sequential模型,包含3层
model = keras.Sequential(
    [
        # 第一层(隐藏层):激活函数为relu,权重初始化为he\_normal
        layers.Dense(3, activation="relu",
                     kernel_initializer="he\_normal", name="layer1",input_shape=(3,)),
        # 第二层(隐藏层):激活函数为relu,权重初始化为he\_normal
        layers.Dense(2, activation="relu",
                     kernel_initializer="he\_normal", name="layer2"),
        # 第三层(输出层):激活函数为sigmoid,权重初始化为he\_normal
        layers.Dense(2, activation="sigmoid",
                     kernel_initializer="he\_normal", name="layer3"),
    ],
    name="my\_Sequential" # 定义该模型的名字
)

展示模型结果:

# 展示模型结果
model.summary()

如下所示:

Model: "my\_Sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param # 
=================================================================
layer1 (Dense)               (None, 3)                 12        
_________________________________________________________________
layer2 (Dense)               (None, 2)                 8         
_________________________________________________________________
layer3 (Dense)               (None, 2)                 6         
=================================================================
Total params: 26
Trainable params: 26
Non-trainable params: 0
_________________________________________________________________

通过这种 sequential 的方式只能构建简单的序列模型,较复杂的模型没有办法实现。

拓展:参数个数的计算

在这里插入图片描述

4.2 利用function API构建

tf.keras 提供了 Functional API,建立更为复杂的模型,使用方法是将层作为可调用的对象并返回张量,并将输入向量和输出向量提供给 tf.keras.Modelinputsoutputs 参数,实现方法如下:

# 导入工具包
import tensorflow as tf
# 定义模型的输入
inputs = tf.keras.Input(shape=(3,),name = "input")
# 第一层:激活函数为relu,其他默认
x = tf.keras.layers.Dense(3, activation="relu",name = "layer1")(inputs)
# 第二层:激活函数为relu,其他默认
x = tf.keras.layers.Dense(2, activation="relu",name = "layer2")(x)
# 第三层(输出层):激活函数为sigmoid
outputs = tf.keras.layers.Dense(2, activation="sigmoid",name = "layer3")(x)
# 使用Model来创建模型,指明输入和输出
model = tf.keras.Model(inputs=inputs, outputs=outputs,name="my\_model") 

展示模型结果:

model.summary()

或者

# 模型展示
keras.utils.plot_model(model,show_shapes=True)

4.3 通过model的子类构建

通过 model 的子类构建模型,此时需要在 __init__ 中定义神经网络的层,在 call 方法中定义网络的前向传播过程,实现方法如下:

# 导入工具包
import tensorflow as tf
# 定义model的子类
class MyModel(tf.keras.Model):
    # 在init方法中定义网络的层结构
    def \_\_init\_\_(self):
        super(MyModel, self).__init__()
        # 第一层:激活函数为relu,权重初始化为he\_normal
        self.layer1 = tf.keras.layers.Dense(3, activation="relu",
                     kernel_initializer="he\_normal", name="layer1",input_shape=(3,))
        # 第二层:激活函数为relu,权重初始化为he\_normal
        self.layer2 =tf.keras.layers.Dense(2, activation="relu",
                     kernel_initializer="he\_normal", name="layer2")
        # 第三层(输出层):激活函数为sigmoid,权重初始化为he\_normal
        self.layer3 =tf.keras.layers.Dense(2, activation="sigmoid",
                     kernel_initializer="he\_normal", name="layer3")
    # 在call方法中完成前向传播
    def call(self, inputs):
        x = self.layer1(inputs)
        x = self.layer2(x)
        return self.layer3(x)
# 实例化模型
model = MyModel()
# 设置一个输入,调用模型(否则无法使用summay())
x = tf.ones((1, 3))
y = model(x)

展示模型结果:

model.summary()

此时就不能使用 keras.utils.plot_model(model,show_shapes=True)展示模型架构了

5 小结

神经网络的优缺点:

  • 优点
    • 精度高,性能优于其他的机器学习方法,甚至在某些领域超过了人类
    • 可以近似任意的非线性函数
    • 随之计算机硬件的发展,近年来在学界和业界受到了热捧,有大量的框架和库可供调用
  • 缺点
    • 黑箱,很难解释模型是怎么工作的
    • 训练时间长,需要大量的计算力
    • 网络结构复杂,需要调整超参数
    • 小数据集上表现不佳,容易发生过拟合

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

x = tf.ones((1, 3))
y = model(x)


展示模型结果:



model.summary()



> 
> 此时就不能使用 `keras.utils.plot_model(model,show_shapes=True)`展示模型架构了
> 
> 
> 


## 5 小结


神经网络的优缺点:


* 优点
	+ 精度高,性能优于其他的机器学习方法,甚至在某些领域超过了人类
	+ 可以近似任意的非线性函数
	+ 随之计算机硬件的发展,近年来在学界和业界受到了热捧,有大量的框架和库可供调用
* 缺点
	+ 黑箱,很难解释模型是怎么工作的
	+ 训练时间长,需要大量的计算力
	+ 网络结构复杂,需要调整超参数
	+ 小数据集上表现不佳,容易发生过拟合







[外链图片转存中...(img-xe2YxM9j-1715313972405)]
[外链图片转存中...(img-nltkZfOa-1715313972406)]
[外链图片转存中...(img-0JORACiy-1715313972406)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值