目录
一、深度学习使用python建立最简单的神经元neuron
1、人工智能&机器学习&深度学习三者关系
2、机器学习& 深度学习区别
3、神经元
4、最小神经网络模型(神经元/感知器)
5、(案例)Predicting if a person would buy life insurnace based on his age using logistic regression使用逻辑回归预测一个人是否会购买人寿保险(基于年龄)
model.coef_ indicates value of m in y=m*x + b equation
model.intercept_ indicates value of b in y=m*x + b equation
Lets defined sigmoid function now and do the math
二、使用程序设计流程图解析并建立神经网络不依赖DL Library
1、模型简述
2、神经网络流程图
3、前馈神经网络与反向传播
三、神经网络建立结果可控最小机器人
基本概念复盘及常见问题汇总:
1、人工智能和机器学习和深度学习关系
2、深度学习优点
3、机器学习和深度学习区别
4、神经元
5、神经元模型
6、神经元工作流程
7、神经网络工作流程
8、前馈神经网络和反馈神经网络
9、神经元模型为什么要添加权重?
10、神经元模型为什么要添加bias?
11、神经元模型为什么要把输入数据和权重相乘并求和?
12、反向传播和前向传播的区别
13、反向传播和反馈神经网络的区别?
14、反向传播中的损失函数(loss)
15、前向传播和前馈神经网络的区别?
16、反向传播和损失函数是必须使用的吗?
代码实战——构建一个会学习的小机器人
(1) assign input values
(2) assign output values
(3) assign weights
(4) add bias
(5) activation function
(6)derivative of sigmoid function
(7)updating weights and bias
(8)prediction
(9)Note
(10)参数说明:
通过修改神经网络中的:
(输入数据)input和(输出数据)output是正确的X(特征)和Y(相应)
(权重值)weights = weights - 0.5 * final_derivative、
(偏置值)bias = bias - 0.5 * i、
(迭代次数)epochs可以很简单的控制神经网络的优化程度。
此外,神经网络的激活函数、反向传播算法、和损失函数的选取也是至关重要的。
解答一个小困惑:
像是这种简单的问题,貌似我们可以通过if语句就能完美的实现,那为什么我们还有用更加复杂的神经网络呢?
四、矩阵乘积和手工验算2层神经网络
1、介绍矩阵乘法
2、神经网络的分类:
3、单层神经网络(神经元Neuron)模型:
(1)单层神经网络手工验算过程
1.定义输入数据
2.定义权重
3.输入与权重进行点乘(对应相乘并求和)
4.定义偏置值
5.神经网络核心计算模型
6.定义激活函数
7.调用激活函数处理前面模型计算好的结果
(2)实现单层神经网络的封装
4、双层神经网络(Neural NetWork)模型:
(1)双层神经网络手工验算过程
8.基于第一层神经网络的计算结果作为第二层的输入(可以理解为是神经网络的一个递归过程)
9.权重不变
10.偏置值不变
11.第二次的输入与权重进行点乘(对应相乘并求和)
12.加上偏置值
13.调用激活函数
(2)实现双层神经网络的封装
五、Keras,TensorFlow和PyTorch比较及应用TensorFlow建立ANN模型
1、深度学习框架介绍
2、安装tensorflow并使用内涵的Keras库进行实验
(1)导入所需库
(2)加载数据集(印第安pima部落的肥胖症数据分析)
(3)划分特征和响应集
(4)定义一个串行的(Sequential)Keras网络结构模型
(5)编译模型
(6)训练模型
(7)评估模型
(8)预测模型
(9)模型总结
完整代码及步骤:
六、Activation Function为什么Relu比Sigmoid好 for Vanishing Gradient
结论
七、调整Activation Function参数对神经网络的影响
1、activation='tanh'
什么是Tensor?
2、activation='relu'
3、activation='sigmoid'
4、添加更多的Dense层,使用多种不同的 activation函数
一、深度学习使用python建立最简单的神经元neuron
1、人工智能&机器学习&深度学习三者关系
2、机器学习& 深度学习区别
IBM官网:人工智能&机器学习&深度学习的关系:AI vs. Machine Learning vs. Deep Learning vs. Neural Networks: What’s the difference?
3、神经元
4、最小神经网络模型(神经元/感知器)
二元分类激活函数——sigmoid
x = np.linspace(-10, 10, 100)
z = 1/(1 + np.exp(-x)) plt.plot(x, z)
plt.xlabel("x")
plt.ylabel("Sigmoid(X)") plt.show()
神经元工作流程:
1、输入被送入感知器
2、每个输入乘以权重
3、求和并加上偏置
4、应用激活函数
注意,这里我们使用阶跃函数,但也有其他更复杂的激活函数,如sigmoid、双曲正切(tanh)、整流器(relu)等。不用担心,我们将在未来涵盖许多这些函数!
输出要么是1,要么不是0。请注意,我们使用y hat来标记由我们的感知器模型产生的输出。
神经网络可以用于回归或分类。在回归模型中,输出一个值,该值可能映射到一组实数,这意味着只需要一个输出神经元。
逻辑回归是一种二元分类方法。它可以建模为一个函数,可以接受任意数量的输入并将输出限制在0和1之间。这意味着,我们可以将逻辑回归视为一层神经网络。
5、(案例)Predicting if a person would buy life insurnace based on his age using logistic regression使用逻辑回归预测一个人是否会购买人寿保险(基于年龄)
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
df = pd.read_csv("Insurance.csv")
df
plt.scatter(df.age,df.bought_insurance,marker='o',color='red')
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(df[['age']],df.bought_insurance,train_size=0.8)X_test
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()model.fit(X_train, y_train)y_predicted = model.predict(X_test)model.predict_proba(X_test)model.score(X_test,y_test)
1.0
y_predicted
array([1, 0, 1, 1, 1, 0], dtype=int64)
y_test
17 1 20 0 2 1 15 1 9 1 13 0 Name: bought_insurance, dtype: int64
model.coef_ indicates value of m in y=m*x + b equation
model.coef_
array([[0.11720474]])
model.intercept_ indicates value of b in y=m*x + b equation
model.intercept_
array([-4.638073])
Lets defined sigmoid function now and do the math
import math
def sigmoid(x):return 1 / (1 + math.exp(-x))
def prediction_function(age):z = model.coef_[0][0] * age + model.intercept_[0]y = sigmoid(z)return y
age = 26
prediction_function(age)
0.16927844550360494
age = 47
prediction_function(age)
0.7048601053948814
plt.scatter(df.age,df.bought_insurance,marker='o',color='red')
x = np.linspace(-10, 10, 100)
z = 1/(1 + np.exp(-x)) plt.plot(x, z)
plt.xlabel("x")
plt.ylabel("Sigmoid(X)") plt.show()
二、使用程序设计流程图解析并建立神经网络不依赖DL Library
1、模型简述
Inputs are fed into the perceptron
输入被送入感知器(感知器是一种二元分类函数,它将输入映射到一个二元输出。感知器算法是一种简单的机器学习算法,它是神经网络的前身之一。感知器是由美国心理学家Frank Rosenblatt在1957年提出的,它是一种线性分类器,可以用于解决二分类问题。 )
Weights are multiplied to each input
每个输入乘以权重
Summation and then add bias
求和然后加上偏置
Activation function is applied. Note that here we use a step function, but there are other more sophisticated activation functions like sigmoid, hyperbolic tangent (tanh), rectifier (relu) and more. No worries, we will cover many of them in the future!
应用激活函数。注意,这里我们使用阶跃函数,但也有其他更复杂的激活函数,如sigmoid、双曲正切(tanh)、整流器(relu)等。不用担心,我们将在未来涵盖许多这些函数!
Output is either triggered as 1, or not, as 0. Note we use y hat to label output produced by our perceptron model
输出要么触发为1,要么不触发为0。注意,我们使用y hat来标记我们的感知器模型产生的输出
Neural networks can be used for either regression or classification. Under regression model a single value is outputted which may be mapped to a set of real numbers meaning that only one output neuron is required
神经网络可以用于回归或分类。在回归模型下,输出单个值,该值可能映射到一组实数,这意味着只需要一个输出神经元即可。
2、神经网络流程图
3、前馈神经网络与反向传播
(a) Feedforward: On a feedforward neural network, we have a set of input features and some random weights. Notice that in this case, we are taking random weights that we will optimize using backward propagation.
(a) 前馈神经网络:在前馈神经网络中,我们有一组输入特征和一些随机权重。需要注意的是,在这种情况下,我们使用随机权重,然后通过反向传播进行优化。
(b) Backpropagation: During backpropagation, we calculate the error between predicted output and target output and then use an algorithm (gradient descent) to update the weight values.
(b) 反向传播:在反向传播过程中,我们计算预测输出与目标输出之间的误差,然后使用一种算法(梯度下降)来更新权重值。
# Import the required libraries
import numpy as np
import pandas as pd
# Load the data
df = pd.read_csv('Lesson44-data.csv')
df
划分输入(特征)输出(预测结果)
# Separate the features and label
x = df[['Glucose','BloodPressure']]
y = df['Outcome']
定义激活函数 (选择的是sigmoid函数)
# Define the sigmoid function
def sigmoid(input): output = 1 / (1 + np.exp(-input))return output
sigmoid梯度下降函数(更新权重时使用)
# Define the sigmoid derivative function
def sigmoid_derivative(input):return sigmoid(input) * (1.0 - sigmoid(input))
(c) The algorithm is used to effectively train a neural network through a method called chain rule. In simple terms, after each forward pass through a network, backpropagation performs a backward pass while adjusting the model’s
(c)该算法通过一种称为链式规则的方法有效地训练神经网络。简单来说,在网络进行每次前向传递之后,反向传播执行一次后向传递,同时调整模型的权重和偏置。
两个不同函数的区别和比较
# show comparision
def sigmoid(xx):return 1 / (1 + np.exp(-xx))def derivative(xx):return sigmoid(xx) * (1.0 - sigmoid(xx))xx = np.linspace(-10, 10, 1000)y1 = sigmoid(xx)
y2 = derivative(xx)plt.plot(xx, y1, label='sigmoid')
plt.plot(xx, y2, label='derivative')
plt.legend(loc='upper left')
plt.show()
训练神经网络
def train_network(x,y,weights,bias,learning_rate,epochs): j=0k=[]l=[]for epoch in range(epochs): dot_prod = np.dot(x, weights) + bias# using sigmoidpreds = sigmoid(dot_prod)# Calculating the errorerrors = preds - y # sigmoid derivativederiva_preds = sigmoid_derivative(preds)deriva_product = errors * deriva_preds#update the weightsweights = weights - np.dot(x.T, deriva_product) * learning_rateloss = errors.sum()j=j+1k.append(j)l.append(loss)print(j,loss)for i in deriva_product:bias = bias - i * learning_rateplt.plot(k,l)return weights,bias
(d) Epochs. One Epoch is when an ENTIRE dataset is passed forward and backward through the neural network only ONCE.
d) 一个Epoch是指将整个数据集仅一次地向前和向后通过神经网络。
(e) Loss is nothing but a prediction error of Neural Net. And the method to calculate the loss is called Loss Function. In simple words, the Loss is used to calculate the gradients. And gradients are used to update the weights of the Neural Net.
(e) 损失函数是神经网络的预测误差,用于计算损失的方法称为损失函数。简单地说,损失函数用于计算梯度,而梯度用于更新神经网络的权重。
(f) Backpropagation and computing gradients(loss)
(f) 反向传播和计算梯度(损失)
定义一些神经网络训练时用到的参数
np.random.seed(10)
label = y.values.reshape(y.shape[0],1)
weights = np.random.rand(2,1)
bias = np.random.rand(1)
learning_rate = 0.0000004
epochs = 1000
开始训练神经网络
weights_final, bias_final = train_network(x,label,weights,bias,learning_rate,epochs)
……
可以看到损失值在不断减小,神经网络模型性能在不断提高。
进行预测
# Prediction
inputs = [[101,76]]
dot_prod = np.dot(inputs, weights_final) + bias_final
preds = sigmoid(dot_prod) >= 1/2
preds
array([[False]])
三、神经网络建立结果可控最小机器人
小机器人——简单理解:就是一个受到了外界刺激(数据输入)的一个神经元(感知器)。多个神经元就是组成神经网络。神经元的核心是激活函数和反向传播机制(包含一个反向作用的函数修改权重和计算损失的函数做迭代条件)。它的工作原理是这样的:输入数据及分配权重——>感知器(神经元/神经网络)通过激活函数处理输入数据并得到输出数据,输出的数据和原始数据集的结果做比较得到误差值,如果误差过大则神经元会触发反向传播机制,通过梯度下降(或者其他函数或算法)修改当前权值,再重新执行输入,反复迭代后,直到误差已经足够低——>输出结果。
AI解答:
感知器、神经元和神经网络是机器学习中的基本概念,它们之间存在密切的关系。
1. 感知器:感知器是一种最简单的人工神经元模型,它接收多个输入信号,通过加权求和和激活函数的处理,输出一个结果。感知器可以用于二分类问题,例如判断一个样本属于两个类别中的哪一个。
2. 神经元:神经元是神经系统中最基本的单元,它接收多个输入信号,通过加权求和和激活函数的处理,输出一个结果。在人工神经网络中,神经元通常被表示为一个节点或单元,它可以接收来自其他神经元的输入信号,并将自己的输出传递给其他神经元。
3. 神经网络:神经网络是由多个神经元组成的计算模型,它可以模拟人类神经系统的结构和功能。神经网络通常由多个层次组成,每一层都包含若干个神经元。每个神经元都有自己的权重和偏置值,这些参数可以通过训练数据进行学习和调整,以使网络能够更好地拟合数据。
综上所述,感知器是神经元的一种特殊形式,而神经网络则是由多个神经元组成的复杂计算模型。感知器和神经元都是神经网络的基础组成部分,它们共同构成了现代机器学习技术的核心。
基本概念复盘及常见问题汇总:
1、人工智能和机器学习和深度学习关系
人工智能、机器学习和深度学习三者之间的关系可以描述为一个层次结构,其中人工智能是最广泛的概念,机器学习是其的一个重要子集,而深度学习则是机器学习的一个特定类型。
1. **人工智能 (Artificial Intelligence, AI)**: 人工智能是一个广义的概念,指的是使计算机或其他机器模拟人类智能的技术。这包括学习、推理、问题解决、感知、语言理解和决策等多个方面。
2. **机器学习 (Machine Learning, ML)**: 机器学习是机器从数据中自动学习和改进的过程,而不依赖于人工编写特定的规则和逻辑。其主要目的是让机器通过数据学习知识并做出预测或决策。
3. **深度学习 (Deep Learning)**: 深度学习是机器学习的一个子集,它使用神经网络模型,特别是深度神经网络,来学习数据的复杂模式和表示。与普通的机器学习算法相比,深度学习需要大量的数据和计算资源,但它能够自动提取和表示数据中的高级特征。
简而言之,人工智能提供了一个广泛的框架,机器学习是实现这一框架的主要手段,而深度学习则是机器学习中的一个特定技术,它强调使用深层神经网络来学习数据的复杂特性。
2、深度学习优点
1. **学习能力强**:深度学习可以自动从数据中提取有用的特征,并使用这些特征来训练模型。这使得它能够处理非常复杂的问题,如图像识别、语音识别和自然语言处理等。
2. **覆盖范围广,适应性好**:深度学习可以应用于许多不同的领域,包括但不限于计算机视觉、自然语言处理、语音识别和推荐系统等。
3. **数据驱动,上限高**:深度学习的性能很大程度上取决于可用的数据量。更多的数据可以帮助深度学习模型更好地理解和泛化问题。
4. **可移植性好**:深度学习算法可以在多个平台上运行,包括CPU、GPU和TPU等。
5. **强大的表征学习能力**:深度学习能通过神经网络的深度结构进行复杂的非线性转换,从而学习数据的丰富的内在表征。
然而,尽管深度学习有许多优点,但也存在一些挑战和局限性,例如计算量大,需要大量的数据和计算资源;模型设计复杂,需要专门的知识和技能;以及可能存在偏见等问题。
3、机器学习和深度学习区别
机器学习和深度学习都是人工智能的子集,但它们之间存在一些关键的区别:
1. **学习方式**:机器学习是一种数据分析方法,它使计算机系统能够从以前的经验中学习并改进其性能。而深度学习是机器学习的一个特定领域,它使用神经网络模型,特别是深度神经网络,来学习数据的复杂模式和表示。
2. **数据依赖性**:深度学习需要大量的数据来训练复杂的模型和提取有用的特征。相比之下,机器学习算法可以在较小的数据集上进行训练,并且可以应用到各种类型的数据上。
3. **硬件需求**:深度学习通常需要更多的计算资源,因为它需要大量的数据和复杂的神经网络结构。然而,机器学习算法可以在普通的计算机上运行,并且不需要太多的计算资源。
4. **模型复杂性**:深度学习模型通常比机器学习模型更复杂,因为它们有更多的参数需要调整。这使得深度学习能够处理更复杂的问题,但也增加了过拟合的风险。
5. **应用领域**:虽然机器学习和深度学习都可以应用于许多不同的领域,但深度学习在图像识别、语音识别和自然语言处理等领域表现出了更强的能力。
4、神经元
神经元是神经系统的基本单位,也被称为神经细胞。它们负责接收、处理和传递信息。每个神经元都由三部分组成:
1. **细胞体**:包含神经元的细胞核和其他细胞器,如线粒体和内质网。
2. **树突**:从细胞体伸出,用于接收其他神经元传来的信息。
3. **轴突**:从细胞体伸出,用于将信息传递给其他神经元或肌肉细胞。当一个神经元被刺激时,这个刺激会沿着树突传到细胞体,然后通过轴突传递出去。这个过程被称为神经冲动。
5、神经元模型
一个最简单的神经元模型可以接收多个输入,并对这些输入进行一些数学运算,然后产生一个输出。具体来说,这个模型可以表示为:
y = f(∑w_ix_i + b)
其中,y 是神经元的输出,x_i 是第 i 个输入,w_i 是对应的权重,b 是偏置,f 是激活函数。这个模型可以是一个2输入的神经元模型。
神经网络则是由多个这样的神经元组成,每个神经元都可以接收上一个神经元的输出作为它的输入。神经网络是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。
6、神经元工作流程
在深度学习中,神经元被视为最基本的计算单元。每个神经元接收多个输入信号,这些信号通过带有权重的连接进行传递,然后加权求和,并通过一个非线性函数(称为激活函数)产生输出。
具体来说,单个神经元通常具有多个树突,主要用来接收传入信息。信息通过轴突传递进来后,经过一系列的计算(例如,细胞核中的新陈代谢过程)最终产生一个信号,这个信号通过轴突传递出去。轴突只有一条,但其尾端有许多轴突末梢可以给其他多个神经元传递信息。
在人工神经网络中,神经元的工作方式可以被抽象为以下的线性模型:所有的输入xi,与相应的权重wi相乘并求和,将求和结果送入到激活函数中,得到最终的输出结果。这样的模型是对生物神经元工作机制的一种简化和模拟。
最后,值得注意的是,虽然单个神经元的工作方式相对简单,但在实际应用中,通常会有数十万甚至上亿个神经元构成的深度神经网络共同工作,完成复杂的模式识别和决策任务。
7、神经网络工作流程
神经网络,又被称为人工神经网络 (ANN) 或模拟神经网络 (SNN),是机器学习的一个重要子领域,也是深度学习算法的核心。神经网络的命名和结构都得到了人脑的启示,能够模仿生物神经元之间传递信号的方式。
神经网络的基本计算单元是神经元,也被称作节点或者单元。每个神经元都可以接收来自其他神经元或外部数据的输入,并根据这些输入进行特定的计算操作,产生一个输出。每个输入都有一个权重,这个权重的大小取决于该输入相对于其他输入的重要性。然后,神经元上会执行一个特定的函数f,也就是激活函数,以引入非线性因素。这是因为现实世界的数据都是非线性的,我们希望神经元也能学习到这些非线性的表示。
具体来说,一个完整的神经网络工作流程可以概括为以下几个步骤:
1. 数据准备:首先需要准备好用于训练和测试的数据。
2. 前向传播:将准备好的数据输入到神经网络中,计算每一层的输出。
3. 计算损失:通过比较神经网络的输出和真实值,计算出损失函数的值。
4. 反向传播:根据损失函数的值,反向传播误差,更新神经网络中的参数(如权重和偏置)。
5. 迭代训练:重复上述过程多次,直到神经网络的性能达到预期为止。8、前馈神经网络和反馈神经网络
前馈神经网络和反馈神经网络是两种不同类型的神经网络结构。
前馈神经网络,如其名称所示,是无反馈的,信息从输入层开始,逐层向前传播至输出层。每一层神经元接收来自前一层神经元的信号并传递到下一层,任何层的输出都不会影响同级层。因此,前馈神经网络可以被视为一个有向无环图。常见的前馈神经网络包括卷积神经网络(CNN)、全连接神经网络(FCN)、生成对抗网络(GAN)等。
相反,反馈神经网络具有记忆功能,神经元不仅可以接收其他神经元的信号,而且还可以接收自己的反馈信号。因此,与前馈神经网络相比,反馈神经网络中的神经元在不同时刻具有不同的状态。反馈神经网络中的信息传播可以是单向也可以是双向传播,因此可以用一个有向循环图或者无向图来表示。常见的反馈神经网络包括循环神经网络(RNN)、长短期记忆网络(LSTM)、Hopfield网络和玻尔兹曼机。
总的来说,这两种神经网络的主要区别在于信息的传播方向:在前馈神经网络中,信息只向前传播;而在反馈神经网络中,信息既可以向前传播也可以向后传播。
9、神经元模型为什么要添加权重?
神经元模型中的权重起着至关重要的作用。它们表示神经元之间的连接强度,权重的大小对应了可能性的大小。在神经网络中,权重被视为未知数,而损失函数则是因变量。这些权重是模型学习的关键组成部分,是通过训练过程动态调整的参数,用于定义模型的行为和适应不同任务的能力。
在模型训练过程中,有很多需要通过反向传播更新的权重,如卷积层、全连接层、批处理化层等。此外,权重初始化也有更深层次的原因,例如打破梯度更新对称性等。因此,权重在神经元模型中起着关键的角色,不仅影响模型的性能,也决定了模型的学习过程和能力。
10、神经元模型为什么要添加bias?
在神经网络中,偏置(bias)的添加是为了增强模型的拟合能力并提高神经元的灵活性。在简单神经元模型中,如果没有偏置项,那么神经元的激活状态仅取决于输入信号与其对应权重的乘积之和。但是,通过加入偏置项,我们实际上是在调整神经元的激活状态,使其能够更好地适应数据。
以sigmoid函数为例,如果没有偏置项,那么输出将仅仅依赖于输入信号与权重的乘积。然而,通过加入偏置项,我们可以在不改变其他参数的情况下,独立地调整神经元的激活状态,从而增加了函数的灵活性和神经元的拟合能力。
具体来说,假设有一个只有一输入一输出的简单网络,如果使用Sigmoid激活函数,并且没有偏置项,那么输出将仅依赖于输入信号与权重的乘积。但是,通过加入偏置项,我们可以使神经元的激活状态更加灵活,从而提高网络的拟合能力。
此外,从实际应用的角度来看,偏置项的存在也有助于提高神经网络的训练精度。例如,在一些实验中,研究者发现在没有偏置项的情况下,神经网络的训练精度往往不能得到提升;而当加入了偏置项后,训练精度反而得到了提高。
11、神经元模型为什么要把输入数据和权重相乘并求和?
在神经元模型中,输入数据与权重相乘并求和的操作是一个核心的步骤。每个输入信号都乘以对应的权重,并且偏置也会被加入到这一过程中,然后这些值会被加在一起,形成加权和。这个加权和被送入激活函数进行非线性变换,产生神经元的输出。
为什么要进行这样的操作呢?主要有以下几个原因:
首先,通过将输入数据与权重相乘并求和,神经元能够调整其对于不同输入信号的响应程度。每个输入信号的权重代表了这个信号相对于其他信号的重要性。如果一个信号的权重大,那么这个信号对于神经元输出的影响就更大;反之,如果一个信号的权重小,那么这个信号对于神经元输出的影响就相对较小。
其次,偏置的存在也是为了调整神经元的激活值。偏置可以被看做是一种可学习的参数,它能够调整神经元的激活函数在输入为零时的截距位置。如果没有偏置参数,神经元的激活函数在输入为零时,其输出总是为零,无法表现出复杂的非线性特征。通过调整偏置参数,可以使神经元的激活函数在输入为零时,其输出值不为零,从而更好地表现出复杂的非线性特征。
最后,通过这种方式,神经网络能够学习到数据中的复杂模式。因为在现实世界中的数据都是非线性的,因此我们希望神经元都可以学习到这些非线性的表示。通过调整权重和偏置,以及使用合适的激活函数,神经网络能够从数据中学习到复杂的非线性关系。
12、反向传播和前向传播的区别
前向传播和反向传播是神经网络训练中的核心算法。简而言之,前向传播是指从神经网络的输入层到输出层的过程,通过输入数据和当前的模型参数,计算网络的输出。具体来说,它从输入层开始,经过一层层的Layer,不断计算每一层的神经网路得到的结果及通过激活函数(如常用的ReLU函数)的本层输出结果,最后得到输出。
反向传播,又称为误差反向传播或backprop,是在前向传播之后进行的操作。其目的是计算损失函数对模型参数的梯度,并从输出层开始反向传递这些梯度信息,以便更新模型参数。为了达到这一目的,反向传播利用了链式法则来计算复合函数的导数,从而高效地计算梯度。
为了更好地理解这两种传播方式,可以将它们视为一个整体的计算图。在这个图中,前向传播是为反向传播准备好要用到的数值,而反向传播则本质上是一种求梯度的高效方法。在实际应用中,这两种传播方式通常与最优化方法(如梯度下降法)结合使用,来训练人工神经网络。
13、反向传播和反馈神经网络的区别?
反向传播(Back-propagation, BP)是神经网络中的关键算法,它的主要作用是根据损失函数反向计算每一层的参数的梯度。这个过程包括两个阶段:前向传播和反向传播。在前向传播阶段,输入数据通过网络向前传递,并在每一层被处理以产生输出;在反向传播阶段,则从最后一层开始,根据损失函数来计算输出误差,并以此误差来反方向地计算更新每一层的参数的梯度。
至于反馈神经网络,它是一种人工神经网络类型,其特点是具有反馈环路。在反馈神经网络中的信息会沿着两个方向流动:一个是前向传播,信息从输入层经过隐藏层流向输出层;另一个是反向传播,即从输出层返回到输入层,通过调整神经元之间的连接权重来优化网络的性能。
因此,可以说反向传播是实现神经网络学习过程的重要方法,而反馈神经网络则是应用了反向传播算法的一种具体的神经网络结构。
14、反向传播中的损失函数(loss)
损失函数,也叫代价函数,是定义在单个样本或整个训练集上的,用于计算模型预测值与真实值之间的误差的函数。它是一个非负实值函数,通常用L(Y, f(x))来表示,损失函数的值越小,说明模型的预测值越接近真实值,从而模型的鲁棒性越好。
在模型的训练阶段,每个批次的训练数据送入模型后,通过前向传播输出预测值,然后损失函数会计算出预测值和真实值之间的差异值,也就是损失值。得到损失值之后,模型通过反向传播去更新各个参数,以降低真实值与预测值之间的损失,使得模型生成的预测值更接近真实值,从而达到学习的目的。
常见的损失函数包括基于距离度量的损失函数、均方差损失、Hinge损失等。例如,在线性回归中,通常使用均方差损失作为损失函数;在SVM中,常常使用Hinge损失。
15、前向传播和前馈神经网络的区别?
前向传播和前馈神经网络是两个在神经网络中经常会被提到的概念,它们之间存在着密切的关系。首先,前向传播是一种计算过程,具体来说,它是将输入数据从输入层开始,经过隐藏层(如果有的话),传递到输出层的过程。
而前馈神经网络,则是实现这一前向传播过程的框架结构。在这个网络中,神经元被按照接收信息的先后顺序分为不同的组,每一组可以看做是一个神经层。每一层中的神经元会接收来自前一层神经元的输出,并将自身的输出传递到下一层神经元。整个网络中的信息只朝着一个方向传播,也就是从输入层向输出层单向传播,因此可以用一个有向无环图来表示。值得注意的是,前馈神经网络可以进一步被分类为全连接前馈神经网络和卷积神经网络等类型。
所以总结一下,前向传播是前馈神经网络中信息流动的一种方式,而前馈神经网络则为这种流动提供了一种可能的结构形式。
16、反向传播和损失函数是必须使用的吗?
不是所有的神经网络都使用反向传播算法。反向传播(Back-propagation, BP)是一种在神经网络中非常常用的参数更新方法,它的主要作用是根据损失函数反向计算每一层的参数的梯度。然而,尽管反向传播在许多神经网络模型的训练中都有应用,比如深度学习、卷积神经网络等,但并非所有的神经网络都使用这种方法。例如,早期的一些简单的神经网络结构可能并不需要反向传播。此外,随着研究的深入,科学家们还在努力寻找反向传播的改进和替代方案。因此,可以认为反向传播是神经网络训练中的一种常见且重要的方法,但并不是所有神经网络都必须使用这种方法。
在神经网络的训练过程中,损失函数并非必须的,但它是关键的一个环节。这是因为,我们通常希望通过训练数据来优化神经网络的参数,使其能够更好地拟合任务需求。在这个过程中,我们需要一个衡量模型预测结果和真实结果之间差距的标准,而损失函数正是提供了这样一个标准。通过反向传播算法,我们可以计算损失函数对模型参数的梯度,并使用优化算法(如梯度下降法)来更新参数以最小化损失函数。
值得注意的是,虽然损失函数是训练神经网络中的重要部分,但并非所有的神经网络模型都需要使用损失函数。例如,对于某些无监督学习任务(如聚类),我们可能并不关心预测的准确性,也就不需要定义损失函数。因此,是否使用损失函数以及如何设计损失函数,需要根据具体的问题和任务来决定。
。
。
。
。
。
。
代码实战——构建一个会学习的小机器人
(1) assign input values
抛给机器人一些问题
# (1) assign input valuesimport numpy as npinput_value=np.array([[0,0],[0,1],[1,1],[1,0]])
(2) assign output values
告诉它正确的答案
# (2) assign output valuesoutput_value=np.array([0,1,1,0])output_value=output_value.reshape(4,1)
(3) assign weights
从不同的角度关注问题
# (3) assign weightsweights = np.array([[0.3],[0.4]])
(4) add bias
告诉机器人处理问题要灵活
# (4) add biasbias = 0.5
(5) activation function
传授给机器人一种解决问题的方法
# (5) activation functiondef sigmoid_func(x):return 1/(1+np.exp(-x))
(6)derivative of sigmoid function
同时教它怎么对错误的结果进行纠正
# (6)derivative of sigmoid functiondef der(x):return sigmoid_func(x)*(1-sigmoid_func(x))
(7)updating weights and bias
不断地更换思考问题的角度和灵活性,当错误率接近0时,机器人已经成为了解决这个问题的专家。
j=0 #debug draw picture
k=[] #debug draw picture
l=[] #debug draw picturefor epochs in range(2000): #控制迭代次数sum = np.dot(input_value, weights) + bias #summation and bias(对输入数据的summation和bias处理)act_output = sigmoid_func(sum) #activation(把数据传入激活函数sigmoid)error = act_output - output_value #calculte error in predict(函数结果值与原数据的Y值作差得到误差值)total_error = np.square(error).mean() #全部误差的平均数作为总的误差act_der = der(act_output) #Backpropagation and chain rule #计算激活函数的导数,,并返回激活函数的导数值derivative = error * act_der #计算误差(error)与激活函数导数(act_der)的乘积,得到偏导数(derivative)final_derivative = np.dot(input_value.T, derivative)#将输入值(input_value)转置(.T),然后与偏导数(derivative)进行点积运算,得到最终的偏导数(final_derivative)#偏导数就是误差与激活函数导数的乘积,它表示了当输入值或权重发生变化时,误差的变化率。通过计算偏导数,可以确定如何更新神经元的权重和偏置,以便最小化误差。j=j+1 #debug draw picturek.append(j) #debug draw picturel.append(total_error) #debug draw pictureprint(j,total_error) #debug draw picture# update weights by gradient descent algorithmweights = weights - 0.5 * final_derivative#将权重(weights)减去0.5乘以最终的偏导数(final_derivative),以更新权重值。# update biasfor i in derivative:#遍历误差与激活函数导数的乘积(derivative),bias = bias - 0.5 * i#将偏置(bias)减去0.5乘以每个误差项的值,以更新偏置值。
#在神经网络训练过程中,反向传播算法用于根据误差梯度来更新权重和偏置值,以便最小化误差。
plt.plot(k,l)
print('weights:',weights)
print('bias:',bias)
(8)prediction
测试一下学习成果,找道题考一考它。
# prediction
pred = np.array([1,0])result = np.dot(pred, weights) + biasres = sigmoid_func(result) >= 1/2print(res)
[False]
(9)Note
此神经网络的激活函数是sigmoid函数,反向传播使用的是梯度下降算法。
梯度下降算法:
1、梯度下降,简单来说,是一种寻找目标函数最小化的方法。它利用梯度信息,通过不断迭代调整参数来寻找合适的目标值。这种方法可以用于求解最小二乘问题(线性和非线性都可以),也是在求解机器学习算法的模型参数,即无约束优化问题时,最常采用的方法之一。
2、关于梯度的概念,可以分为四个层次:导数、偏导数、方向导数和梯度。导数表示函数曲线上的切线斜率;偏导数则是多元函数中一个多变量的函数的导数,是关于其中一个变量的导数,而保持其他变量恒定。
3、在实际应用中,以一元二次函数为例,梯度下降法通过随机选择一个点作为起始点,计算该点的梯度,然后按照梯度的负方向更新参数,重复这个过程,直到满足停止条件为止。这样,每一步都朝着函数值下降最快的方向进行调整,最终找到函数的极小值点。
梯度下降中的偏导数:1、在进行梯度下降时,求偏导数是必要的。这是因为梯度下降法的步骤中,首先需要找到目标函数相对于每个参数的斜率,也就是计算函数的梯度。而这个梯度其实就是函数对各个自变量求偏导后,由偏导数组成的一个向量。因此,我们在使用梯度下降法求解最优化问题时,必须对目标函数进行求偏导,以获取每个参数对目标函数的影响程度,进而更新参数值,使得目标函数逐渐最小化。总的来说,偏导数在梯度下降中扮演了关键的角色,它是执行梯度下降算法的基础和前提。
2、梯度下降法是一种迭代优化算法,用于求解函数的最大值或最小值。在每一步迭代过程中,都会计算目标函数关于每个参数的偏导数,进而获取函数变化率最大的方向和大小,即梯度。然后根据梯度来更新参数的值,使得目标函数朝着最小化的方向逐步变化。因此,我们可以说偏导数在梯度下降法中起着关键的作用,它是执行梯度下降算法的基础和前提。总的来说,求偏导数和进行梯度下降是密切相关的两步过程,两者共同构成了求解最优化问题的重要方法。
(10)参数说明:
通过修改神经网络中的:
(输入数据)input和(输出数据)output是正确的X(特征)和Y(相应)
(权重值)weights = weights - 0.5 * final_derivative、
(偏置值)bias = bias - 0.5 * i、
(迭代次数)epochs可以很简单的控制神经网络的优化程度。
此外,神经网络的激活函数、反向传播算法、和损失函数的选取也是至关重要的。
解答一个小困惑:
像是这种简单的问题,貌似我们可以通过if语句就能完美的实现,那为什么我们还有用更加复杂的神经网络呢?
这里使用神经网络处理问题只是举一个最简单的例子了解神经网络的工作原理,而并非是最好的解决方案。但是从结果可以看出,神经网络通过模仿人类神经元的方式,让机器仿佛可以向人一样学习,效果是很好的,非常值得人们的期待的。
而且搭建神经网络(神经元)和使用if分支语句的本质是不同的,且前者更具有普遍性。试想,当我们要处理一个非常庞大且计算复杂的数据的时候,我们是希望通过if分支语句一步一步去手动计算并处理,还是通过搭建一个神经网络给出一定的权重和误差标准和定义一个函数让程序自己去找合适的答案方便还是前者方便呢?答案肯定是后者。无论是硬件还是软件的发展其目的都是为了人能更便利的解决问题,所以科技才会不断的推陈出新,不断的进步,因此,使用神经网络模型不但大大降低了人工成本,更是科技进步的一个里程碑。只要我们不断的在此基础上创新,发现和改进更多的解决实际问题的好方法、好模型,那么人工智能的发展将始终充满蓬勃生机。
四、矩阵乘积和手工验算2层神经网络
1、介绍矩阵乘法
import numpy as np
a,b = np.arange(3), np.arange(3,6)
print(np.dot(a,b))
14
print(a @ b)#dot的另一种写法
14
c,d = np.arange(4).reshape(2,2), np.arange(3,9).reshape(2,3)
print(np.dot(c,d))
[[ 6 7 8][24 29 34]]
print(c @ d)
[[ 6 7 8][24 29 34]]
from IPython.display import Image
Image(filename='./Lesson45-DL18.PNG')
2、神经网络的分类:
1.Feedforward: On a feedforward neural network, we have a set of input features and some random weights. Notice that in this case, we are taking random weights that we will optimize using backward propagation.
1. 前馈神经网络:在前馈神经网络中,我们有一组输入特征和一些随机权重。注意在这种情况下,我们使用后向传播来优化随机权重。
2.Backpropagation: During backpropagation, we calculate the error between predicted output and target output and then use an algorithm (gradient descent) to update the weight values.
2. 反向传播:在反向传播过程中,我们计算预测输出和目标输出之间的误差,然后使用一种算法(梯度下降)来更新权重值。
(以下两个实验均以简单的前馈神经网络实现)
3、单层神经网络(神经元Neuron)模型:
(1)单层神经网络手工验算过程
1.定义输入数据
x = [1,2,3]
2.定义权重
w = [0.7,0.6,1.4]
3.输入与权重进行点乘(对应相乘并求和)
np.dot(x,w)
6.1
4.定义偏置值
bias = 1
5.神经网络核心计算模型
np.dot(x,w) + bias
7.1
6.定义激活函数
def sigmoid_func(x):return 1/(1+np.exp(-x))
7.调用激活函数处理前面模型计算好的结果
sigmoid_func(7.1) #feedforward NN
0.9991755753136017
(2)实现单层神经网络的封装
import numpy as npdef sigmoid__func(x):return 1 / (1 + np.exp(-x))class Neuron:def __init__(self, weights, bias):self.weights = weightsself.bias = biasdef feedforward(self, inputs):# summationtotal = np.dot(self.weights, inputs) + self.biasreturn sigmoid_func(total)weights = np.array([0.7, 0.6, 1.4]) # w1 = 0.7, w2 = 0.6, 1.4
bias = 1 # bias = 1
n=Neuron(weights, bias)x = np.array([1,2,3]) # x1 = 1, x2 = 2, x3
print(n.feedforward(x)) # 0.9991755753136017
0.9991755753136017
4、双层神经网络(Neural NetWork)模型:
(1)双层神经网络手工验算过程
8.基于第一层神经网络的计算结果作为第二层的输入(可以理解为是神经网络的一个递归过程)
h = [0.9991755753136017,0.9991755753136017,0.9991755753136017]
9.权重不变
w = [0.7,0.6,1.4]
10.偏置值不变
bias = 1
11.第二次的输入与权重进行点乘(对应相乘并求和)
np.dot(h,w)
2.6977740533467243
12.加上偏置值
np.dot(h,w) + bias
3.6977740533467243
13.调用激活函数
sigmoid_func(3.6977740533467243)
0.9758205133194947
(2)实现双层神经网络的封装
import numpy as np# ... code from previous section hereclass OurNeuralNetwork:'''A neural network with:- 3 inputs- a hidden layer with 3 neurons (h1, h2, h3)- an output layer with 1 neuron (o1)Each neuron has the same weights and bias:- w = [0.7, 0.6, 1.4]- bias = 1'''def __init__(self):weights = np.array([0.7, 0.6, 1.4])bias = 1# The Neuron class here is from the previous sectionself.h1 = Neuron(weights, bias)self.h2 = Neuron(weights, bias)self.h3 = Neuron(weights, bias)self.o1 = Neuron(weights, bias)def feedforward(self, x):out_h1 = self.h1.feedforward(x)out_h2 = self.h2.feedforward(x)out_h3 = self.h3.feedforward(x)# The inputs for o1 are the outputs from h1 and h2out_o1 = self.o1.feedforward(np.array([out_h1, out_h2, out_h3]))return out_o1network = OurNeuralNetwork()
x = np.array([1, 2, 3])
print(network.feedforward(x)) # 0.9758205133194947
0.9758205133194947
五、Keras,TensorFlow和PyTorch比较及应用TensorFlow建立ANN模型
1、深度学习框架介绍
from IPython.display import Image
Image(filename='./Lesson47-comp2.png')
from IPython.display import Image
Image(filename='./Lesson47-comp1.png')
from IPython.display import Image
Image(filename='./Lesson47-comp3.png')
from IPython.display import Image
Image(filename='./Lesson46-NN2.JPG')
输入被送入感知器
每个输入乘以权重
求和然后加上偏置
应用激活函数。注意,这里我们使用阶跃函数,但也有其他更复杂的激活函数,如sigmoid、双曲正切(tanh)、整流器(relu)等。不用担心,我们将在未来涵盖许多这些函数!
输出要么触发为1,要么不触发为0。注意我们使用y hat来标记我们的感知器模型产生的输出
2、安装tensorflow并使用内涵的Keras库进行实验
命令行安装:
#pip install tensorflow#conda install -c conda-forge tensorflow#cpu和gpu的版本并不兼容,如果没有gpu,只用cpu的即可。
导航界面安装:
Keras是一个强大且易于使用的免费开源Python库,用于开发和评估深度学习模型。
您将在本教程中涵盖以下步骤:
(1)定义Keras模型
(2)加载数据
(3)编译Keras模型
(4)拟合Keras模型
(5)评估Keras模型
(6)进行预测
(1)导入所需库
# first neural network with keras tutorial
from numpy import loadtxt
from keras.models import Sequential
from keras.layers import Dense
1. numpy:是一个用于科学计算的Python库,提供了多维数组对象、线性代数、傅里叶变换等功能。
2. keras:是一个用于构建和训练深度学习模型的高级API,可以运行在TensorFlow、Microsoft-CNTK或Theano之上。它提供了Sequential和Functional API两种模型构建方式,以及各种常见的神经网络层和损失函数等组件。
3. Sequential:是keras中的一种模型结构,由多个网络层依次堆叠而成,通常用于构建简单的神经网络。
4. Dense:是keras中的一种全连接层(也称为密集层),每个神经元与前一层的所有神经元相连。它是神经网络中最基础的组成部分之一,常用于实现分类、回归等任务。
from IPython.display import Image
Image(filename='./Lesson47-ANN1.png')
Sequential API——串行的网络结构模型接口
Functional API——并行的网络结构模型接口
Model Subclassing——嵌套型的网络结构模型接口
(2)加载数据集(印第安pima部落的肥胖症数据分析)
# load the dataset
dataset = loadtxt('Lesson47-pima-indians-diabetes.data', delimiter=',')
dataset#The variables can be summarized as follows:#Input Variables (X):#Number of times pregnant
#Plasma glucose concentration a 2 hours in an oral glucose tolerance test
#Diastolic blood pressure (mm Hg)
#Triceps skin fold thickness (mm)
#2-Hour serum insulin (mu U/ml)
#Body mass index (weight in kg/(height in m)^2)
#Diabetes pedigree function
#Age (years)#Output Variables (y):#Class variable (0 or 1)
(3)划分特征和响应集
# split into input (X) and output (y) variables
X = dataset[:,0:8]
y = dataset[:,8]
(4)定义一个串行的(Sequential)Keras网络结构模型
# define the keras model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
这是一个使用Keras库构建的简单神经网络模型。模型包含一个输入层(8个神经元),两个隐藏层(分别有12个和8个神经元),以及一个输出层(1个神经元)。激活函数分别为ReLU和Sigmoid。
输入层必须是8,因为特征集的列就是8个,这里必须要对应上。
(5)编译模型
# compile the keras model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])#Binary cross-entropy is for multi-label classifications
#Adam is a replacement optimization algorithm for stochastic gradient descent for training deep learning models.
这段代码是用于编译神经网络模型的。其中,loss参数指定了损失函数为二元交叉熵(binary_crossentropy),optimizer参数指定了优化器为Adam,metrics参数指定了评估指标为准确率(accuracy)。
在这个例子中,模型是一个用于二分类问题的神经网络模型,因此损失函数选择了二元交叉熵(binary_crossentropy),它适用于二分类问题。
优化器选择了Adam,它是一种常用的自适应学习率优化算法,能够有效地更新模型参数。
评估指标选择了准确率(accuracy),它是衡量模型预测结果与真实标签匹配程度的常用指标,适用于二分类问题。这些参数的选择是基于经验和实践的,可以根据具体任务和数据进行调整。
from IPython.display import Image
Image(filename='./Lesson48-SGD.png')
(6)训练模型
# fit the keras model on the dataset
model.fit(X, y, epochs=200, batch_size=10)
这是一个使用Keras库训练神经网络模型的代码片段。它的作用是对输入数据X和标签y进行训练,设置训练轮数(epochs)为200,批量大小(batch_size)为10。
(7)评估模型
# evaluate the keras model
_, accuracy = model.evaluate(X, y)
print('Accuracy: %.2f' % (accuracy*100))
(8)预测模型
# make class predictions with the model
predictions = model.predict(X)
# summarize the first 5 cases
for i in range(len(X)):print('%s => %d (expected %d)' % (X[i].tolist(), predictions[i], y[i]))
(9)模型总结
model.summary() #for dense level, output_size * (input_size + 1) == number_parameters
神经网络模型:
参数分析:
该神经网络一共有三个全连接层(Dense)
Dense1:108(8*12+12*1)第一个全连接层中的全部线数加第二层(hide1)结点个数(偏置值)
Dense2:104(8*12+8*1)第二个全连接层中的全部线数加第三层(hide2)结点个数(偏置值)
Dense3:9(8+1)第三个全连接层中的全部线数加第四层(输出层)结点个数
完整代码及步骤:
(1)定义Keras模型
(2)加载数据
(3)编译Keras模型
(4)拟合Keras模型
(5)评估Keras模型
(6)进行预测
# first neural network with keras tutorial
from numpy import loadtxt
from keras.models import Sequential
from keras.layers import Dense# load the dataset
dataset = loadtxt('Lesson47-pima-indians-diabetes.data', delimiter=',')# split into input (X) and output (y) variables
X = dataset[:,0:8]
y = dataset[:,8]# define the keras model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))# compile the keras model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])# fit the keras model on the dataset
model.fit(X, y, epochs=200)# evaluate the keras model
_, accuracy = model.evaluate(X, y)
print('Accuracy: %.2f' % (accuracy*100))
六、Activation Function为什么Relu比Sigmoid好 for Vanishing Gradient
from IPython.display import Image
Image(filename='./Lesson48-Relu.gif')
Sigmoid或Logistic激活函数(软步)-它主要用于二元分类问题(即输出值范围为0-1)。...这是用于分类问题的广泛使用的激活函数,但这个函数更容易导致后期层的饱和,使训练更加困难。
简单讲,建立一个多层的神经网络必然要使每层发挥其功能,结果一层sigmoid就把数据干饱和了,后面几层干啥子?
from IPython.display import Image
Image(filename='./Lesson48-DL10.png')
from IPython.display import Image
Image(filename='./Lesson48-ActivationFunctions.png')
# show comparision
def sigmoid(xx):return 1 / (1 + np.exp(-xx))def derivative(xx):return sigmoid(xx) * (1.0 - sigmoid(xx))xx = np.linspace(-10, 10, 1000)y1 = sigmoid(xx)
y2 = derivative(xx)plt.plot(xx, y1, label='sigmoid')
plt.plot(xx, y2, label='derivative')
plt.legend(loc='upper left')
plt.show()
在反向传播时使用梯度下降算法,势必要用到求激活函数sigmoid的导数,但是如果当数据不在-2.5到2.5之间时,sigmoid导数的大小是趋近于0的,如果用此值来做梯度下降的话,当前权重减去一个趋于0的数,是不会发生明显改变的,也就是造成了“梯度消失”的假象,模型检测到梯度变化太小就不会继续优化运行下去。
from IPython.display import Image
Image(filename='./Lesson48-2.png')
from IPython.display import Image
Image(filename='./Lesson48-1.png')
from IPython.display import Image
Image(filename='./Lesson48-3.png')
结论
ReLU激活函数和Sigmoid激活函数在处理梯度消失问题上有显著的不同。
Sigmoid函数的导数在0附近才有较好的激活性,在正负饱和区的梯度都接近于0,这会导致梯度弥散。
这是因为Sigmoid函数的形状为一条S型曲线,其取值范围为(0,1),且其导数在两端的值都非常小,近乎于0。
而ReLU函数则不存在这个问题,它的导数在大于0的部分是恒定的,不会因为输入值的大小而改变,所以ReLU不会出现梯度弥散现象。
此外,ReLU函数在负半区的导数为0,神经元一旦激活值进入负半区,那么梯度就会为0,也就是说这个神经元会处于非活跃状态,这就实现了稀疏性。
再者,ReLU函数的导数计算更快,程序实现就是一个if-else语句,而sigmoid函数要进行浮点四则运算。
因此,对于解决梯度消失问题来说,ReLU函数比Sigmoid函数更具有优势。
七、调整Activation Function参数对神经网络的影响
from IPython.display import Image
Image(filename='./Lesson48-Keras-Dense-Layer.gif')
输入被送入感知器
每个输入乘以权重
求和然后加上偏置
应用激活函数。注意,这里我们使用阶跃函数,但也有其他更复杂的激活函数,如sigmoid、双曲正切(tanh)、整流器(relu)等。不用担心,我们将在未来涵盖许多这些函数!
输出要么触发为1,要么不触发为0。注意我们使用y hat来标记我们的感知器模型产生的输出
感知器,也被称为感知机,是由Frank Rosenblatt在1957年就职于康奈尔航空实验室(Cornell Aeronautical Laboratory)时发明的一种人工神经网络。它被视为一种最简单形式的前馈式人工神经网络,是一种二元线性分类器。感知器是人工神经网络中的一种典型结构,其特性在于结构简单,对所能解决的问题存在收敛算法,并能从数学上严格证明。在神经网络研究中起到了重要的作用。单层感知器(Single Layer Perceptron)是最简单的神经网络。
# scatter plot of the circles dataset with points colored by class
from sklearn.datasets import make_circles
from numpy import where
from matplotlib import pyplot
# generate circles
X, y = make_circles(n_samples=1000, noise=0.1, random_state=1)
# select indices of points with each class label
for i in range(2):samples_ix = where(y == i)pyplot.scatter(X[samples_ix, 0], X[samples_ix, 1], label=str(i))
pyplot.legend()
pyplot.show()
1、activation='tanh'
# mlp for the two circles classification problem
from sklearn.datasets import make_circles
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import SGD
from keras.initializers import RandomUniform
from matplotlib import pyplot
# generate 2d classification dataset
X, y = make_circles(n_samples=1000, noise=0.1, random_state=1)
# scale input data to [-1,1]
scaler = MinMaxScaler(feature_range=(-1, 1))
X = scaler.fit_transform(X)
# split into train and test
n_train = 500
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
# define model
model = Sequential()
init = RandomUniform(minval=0, maxval=1)
model.add(Dense(5, input_dim=2, activation='tanh', kernel_initializer=init))
model.add(Dense(1, activation='sigmoid', kernel_initializer=init))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()
from sklearn.datasets import make_circles
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Dense
from keras.models import Sequential#Stochastic gradient descent (often abbreviated SGD) is an iterative method for optimizing an objective function with
#suitable smoothness properties (e.g. differentiable or subdifferentiable).
#Adam combines the best properties of the AdaGrad and RMSProp algorithms to provide an optimization algorithm that can
#handle sparse gradients on noisy problems. Adam is relatively easy to configure where the default configuration parameters
#do well on most problems
from keras.optimizers import SGD
from tensorflow.keras.optimizers import Adam
#Initializer that generates tensors with a uniform distribution
#A "Keras tensor" is a tensor that was returned by a Keras layer, (Layer class) or by Input
from keras.initializers import RandomUniform from matplotlib import pyplot
# generate 2d classification dataset
X, y = make_circles(n_samples=1000, noise=0.1, random_state=1)
# scale input data to [-1,1]
scaler = MinMaxScaler(feature_range=(-1, 1))
X = scaler.fit_transform(X)
# split into train and test
n_train = 500
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
什么是Tensor?
from IPython.display import Image
Image(filename='./Lesson49-7.png')
- Tensor(张量)是机器学习和深度学习中常用的数据结构,可以看作是多维数组或矩阵。
- 在神经网络中,张量通常用于表示输入数据、权重、偏置和输出等。
- 张量的维度可以是任意的,例如一维张量可以表示向量,二维张量可以表示矩阵,三维张量可以表示图像或视频等。张量的每个元素都可以是一个标量(0维张量),也可以是一个向量、矩阵或其他张量(高维张量)。
- 在 TensorFlow 和 PyTorch 等深度学习框架中,张量是最基本的数据类型之一,并且提供了丰富的操作和函数来处理和操作张量。
from IPython.display import Image
Image(filename='./Lesson49-tensorflow.jpg')
from IPython.display import Image
Image(filename='./Lesson49-tensor3.jpg')
2、activation='relu'
# define model
model = Sequential()
init = RandomUniform(minval=0, maxval=1)
model.add(Dense(5, input_dim=2, activation='relu', kernel_initializer=init))
model.add(Dense(1, activation='sigmoid', kernel_initializer=init))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()
3、activation='sigmoid'
# define model
model = Sequential()
init = RandomUniform(minval=0, maxval=1)
model.add(Dense(5, input_dim=2, activation='sigmoid', kernel_initializer=init))
model.add(Dense(1, activation='sigmoid', kernel_initializer=init))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()
4、添加更多的Dense层,使用多种不同的 activation函数
#The number of hidden layers can be increased from 1 to 5
# define model
init = RandomUniform(minval=0, maxval=1)
model = Sequential()
model.add(Dense(5, input_dim=2, activation='tanh', kernel_initializer=init))
model.add(Dense(5, activation='tanh', kernel_initializer=init))
model.add(Dense(5, activation='tanh', kernel_initializer=init))
model.add(Dense(5, activation='tanh', kernel_initializer=init))
#Initializers define the way to set the initial random weights of Keras layers. The keyword arguments used for passing
#initializers to layers depends on the layer.
model.add(Dense(5, activation='tanh', kernel_initializer=init))
model.add(Dense(1, activation='sigmoid', kernel_initializer=init))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()
# define model
model = Sequential()
model.add(Dense(5, input_dim=2, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(5, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(5, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(5, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(5, activation='relu', kernel_initializer='he_uniform'))
#he_uniform . Draws samples from a uniform distribution within [-limit, limit] , where limit = sqrt(6 / fan_in)
#( fan_in is the number of input units in the weight tensor).model.add(Dense(1, activation='sigmoid'))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()
from IPython.display import Image
Image(filename='./Lesson49-6.png')
# define model
init = RandomUniform(minval=0, maxval=1)
model = Sequential()
model.add(Dense(5, input_dim=2, activation='relu', kernel_initializer=init))
model.add(Dense(5, activation='relu', kernel_initializer=init))
model.add(Dense(5, activation='relu', kernel_initializer=init))
model.add(Dense(5, activation='relu', kernel_initializer=init))
model.add(Dense(5, activation='relu', kernel_initializer=init))
model.add(Dense(1, activation='sigmoid', kernel_initializer=init))
# compile model
opt = SGD(lr=0.01, momentum=0.9)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=500, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
# plot training history
pyplot.plot(history.history['accuracy'], label='train')
pyplot.plot(history.history['val_accuracy'], label='test')
pyplot.legend()
pyplot.show()