我想制作一个像 w1x1+w2x2+w3*x3+b1 这样的单神经元函数 我的训练输入是
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[1, 1, 0],
[0, 1, 1],
[1, 1, 1],
[2, 0, 0]
训练输出是:
[1,2,0,1,0,2,3]
我尝试用一种热编码编写代码,但失败了。我是 AI 编码新手,不想使用任何 AI 库,例如 Pytorch 和 Tensorflow 或 scikitlearn。这个问题困扰了我两周,我也尝试了不同的代码,但没有成功。这是一个示例代码,我知道它是错误的,但它可能会给您带来启发。
import numpy as np
import pandas as pd
def sigmoid(x):
return 1 /(1+np.exp(-x))
def sigmoid_derivative(x):
return x*(1-x)
training_inputs = np.array([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[1, 1, 0],
[0, 1, 1],
[1, 1, 1],
[2, 0, 0]
])
training_outputs = np.array([[1,2,0,1,0,2,3]]).T
np.random.seed(1)
synaptic_weights = 2 * np.random.random((3,1))-1
print('Random starting synaptic weights: ')
print(synaptic_weights)
for iteration in range(2000):
input_layer = training_inputs
outputs = sigmoid(np.dot(input_layer, synaptic_weights))
error = training_outputs - outputs
adjustments = error * sigmoid_derivative(outputs)
synaptic_weights += np.dot(input_layer.T,adjustments)
print('Synaptic Weights After Training: ')
print(synaptic_weights)
print('Outputs after training: ')
print(outputs)
我希望它输出像 [0,1,0,0] 这样的结果,意思是 1 作为一个热编码。我不知道该怎么做。
看到您使用 sigmoid,我们可以假设这是一个分类问题。
但是,您有 4 个类,因此我们需要使用其多类泛化,即 softmax 函数。
正如您所注意到的,我们需要对目标使用 one-hot 编码:您的预测应该与
training_outputs
具有相同的形状。可以轻松完成using np.eye()
。
接下来,您在线性方程中提到
b
,因此您必须向 training_inputs
(所有)添加一个偏差列。
因此,权重将变成 4x4 矩阵(4 个特征,包括偏差和 4 个类别)。
最后,学习率可能需要降低一点。
无需计算额外的导数:对数损失 w.r.t 的导数。权重仍然与
X * error
成正比。
如果我们扩展训练数据,这可能会进一步改善。
值得注意的是,多类分类并不完全是一个神经元,而是每类一个神经元。
import numpy as np
import pandas as pd
from scipy.special import softmax
training_inputs = np.array([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[1, 1, 0],
[0, 1, 1],
[1, 1, 1],
[2, 0, 0]
])
# Adding bias
training_inputs = np.hstack([training_inputs, np.ones((training_inputs.shape[0], 1))])
training_outputs = np.array([1,2,0,1,0,2,3])
# One-hot encoding
training_outputs = np.eye(4)[training_outputs]
np.random.seed(1)
synaptic_weights = 2 * np.random.random((4,4))-1
print('Random starting synaptic weights: ')
print(synaptic_weights)
for iteration in range(2000):
input_layer = training_inputs
# Softmax here
outputs = softmax(np.dot(input_layer, synaptic_weights), axis=1)
error = training_outputs - outputs
synaptic_weights += np.dot(input_layer.T,error) * 0.1 # learning rate
print('Synaptic Weights After Training: ')
print(synaptic_weights)
print('Outputs after training (one-hot): ')
print(np.round(outputs))
print('Outputs after training: ')
print(np.argmax(outputs, axis=1))