如何构建自定义单神经元神经网络?含训练数据与独热输出需求
问题分析与解决方案
原代码的核心问题
- 激活函数不匹配:sigmoid输出范围是(0,1),但你的目标输出是0、1、2、3多分类值,无法用sigmoid覆盖
- 缺少偏置项:你要实现的函数是
w1*x1+w2*x2+w3*x3+b1,但代码里没有偏置参数 - 目标输出未转独热编码:直接用数值作为训练目标,不符合分类任务的损失计算逻辑
- 损失与更新逻辑错误:均方误差+sigmoid导数适合二分类或回归,不适合多分类任务
分步实现方案
1. 手动实现独热编码转换
先把训练输出的数值转为独热编码向量,类别为0、1、2、3,共4类:
def to_one_hot(labels, num_classes): # 创建全0矩阵,形状为(样本数, 类别数) one_hot = np.zeros((len(labels), num_classes)) # 对每个样本,对应类别位置设为1 for i, label in enumerate(labels): one_hot[i, label] = 1 return one_hot # 训练输出数值转独热编码 training_outputs_numeric = [1,2,0,1,0,2,3] num_classes = 4 training_outputs_one_hot = to_one_hot(training_outputs_numeric, num_classes)
2. 定义单神经元的核心函数
加入偏置项,使用softmax激活函数(多分类任务的标准激活):
import numpy as np def softmax(x): # 防止数值溢出,减去每行最大值 exp_x = np.exp(x - np.max(x, axis=1, keepdims=True)) return exp_x / np.sum(exp_x, axis=1, keepdims=True) def cross_entropy_loss(y_pred, y_true): # 加入微小值防止log(0) epsilon = 1e-10 return -np.mean(np.sum(y_true * np.log(y_pred + epsilon), axis=1))
3. 完整训练代码
实现带偏置的单神经元,用交叉熵损失更新权重和偏置:
# 训练输入 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_numeric = [1,2,0,1,0,2,3] num_classes = 4 training_outputs = to_one_hot(training_outputs_numeric, num_classes) # 初始化权重和偏置 np.random.seed(1) input_dim = 3 # 输入特征数 weights = np.random.uniform(-0.5, 0.5, (input_dim, num_classes)) bias = np.random.uniform(-0.5, 0.5, num_classes) learning_rate = 0.1 epochs = 10000 # 训练循环 for epoch in range(epochs): # 前向传播:计算线性输出 -> softmax得到概率 linear_output = np.dot(training_inputs, weights) + bias y_pred = softmax(linear_output) # 计算损失(可选,用于观察训练过程) loss = cross_entropy_loss(y_pred, training_outputs) # 反向传播:计算梯度 error = y_pred - training_outputs # 权重梯度:输入转置 · 误差 weights_grad = np.dot(training_inputs.T, error) / len(training_inputs) # 偏置梯度:误差的均值 bias_grad = np.mean(error, axis=0) # 更新权重和偏置 weights -= learning_rate * weights_grad bias -= learning_rate * bias_grad # 每1000轮打印一次损失 if (epoch + 1) % 1000 == 0: print(f"Epoch {epoch+1}, Loss: {loss:.4f}") # 测试训练后的输出 print("\n训练后的权重:") print(weights) print("\n训练后的偏置:") print(bias) # 预测并转独热编码形式 predictions = softmax(np.dot(training_inputs, weights) + bias) # 取概率最大的索引作为预测类别,再转独热编码 predicted_one_hot = to_one_hot(np.argmax(predictions, axis=1), num_classes) print("\n预测的独热编码输出:") print(predicted_one_hot)
4. 关键说明
- softmax激活:将线性输出转为0-1之间的概率分布,总和为1,适合多分类任务
- 交叉熵损失:衡量预测概率分布与真实独热编码分布的差异,是多分类任务的标准损失函数
- 偏置项:加入后才符合你要求的
w1*x1+w2*x2+w3*x3+b形式(这里b是4维向量,对应每个类别的偏置) - 手动独热编码:完全不依赖第三方AI库,纯numpy实现
内容的提问来源于stack exchange,提问作者Ahmet Rauf Oktay
相关产品推荐
相关产品推荐

