定义
为了理解神经网络,我们应该先理解神经网络的组成单元——神经元。神经元也叫做感知器。感知器算法在上个世纪50-70年代很流行,也成功解决了很多问题。并且,感知器算法也是非常简单的。
参考
- 感知机的输入是多维样本:
- 样本的每一个维度对应一个权重:
- Perceptron对输入样本经过一次线性变化:,
简记为:,其中b是一个偏置项常数。 - 后再跟一次激非线性活函数:,其中
代码
使用Perceptron模拟实现逻辑与和逻辑或
首先定义Perceptron类
from functools import reduce
class Perceptron:
def __init__(self, input_dim, activator) -> None:
"""
Initialize the perceptron, including the dimensions of input parameters and the activation function used
"""
self.activator = activator
# According to the number of input parameters, initialize the corresponding weight vector
self.weights = [0.0 for _ in range(input_dim)]
# initialize the corresponding bias
self.bias = 0.0
def __str__(self):
"""
return the learned weights and bia to the sys.stdout
"""
return f"weights:\t{self.weights}\nbias:\t{self.bias}"
def train(self, input_values, labels, iterations, lr):
"""
training the perceptron's weights and bias:
need input_values(train_set), labels(groud_truth), iterations(epoch), lr(learning rate)
"""
for i in range(iterations):
print(f"EPOCH {i}")
print(f"Before\t{str(self)}", end="\n")
self._train_one_epoch(input_values, labels, lr)
print(f"After\t{str(self)}")
def _train_one_epoch(self, input_values, labels, lr):
"""
All data is trained once and called an epoch.
"""
for data, label in zip(input_values, labels):
# Computes the output of an input sample given the current weights of the perceptron
output = self.predict(data)
# updates weights
self._update_weights(data, label, output, lr)
def predict(self, data):
"""
Computes the perceptron's predict for the data.
"""
return self.activator(
reduce(lambda x, y: x + y, map(lambda a, b: a * b, self.weights, data))
+ self.bias
)
def _update_weights(self, data, label, output, lr):
"""
update the weights and bias of perceptron according the target rule.
"""
self.weights = list(
map(lambda x, y: y + lr * (label - output) * x, data, self.weights)
)
self.bias += lr * (label - output)
- 这里更新权重和偏置的过程按照如下规则(个人理解为机器学习的优化目标函数):
定义训练过程
- 这里使用符号函数作为激活函数
def sign(x):
"""
Next, we use this perceptron class to implement the and function.
"""
# define sign activate function
return 1 if x > 0 else 0
def get_training_dataset():
"""
construct training set based on 'and' oprands true table.
"""
# datas = [[1, 1], [0, 0], [1, 0], [0, 1]]
# labels = [1, 0, 0, 0]
datas = [[1, 1], [0, 0], [1, 0], [0, 1]]
labels = [1, 0, 1, 1]
return datas, labels
def train_perceptron(iterations, lr):
p = Perceptron(input_dim=2, activator=sign)
p.train(*get_training_dataset(), iterations=iterations, lr=lr)
return p
测试
if __name__ == "__main__":
perceptron = train_perceptron(10, 0.1)
# test and
# print(f"1 and 1 ={perceptron .predict([1, 1])}")
# print(f"0 and 0 ={perceptron .predict([0, 0])}")
# print(f"1 and 0 = {perceptron .predict([1, 0])}")
# print(f"0 and 1 = {perceptron .predict([0, 1])}")
# test or
print(f"1 and 1 ={perceptron .predict([1, 1])}")
print(f"0 and 0 ={perceptron .predict([0, 0])}")
print(f"1 and 0 = {perceptron .predict([1, 0])}")
print(f"0 and 1 = {perceptron .predict([0, 1])}")
···