AI实战:从入门到精通系列——用感知器实现情感分类(一)
AI实战:从入门到精通系列——用感知器实现情感分类(二)
前言
上世纪80年代,BP(BackPropagation)算法被提出,用于多层神经网络的参数计算,以解决非线性分类和学习的问题。然而,人工神经网络的设计一直缺少相应的严格的数学理论支持,之后BP算法更被指出存在梯度消失问题,因此无法对前层进行有效的学习。
概念
-
全连接(full connected, FC)神经网络
FC神经网络示意图:
- 特点:
- 同一层的神经元之间没有连接。
- 第N层的每个神经元和第N-1层的所有神经元相连(这就是full connected的含义),第N-1层神经元的输出就是第N层神经元的输入。
- 每个连接都有一个权值。
- 特点:
-
反向传播算法(Back Propagation)
点击自行查阅:反向传播算法推导
-
全连接神经网络的输出计算公式:
a ⃗ = r ( W ⋅ x ⃗ ) \vec{a}=r(W\centerdot\vec{x})\qquad a=r(W⋅x)
其中 r r r 表示relu 函数: r ( x ) = m a x ( 0 , x ) r(x)=max(0, x) r(x)=max(0,x)
-
目标函数
均方差:
E d ≡ 1 2 ∑ i ∈ o u t p u t s ( t i − y i ) 2 E_d\equiv\frac{1}{2}\sum_{i\in outputs}(t_i-y_i)^2 Ed≡21∑i∈outputs(ti−yi)2
-
权值更新方法:
-
偏置项更新方法:
-
误差项 δ δ δ 的计算方法:
-
参数说明
每个训练样本为 ( x ⃗ , t ⃗ ) (\vec{x}, \vec{t}) (x,t)
x ⃗ \vec{x} x 是输入
y ⃗ \vec{y} y 是神经网络的输出
δ ( l ) \delta^{(l)} δ(l) 是第 l l l 层的误差项
a ( l ) a^{(l)} a(l) 是第 l l l 层的输出
-
python实现全连接神经网络
-
全连接层实现类
fc_net.pyclass FullConnectedLayer(object): def __init__(self, input_size, output_size, activator): ''' 构造函数 input_size: 本层输入向量的维度 output_size: 本层输出向量的维度 activator: 激活函数 ''' self.input_size = input_size self.output_size = output_size self.activator = activator # 权重数组W self.W = np.random.uniform(-0.1, 0.1, (output_size, input_size)) # 偏置项b self.b = np.zeros((output_size, 1)) # 输出向量 self.output = np.zeros((output_size, 1)) def forward(self, input_array): ''' 前向计算 input_array: 输入向量,维度必须等于input_size ''' self.input = input_array self.output = self.activator.forward(np.dot(self.W, input_array) + self.b) def backward(self, delta_array): ''' 反向计算W和b的梯度 delta_array: 从上一层传递过来的误差项 ''' self.delta = self.activator.backward(self.input) * np.dot(self.W.T, delta_array) self.W_grad = np.dot(delta_array, self.input.T) self.b_grad = delta_array def update(self, learning_rate): ''' 使用梯度下降算法更新权重 ''' self.W += learning_rate * self.W_grad self.b += learning_rate * self.b_grad
-
Relu激活函数类
class ReluActivator(object): def forward(self, weighted_input): return np.maximum(weighted_input, 0) def backward(self, output): return np.where(output > 0, 1, 0)
-
全连接神经网络类
class Network(object): def __init__(self, layers): ''' 构造函数 ''' self.layers = [] for i in range(len(layers) - 1): self.layers.append(FullConnectedLayer(layers[i], layers[i+1], ReluActivator())) def predict(self, sample): ''' 使用神经网络实现预测 sample: 输入样本 ''' output = sample for layer in self.layers: layer.forward(output) output = layer.output return output def train(self, labels, data_set, rate, epoch): ''' 训练函数 labels: 样本标签 data_set: 输入样本 rate: 学习率 epoch: 训练轮数 ''' for i in range(epoch): for d in range(len(data_set)): self.train_one_sample(labels[d], data_set[d], rate) def train_one_sample(self, label, sample, rate): self.predict(sample) self.calc_gradient(label) self.update_weight(rate) def calc_gradient(self, label): # 计算梯度 delta = self.layers[-1].activator.backward(self.layers[-1].output) * (label - self.layers[-1].output) for layer in self.layers[::-1]:#从后向前计算 layer.backward(delta) delta = layer.delta return delta def update_weight(self, rate): #更新权值 for layer in self.layers: layer.update(rate)
后续
使用全连接神经网络训练微博情感分类模型