深度学习简介:前馈神经网络FFNN(又名多层感知器MLP)
深度前馈神经网络(FFNN) -又名多层感知器(MLP)
人工神经网络(ANN)由许多相互连接的神经元组成:
来自人工神经网络(ANN)的单个神经元
每个神经元接受一些浮点数(例如1.0、0.5、-1.0),并将它们乘以一些称为权重的其他浮点数(例如0.7,0.6,1.4)(1.0 * 0.7 = 0.7,0.5 * 0.6 = 0.3, -1.0 * 1.4 = -1.4)。权重作为一种机制,用于关注或忽略某些输入。然后将加权输入(例如0.7 + 0.3 + -1.4 = -0.4)和偏差值(例如-0.4 + -0.1 = -0.5)相加。
根据神经元的激活函数(y = f(x)),将求和后的值(x)转换为输出值(y)。以下是一些常用的激活函数:
一些热门激活函数
例如-0.5→-0.05,如果我们使用Leaky ReLU激活函数:y = f(x) = f(-0.5) = max(0.1*-0.5, -0.5) = max(-0.05, -0.5) = -0.05
神经元的输出值(例如-0.05)通常是另一个神经元的输入。
神经元的输出值经常作为人工神经网络(ANN)中其他神经元的输入
Perceptron是最早的神经网络之一,仅由一个神经元组成
最早的神经网络之一被称为感知器,它只有一个神经元。
感知器
感知器神经元的输出作为最终的预测。
每个神经元都是一个线性二元分类器(例如输出值> = 0表示蓝色类,而输出值<0表示红色类)
让我们编写我们自己的感知器,Python代码如下:
import numpy as np class Neuron: def __init__(self, n_inputs, bias = 0., weights = None): self.b = bias if weights: self.ws = np.array(weights) else: self.ws = np.random.rand(n_inputs) def __call__(self, xs): return self._f(xs @ self.ws + self.b) def _f(self, x): return max(x*.1, x)
(注意:我们在上面的示例中没有包含任何学习算法)
perceptron = Neuron(n_inputs = 3, bias = -0.1, weights = [0.7, 0.6, 1.4]) perceptron([1.0, 0.5, -1.0])
-0.04999999999999999
请注意,通过调整权重和偏差的值,您可以调整神经元的 决策边界。 (注意:神经元 通过更新其权重和偏差值来学习 ,以减少其决策的误差)。
如果一个神经网络能满足我们的需要(作为一个分类器),为什么我们需要这么多神经元呢?
限制:神经元是一个二元分类器,因为它只能学习区分两个类(如蓝色和红色)的最大值。神经元是一个线性分类器,因为它的决策边界是二维数据的直线(或三维数据的平面,等等)
不幸的是,单个神经元无法对非线性可分离数据进行分类,因为它们只能学习线性决策边界。
然而,通过将神经元组合在一起,我们实际上是在组合它们的决策边界。因此,由多个神经元组成的神经网络能够学习非线性决策边界。
神经元根据特定的网络结构连接在一起。尽管有不同的体系结构,但几乎所有的体系结构都包含层。(注:同一层神经元不相互连接)
神经网络包含层
通常有一个输入层(包含多个神经元等于数据中输入特征的数量),一个输出层(包含多个等于类数的神经元)和一个隐藏层(包含任意数量的神经元) )。
深度神经网络包含多个隐藏层
可以有多个隐层来允许神经网络学习更复杂的决策边界(任何具有多个隐层的神经网络都被认为是深度神经网络)。
让我们建立一个深度神经网络来描绘这幅画:
我们的人工神经网络将学习绘制一个示例图像(它将学习将特定颜色与图像的特定区域相关联)
让我们下载图像并将其像素加载到一个数组中,Python代码如下:
!curl -O https://pmcvariety.files.wordpress.com/2018/04/twitter-logo.jpg?w=100&h=100&crop=1 from PIL import Image image = Image.open('twitter-logo.jpg?w=100') import numpy as np image_array = np.asarray(image)
现在教ANN画画是一项监督学习任务,所以我们需要创建一个带标签的训练集(我们的训练数据将为每个输入提供输入和预期输出标签)。训练输入将有2个值(每个像素的x、y坐标)。
考虑到图像的简单性,我们实际上可以用两种方法来解决这个问题。分类问题(在给定xy坐标的情况下,神经网络预测像素属于“蓝色”类还是“灰色”类)或回归问题(在给定其坐标的情况下,神经网络预测像素的RGB值)。
如果将其视为回归问题:训练输出将有3个值(每个像素的标准化r、g、b值)。
training_inputs,training_outputs = [],[] for row,rgbs in enumerate(image_array): for column,rgb in enumerate(rgbs): training_inputs.append((row,column)) r,g,b = rgb training_outputs.append((r/255,g/255,b/255))
现在让我们创建我们的ANN:
全连接前馈神经网络(FFNN) - 又名多层感知器(MLP)
- 它应该在输入层中有2个神经元(因为有2个值可以采用:x和y坐标)。
- 它应该在输出层有3个神经元(因为要学习3个值:r,g,b)。
- 隐藏层的数量和每个隐藏层中的神经元数量是两个要进行实验的超参数(以及我们将训练它的epochs数,激活函数等) - 我将使用10个隐藏层,每个隐藏层包含100个神经元(使其成为一个深度神经网络)
from sklearn.neural_network import MLPRegressor ann = MLPRegressor(hidden_layer_sizes= tuple(100 for _ in range(10))) ann.fit(training_inputs, training_outputs)
训练好的网络现在可以预测任何坐标(例如x,y = 1,1)的归一化rgb值。
ann.predict([[1,1]])
array([[0.95479563, 0.95626562, 0.97069882]])
让我们使用ANN来预测每个坐标的rgb值,并让我们显示整个图像的预测rgb值,看看效果如何
predicted_outputs = ann.predict(training_inputs) predicted_image_array = np.zeros_like(image_array) i = 0 for row,rgbs in enumerate(predicted_image_array): for column in range(len(rgbs)): r,g,b = predicted_outputs[i] predicted_image_array[row][column] = [r*255,g*255,b*255] i += 1 Image.fromarray(predicted_image_array)
可以尝试更改超参数以获得更好的结果。