MLP(多层感知机) 虚战1

使用Keras实现MLP

前两节地址:

优快云matplotlib 虚战1-优快云博客    (数据的获取在这有说明)

数据预处理 虚战1-优快云博客优快云

数据预处理的最后一步:将数据集分为 训练数据集测试数据集校验数据集

训练数据集:神经网络将基于此子数据集进行训练。

测试数据集:基于此子数据集对模型进行最终的评估。

验证数据集:提供无偏差数据以帮助我们进行超参数的调节(调节隐藏层的个数)
数据预处理 虚战1-优快云博客  preprocess的代码在这

import numpy as np
np.random.seed(16)
import matplotlib
matplotlib.use("TkAgg")
from utils import preprocess
import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np
np.random.seed(16)


df = pd.read_csv('diabetes.csv')

# Perform preprocessing and feature engineering
df = preprocess(df)

# Split the data into a training and testing set
X = df.loc[:, df.columns != 'Outcome']
y = df.loc[:, 'Outcome']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

这里只把数据简单分为训练数据集和测试数据集

X = df.loc[:, df.columns != 'Outcome']  # 获取全部的行,除了Outcome列的所有列。

y = df.loc[:, 'Outcome']  # 获取全部的行,只要Outcome列。

记住Outcome是目标结果,有糖尿病或者没有糖尿病,即1或者0。

train_test_split()  函数完成这个分割过程,80%作为训练数据集、 20%作为测试数据集。

 模型结构

MLP是一种前馈神经网络,至少有一个隐藏层,且每层均通过一个非线性激活函数。这种多层神经网络结构和非线性激活函数使得MLP可以生成非线性的决策边界。

输入层:输入层的每个节点表示一个特征。

隐藏层:对应一个激活函数,该层最终输出结果由激活函数、权重和偏差决定。

激活函数:需要为每一层选择一个激活函数

这里使用,修正线性单元(Rectified Linear Unit,ReLU)和 sigmoid 激活函数作为激活函数。

ReLU常常作为中间层的激活函数(非输出层),是深度神经网络的默认的激活函数。

ReLU函数仅仅考虑原始X中非负的部分,并将负数部分替换为0。

sigmoid激活函数将输出值的范围压缩至0到1之间。sigmoid激活函数接收一个输入值并输出一个二元的分类结果(1或0)。

建模

使用Keras构建模型

通过将层堆叠起来的方法在Keras中创建一个神经网络:

activation='relu'

1.先创建一个Sequential()类

model = Sequential()

2.然后创建第一个隐藏层,该隐藏层包含32个节点,输入的维度input_dim是8,因为该数据集有8个特征。只有第一个隐藏层需要指明输入维度,后面的隐藏层会自动处理。

第一个隐藏层中节点的个数,比如这里设置的32,是一个超参数(需要调试才得出来的数),这里人为的选择32作为节点个数,该数据集较简单,该变量产生的影响并不大。

 activation='relu'   选择ReLU作为激活函数

3.添加第二个隐藏层

4.添加输出层,输出层只有一个节点,因为处理的是二元分类问题,激活函数使用的是sigmoid函数,它将输出结果压缩至0~1(二元输出)。

模型编译
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

训练模型之前,先定义训练过程的参数,通过compile()方法完成。

训练过程中的3个参数:

优化器:这里使用adam优化器

损失函数:使用二元交叉熵(binary_crossentropy)作为损失函数,因为这是一个二元分类问题

评估标准:使用准确率(即正确分类的样本比例)作为模型性能的评估标准。

模型训练

model.fit(X_train, y_train, epochs=200)

调用fit函数训练我们之前训练的模型,进行200轮,可以看到每一轮训练的情况,损失减少,准确度提高。这是学习算法根据训练数据在持续不断更新MLP的权重和偏差。这里的准确率指的是基于训练数据集的准确率。

结果分析

 MLP模型已经完成训练,可通过基于测试准确率混淆矩阵(confusion matrix)受试者操作特征曲线(Receiver Operating Characteristic,ROC)评估模型的性能

# Results - Accuracy
scores = model.evaluate(X_train, y_train, verbose=False)
print("Training Accuracy: %.2f%%\n" % (scores[1]*100))
scores = model.evaluate(X_test, y_test, verbose=False)
print("Testing Accuracy: %.2f%%\n" % (scores[1]*100))

训练数据集测试数据集上的模型准确率。

可以看到训练数据集的准确率是会比测试数据集的准确率高很多的,因为本来就是在训练数据集上训练出来的。基于测试数据计算出的准确率是我们评估模型在真实环境中应用准确率的标准,这是数据是模型未曾训练过的。

混淆矩阵是一个很有用的可视化工具。

真阴性:实际分类为阴性(没有糖尿病)而模型预测结果也是阴性(未患糖尿病)

假阴性:实际分类为阳性(有糖尿病) 而模型预测结果是阴性(未患糖尿病)

真阳性:实际分类为阳性(患糖尿病)而模型预测结果为阳性(患糖尿病)

假阳性:实际分类为阴性(未患糖尿病)而模型预测结果为阳性(患糖尿病)

真阳性和真阴性的数量越多就好,而假阳性和假阴性的数量越少越好。

# Results - Confusion Matrix
y_test_pred = model.predict_classes(X_test)
c_matrix = confusion_matrix(y_test, y_test_pred)
ax = sns.heatmap(c_matrix, annot=True, xticklabels=['No Diabetes', 'Diabetes'], yticklabels=['No Diabetes', 'Diabetes'], cbar=False, cmap='Blues')
ax.set_xlabel("Prediction")
ax.set_ylabel("Actual")
plt.show()
plt.clf()

sns.heatmap()绘制热度图              

c_matrix  :数据

cmap:定义热度图的配色板

annot:是否显示数值注释

cbar:删除seaborn中默认的条带,设置cbar=False。

xticklabels、yticklabels  刻度标签 

ROC曲线

将真阳性率(TPR)作为y轴,假阳性率(FPR)作为x轴。

 在分析ROC曲线时,通过曲线下方面积(Area Under the Curve,AUC)可以对该曲线的模型进行性能评估。

AUC大,表示模型能够更准确地区分不同分类

AUC小,表示模型做出的预测准确率不高,预测结果常有错

落在对角线上的ROC表示模型预测准确率并不高于随机预测的。

scikit-learn 提供了roc_curve类来帮我们绘制ROC曲线。

# Results - ROC Curve
y_test_pred_probs = model.predict(X_test)
FPR, TPR, _ = roc_curve(y_test, y_test_pred_probs)
plt.plot(FPR, TPR)
plt.plot([0,1],[0,1],'--', color='black') #diagonal line  对角线
plt.title('ROC Curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
plt.clf()

结果:

可以看出,该模型预测效果不错。 

全部代码:
 

import matplotlib
matplotlib.use("TkAgg")
from utils import preprocess
import pandas as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_curve
from keras.models import Sequential
from keras.layers import Dense
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(16)


df = pd.read_csv('diabetes.csv')


# Perform preprocessing and feature engineering
df = preprocess(df)

# Split the data into a training and testing set
X = df.loc[:, df.columns != 'Outcome']
y = df.loc[:, 'Outcome']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Build neural network in Keras
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=8))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=200, verbose=False)

# Results - Accuracy
scores = model.evaluate(X_train, y_train, verbose=False)
print("Training Accuracy: %.2f%%\n" % (scores[1]*100))
scores = model.evaluate(X_test, y_test, verbose=False)
print("Testing Accuracy: %.2f%%\n" % (scores[1]*100))

# Results - Confusion Matrix
y_test_pred = model.predict_classes(X_test)
c_matrix = confusion_matrix(y_test, y_test_pred)
ax = sns.heatmap(c_matrix, annot=True, xticklabels=['No Diabetes', 'Diabetes'], yticklabels=['No Diabetes', 'Diabetes'], cbar=False, cmap='Blues')
ax.set_xlabel("Prediction")
ax.set_ylabel("Actual")
plt.show()
plt.clf()

# Results - ROC Curve
y_test_pred_probs = model.predict(X_test)
FPR, TPR, _ = roc_curve(y_test, y_test_pred_probs)
plt.plot(FPR, TPR)
plt.plot([0,1],[0,1],'--', color='black') #diagonal line
plt.title('ROC Curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
plt.clf()

参考:

python使用seaborn画热力图中设置colorbar图例刻度字体大小_seaborn 设置colorbar刻度-优快云博客

Python可视化 | Seaborn5分钟入门(六)——heatmap热力图 - 知乎 (zhihu.com) 

python 神经网络项目实战 

<think>好的,我现在需要处理用户关于多层感知机MLP)的查询。首先,用户希望了解MLP的介绍和实现方法,可能需要包括原理、结构以及代码示例。根据系统指令,我需要确保数学公式正确使用行内或独立格式,并且用中文回答,同时生成相关问题。 首先,回顾用户提供的引用内容。引用[1]提到前馈神经网络的结构,包括输入层、隐藏层和输出层,信号单向传播,这有助于解释MLP的基础结构。引用[2]指出单层神经网络的局限性,如无法解决非线性问题,而多层网络需要有效的训练算法,比如BP算法,这可能要详细说明MLP如何克服这些限制。引用[3]提到Hopfield网络,但用户的问题是关于MLP,所以这部分可能不太相关,不过引用[4]给出了MLP的矩阵表示,可以用来解释前向传播的数学公式。 接下来,我需要组织回答的结构。首先介绍MLP的基本概念,强调其多层结构和前馈特性。然后解释其核心原理,比如如何通过隐藏层处理非线性问题,激活函数的作用(如Sigmoid、ReLU),以及反向传播算法的重要性。数学部分需要正确使用LaTeX,比如输入层到隐藏层的计算:$z^{(1)} = W^{(1)}x + b^{(1)}$,激活后的输出$a^{(1)} = \sigma(z^{(1)})$,然后到输出层的过程。反向传播部分需要推导梯度下降,涉及链式法则,可能需要独立公式块展示。 在实现方法部分,提供一个Python示例代码,使用NumPy库实现MLP,包括初始化参数、前向传播、损失计算(如交叉熵)、反向传播和参数更新。代码需要简洁,并且注释清楚每一步的作用,比如初始化权重矩阵的维度,激活函数的选择,损失函数的计算,以及梯度更新的步骤。 生成相关问题时要考虑用户可能进一步的需求,比如激活函数的选择、梯度消失问题、与CNN/RNN的区别、实际应用场景等。这些问题需要基于MLP的基础知识,帮助用户深入理解。 需要检查是否符合系统指令:行内公式用$...$,独立公式用$$...$$,正确的中文回答,引用标注在相关段落末尾,比如提到Minsky的感知机局限时添加[^2],提到反向传播时引用[2]中的BP算法。同时确保LaTeX语法正确,比如矩阵乘法、激活函数符号等。 最后,确保回答结构清晰,分点明确,帮助用户逐步理解MLP的原理和实现,并附上相关问题促进深入学习。需要避免技术错误,比如正确的矩阵维度,正确的导数计算,以及在代码中合理处理前向和反向传播的步骤。</think>### 多层感知机MLP)介绍与实现 #### 1. **基本概念** 多层感知机(Multilayer Perceptron, MLP)是一种**前馈人工神经网络**,由输入层、至少一个隐藏层和输出层组成。与单层感知机不同,MLP通过引入隐藏层和非线性激活函数,能够解决复杂的非线性分类和回归问题[^1]。 #### 2. **核心原理** - **网络结构**: 输入层接收原始数据,隐藏层通过权重矩阵和激活函数对信号进行非线性变换,输出层生成最终预测结果。例如,一个两层的MLP可表示为: $$ z^{(1)} = W^{(1)}x + b^{(1)}, \quad a^{(1)} = \sigma(z^{(1)}) $$ $$ z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}, \quad \hat{y} = \text{softmax}(z^{(2)}) $$ 其中$\sigma$为激活函数(如ReLU或Sigmoid),$\text{softmax}$用于多分类任务。 - **激活函数**: 关键组件,赋予网络非线性能力。常用函数包括: - Sigmoid:$\sigma(z) = \frac{1}{1+e^{-z}}$ - ReLU:$\sigma(z) = \max(0, z)$ - **反向传播算法**: 通过计算损失函数对权重的梯度(链式法则),使用梯度下降优化参数。例如,交叉熵损失对输出层权重的梯度为: $$ \frac{\partial L}{\partial W^{(2)}} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z^{(2)}} \cdot \frac{\partial z^{(2)}}{\partial W^{(2)}} $$ 逐层反向传递误差信号以更新权重[^4]。 #### 3. **Python实现示例** ```python import numpy as np class MLP: def __init__(self, input_size, hidden_size, output_size): # 初始化权重矩阵和偏置 self.W1 = np.random.randn(input_size, hidden_size) * 0.01 self.b1 = np.zeros((1, hidden_size)) self.W2 = np.random.randn(hidden_size, output_size) * 0.01 self.b2 = np.zeros((1, output_size)) def relu(self, x): return np.maximum(0, x) def forward(self, X): # 前向传播 self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = self.relu(self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 exp_scores = np.exp(self.z2) self.probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) return self.probs def backward(self, X, y, learning_rate=0.01): # 反向传播 delta3 = self.probs delta3[range(len(X)), y] -= 1 dW2 = np.dot(self.a1.T, delta3) db2 = np.sum(delta3, axis=0, keepdims=True) delta2 = np.dot(delta3, self.W2.T) * (self.z1 > 0) # ReLU导数 dW1 = np.dot(X.T, delta2) db1 = np.sum(delta2, axis=0) # 参数更新 self.W2 -= learning_rate * dW2 self.b2 -= learning_rate * db2 self.W1 -= learning_rate * dW1 self.b1 -= learning_rate * db1 # 示例用法 mlp = MLP(input_size=4, hidden_size=5, output_size=3) X = np.random.randn(10, 4) # 输入数据(10个样本) y = np.array([0, 1, 2, 0, 1, 2, 0, 1, 2, 0]) # 标签 for epoch in range(100): probs = mlp.forward(X) mlp.backward(X, y) ``` #### 4. **关键特点** - **解决非线性问题**:通过隐藏层组合特征,突破单层感知机的线性限制[^2]。 - **通用近似定理**:一个足够大的MLP可以逼近任意连续函数。 - **应用场景**:图像分类、信用评分、自然语言处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值