- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
我的环境:
- 语言环境:Python3.10.7
- 编译器:VScode
- 深度学习环境:TensorFlow 2.13.0
一、前期工作:
1、导入数据集
age: 1)年龄
sex:2)性别
cp: 3) 胸痛类型(4 values) aK同字
trestbps: 4) 静息血压
chol: 5) 血清胆甾醇(mg/dl
fbs: 6) 空腹血糖> 120 mg/dI
restecg: 7) 静息心电图结果(值0,1 ,2)
thalach: 8) 达到的最大心率
exang: 9) 运动诱发的心绞痛
oldpeak: 10) 相对于静止状态,运动弓|起的ST段压低
slope: 11) 运动峰值ST段的斜率
ca: 12) 荧光透视着色的主要血管数量(0-3)
thal: 13)0= 正常; 1 =固定缺陷; 2 =可逆转的缺陷
target: 14) 0 =心脏病发作的几率较小1 =心脏病发作的几率更大
实验代码:
import pandas as pd
import numpy as np
df = pd.read_csv("D:\R1heart.csv")
print (df)
print (df.isnull().sum())
df.isnull().sum()):检查是否有空值,并计算每个标签空值个数
运行结果:
2.数据集划分
实验代码:
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
X = df.iloc[:,:-1]
y = df.iloc[:,-1]
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.1, random_state = 1)
print (X_train.shape, y_train.shape)
1. sklearn.preprocessing.StandardScaler:
这个库是用于数据预处理中的特征缩放工具。在许多机器学习算法中,特征的尺度(scale)可能会对模型的性能产生影响。一些算法(如支持向量机、K近邻等)对于特征的尺度比较敏感,如果特征的尺度差异较大,可能会导致算法收敛速度慢或者模型表现不佳。
StandardScaler 可以对数据集中的每个特征进行标准化处理,使得每个特征的均值为 0,标准差为 1。具体来说,对于每个特征,它会执行以下操作:
从每个特征中减去平均值(均值为0)
除以标准差,使得特征的值符合标准正态分布
这样处理后,所有特征的尺度都是相同的,有助于提高某些算法的性能和收敛速度。
2. sklearn.model_selection.train_test_split:
这个库用于将数据集划分为训练集和测试集,以便在机器学习模型的开发和评估中使用。
在机器学习中,为了能够对模型进行准确的评估和测试,需要将原始数据集划分为两部分:
训练集(Training Set):用于训练模型
测试集(Test Set):用于评估模型的性能
train_test_split 函数的作用就是根据指定的划分比例,将原始数据集划分为训练集和测试集。通常情况下,数据集的大部分(比如 80% - 90%)用于训练,剩余的部分用于测试。这样划分可以确保在训练和测试时使用不同的数据,避免模型过拟合训练数据。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
`train_test_split` 将数据集 X 和标签 y 按照 80%-20% 的比例划分为训练集和测试集。其中,`test_size` 参数指定了测试集所占的比例,`random_state` 参数用于设置随机种子,保证结果的可重复性。
3.X = df.iloc[:, :-1]
:
这行代码使用 iloc
属性从 DataFrame df
中选择了所有行和除最后一列之外的所有列。iloc
是 Pandas 库中用于通过行和列的索引选择数据的属性。其中 ‘:'
表示选择所有行,':-1'
表示选择除了最后一列之外的所有列。
运行结果:
3.标准化
实验代码:
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
X_train = X_train.reshape(X_train.shape[0],X_train.shape[1],1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1],1)
-
sc = StandardScaler()
: 这行代码创建了一个StandardScaler
的实例对象sc
,用于对特征进行标准化处理。 -
X_train = sc.fit_transform(X_train)
: 将训练集X_train
中的特征数据进行标准化处理。fit_transform
方法会在训练集上进行标准化,并且在同一时间计算出训练集上的均值和标准差。然后,使用这些均值和标准差对训练集进行标准化处理,使得训练集的特征符合标准正态分布。 -
X_test = sc.transform(X_test)
:将测试集X_test
中的特征数据使用之前计算得到的训练集的均值和标准差进行标准化处理。这里使用的是transform
方法,它会使用已经计算得到的均值和标准差来对测试集进行标准化,确保测试集的特征也符合与训练集相同的标准正态分布。 -
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
: 这行代码对训练集X_train
进行了维度调整。有些机器学习模型,尤其是深度学习模型,可能对输入的维度有特定要求。在这里,将X_train
的维度从原本的(样本数量, 特征数量)
调整为(样本数量, 特征数量, 1)
。这样的维度调整通常用于一维卷积神经网络 (1D Convolutional Neural Network) 模型中,其中1
表示每个特征现在具有 1 个维度。 -
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)
: 这行代码对测试集X_test
进行了与训练集相同的维度调整,以保持输入维度的一致性。
二、构建RNN模型:
实验代码:
import tensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,LSTM,SimpleRNN
model = Sequential()
model.add(SimpleRNN(200,input_shape=(13,1),activation = 'relu'))
model.add(Dense(100, activation = 'relu'))
model.add(Dense(1,activation = 'sigmoid'))
model.summary()
model.add(SimpleRNN(200,input_shape=(13,1),activation = 'relu')) 代码中 input_shape=(13,1)的输入过程为:
输入1: [样本1的特征1]
[样本2的特征1]
[样本3的特征1]
...
[样本13的特征1]
输入2: [样本14的特征1]
[样本15的特征1]
[样本16的特征1]
...
[样本26的特征1]
输入3: [样本27的特征1]
[样本28的特征1]
[样本29的特征1]
...
[样本39的特征1]
…
直至270*13个特征全部输入完毕后输入过程结束
整个训练过程流程
训练数据 (train_data, train_labels)
↓
前向传播
↓
输入层 (Input Layer) SimpleRNN层 Dense层 Dense层
(输入数据的形状为 (13,1)) (200个神经元) (100个神经元) (1个神经元)
↓ ↓ ↓ ↓
──────────────▶ ─────────────▶ ───────────▶ ──────────▶
↓ ↓ ↓ ↓
↘ (包含权重) ↘ (包含权重) ↘ (包含权重) ↘ (包含权重)
计算损失
↓
反向传播
↓
优化器更新权重
↓
循环以上过程 (多次Epoch)
运行结果:
三、编译
opt = tf.keras.optimizers.Adam(learning_rate = 1e-4)
model.compile(loss = 'binary_crossentropy',
optimizer = opt,
metrics = "accuracy")
1. opt = tf.keras.optimizers.Adam(learning_rate = 1e-4):
Adam 是一种常用的梯度下降优化算法,它在深度学习中广泛使用。learning_rate = 1e-4 是指定的学习率,用于控制参数更新的步长,即每次迭代中参数更新的幅度。
2. model.compile(loss = 'binary_crossentropy', optimizer = opt, metrics = "accuracy"):
为训练过程指定损失函数、优化器和评估指标。
loss = 'binary_crossentropy:
代码指定了损失函数,该模型使用二分类问题的交叉熵(Cross Entropy)作为损失函数。在二分类问题中,交叉熵是常见的损失函数之一,用于度量模型输出与实际标签之间的差异。
optimizer = opt:
代码指定了优化器,将之前创建的 Adam 优化器 `opt` 赋值给了模型的优化器。模型在训练过程中将使用 Adam 优化器来自动调整参数以最小化损失函数。
metrics = "accuracy":
代码指定了评估指标,模型在训练过程中将计算并输出准确率(Accuracy)作为评估指标。准确率是衡量模型分类性能的常用指标,它表示模型在预测时正确分类的样本比例。
四、模型训练
实验代码:
epochs = 100
history = model.fit(X_train,y_train,
epochs = epochs,
batch_size = 128,
validation_data = (X_test,y_test),
verbose = 1)
batch_size=128
: 这个参数表示在每个迭代(epoch)中,将训练数据划分为大小为 128 的小批次。每个小批次会包含 128 个样本(数据点)和对应的标签(目标变量)。
小批量梯度下降是梯度下降算法的一种改进版本。传统的梯度下降算法在每次迭代中使用所有训练数据来更新模型的参数,这样的算法被称为批量梯度下降(Batch Gradient Descent)。但是,当数据集非常大时,批量梯度下降的计算代价会很高,而且每次迭代只能进行一次参数更新。
小批量梯度下降通过将数据分成多个小批次,每个小批次包含部分训练数据,从而实现更高效的参数更新。在每次迭代中,模型将对每个小批次的样本计算损失函数并求取梯度,然后将这些梯度的平均值用于更新模型的参数。这样的做法使得每个迭代可以进行多次参数更新,从而更快地收敛到最优解。
batch_size
的选择
通常需要根据具体的问题和硬件资源进行权衡。较小的 batch_size
可能会导致模型更新不稳定,但可以更快地收敛。较大的 batch_size
可能会更稳定,但可能需要更多的内存和计算资源。常见的 batch_size
大小通常是 32、64、128、256 等。
validation_data=(X_test, y_test) :是用于在每个 epoch 结束后评估模型在测试集上的性能。它用于监控模型的泛化能力,即模型在未见过的测试数据上的表现。在训练过程中,模型使用训练集数据进行参数更新,而测试集数据仅用于评估模型性能,不会参与参数更新。
评估性能主要包括以下指标:
1. 损失函数(Loss)
损失函数是模型在训练数据上的表现,它衡量模型输出与真实标签之间的差异。在这里,使用的损失函数是二分类问题的交叉熵(binary cross-entropy)。在训练过程中,模型会尝试最小化损失函数,使得模型预测尽可能接近真实标签。
2. 准确率(Accuracy)
准确率是模型在测试数据上的表现,它表示模型预测正确的样本比例。准确率是分类任务中最常用的评估指标之一。
3. 其它指标
除了损失函数和准确率,还可以使用其它一些指标来评估模型性能,具体根据任务的要求而定。例如,对于多分类问题,还可以使用精确率(Precision)、召回率(Recall)、F1 分数等指标来衡量模型的表现。
在每个 epoch 结束后,模型会根据测试集数据计算损失函数和评估指标,并输出这些指标的值。通过观察这些指标的变化,可以了解模型在训练过程中的性能变化,是否出现过拟合或欠拟合等问题。当模型的性能在测试集上表现稳定且令人满意时,可以停止训练,得到一个较好的泛化模型。
运行结果:
需要注意的是input_shape=(13, 1)
和 batch_size=128
之间没有直接联系,它们分别用于不同的目的
五、模型评估
实验代码:
#模型评估
import matplotlib.pyplot as plt
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(14,4))
plt.subplot(1,2,1)
plt.plot(epochs_range, loss, label = 'Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
运行结果:
完整代码
import tensorflow as tf
import pandas as pd
import numpy as np
df = pd.read_csv("D:\R1heart.csv")
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
X = df.iloc[:,:-1]
y = df.iloc[:,-1]
#划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.1, random_state = 1)
#标准化处理
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
X_train = X_train.reshape(X_train.shape[0],X_train.shape[1],1)
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1],1)
import tensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,LSTM,SimpleRNN
#model = Sequential()
#model.add(SimpleRNN(200,input_shape=(13,1),activation = 'relu'))
#model.add(Dense(100, activation = 'relu'))
#model.add(Dense(1,activation = 'sigmoid'))
model = Sequential()
model.add(SimpleRNN(128, input_shape= (13,1),return_sequences=True,activation='relu'))
model.add(SimpleRNN(64,return_sequences=True, activation='relu'))
model.add(SimpleRNN(32, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()
opt = tf.keras.optimizers.Adam(learning_rate = 1e-4)
model.compile(loss = 'binary_crossentropy',
optimizer = opt,
metrics = "accuracy")
epochs = 100
history = model.fit(X_train,y_train,
epochs = epochs,
batch_size = 128,
validation_data = (X_test,y_test),
verbose = 1)
#模型评估
import matplotlib.pyplot as plt
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(14,4))
plt.subplot(1,2,1)
plt.plot(epochs_range, loss, label = 'Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
#准确率评估
scores = model.evaluate(X_test, y_test, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))